All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-02-27  9:34 Hans de Goede
  2017-02-28  5:19   ` [Devel] " Zheng, Lv
                   ` (2 more replies)
  0 siblings, 3 replies; 51+ messages in thread
From: Hans de Goede @ 2017-02-27  9:34 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng
  Cc: Hans de Goede, linux-acpi, devel

Some machines have the exact (byte for byte) same SSDT tables multiple
times in the root_table_list. Detect this and silently skip the duplicates
rather then printing a scary looking set of errors.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index 82019c0..1971cd7 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_tb_find_duplicate_ssdt
+ *
+ * PARAMETERS:  table         - validated acpi_table_desc of table to check
+ *              index         - index of table to find a duplicate of
+ *
+ * RETURN:      TRUE if a duplicate is found, FALSE if not
+ *
+ * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
+ *              avoid trying to load duplicate ssdt tables
+ *
+ ******************************************************************************/
+static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
+{
+	struct acpi_table_desc *dup;
+	u32 i;
+
+	for (i = 0; i < index; ++i) {
+		dup = &acpi_gbl_root_table_list.tables[i];
+
+		if (!acpi_gbl_root_table_list.tables[i].address ||
+		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
+		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
+					   ACPI_SIG_PSDT)
+		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
+					   ACPI_SIG_OSDT))
+		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
+		    || dup->length != table->length) {
+			continue;
+		}
+
+		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_tb_load_namespace
  *
  * PARAMETERS:  None
@@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
 					   ACPI_SIG_PSDT)
 		     && !ACPI_COMPARE_NAME(table->signature.ascii,
 					   ACPI_SIG_OSDT))
-		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
+		    || ACPI_FAILURE(acpi_tb_validate_table(table))
+		    || acpi_tb_find_duplicate_ssdt(table, i)) {
 			continue;
 		}
 
-- 
2.9.3


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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-02-28  5:19   ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-02-28  5:19 UTC (permalink / raw)
  To: Hans de Goede, Rafael J . Wysocki, Len Brown, Moore, Robert
  Cc: linux-acpi, devel

Hi,

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Some machines have the exact (byte for byte) same SSDT tables multiple
> times in the root_table_list.

Could you give a machine list here?

> Detect this and silently skip the duplicates
> rather then printing a scary looking set of errors.

Why will this matter to OSPMs?
And should we add non-costless steps just in order to reduce errors,
while the errors are on the contrary useful (indicating platform issues)?

Thanks
Lv

> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> index 82019c0..1971cd7 100644
> --- a/drivers/acpi/acpica/tbxfload.c
> +++ b/drivers/acpi/acpica/tbxfload.c
> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> 
>  /*******************************************************************************
>   *
> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> + *
> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> + *              index         - index of table to find a duplicate of
> + *
> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> + *
> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> + *              avoid trying to load duplicate ssdt tables
> + *
> + ******************************************************************************/
> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> +{
> +	struct acpi_table_desc *dup;
> +	u32 i;
> +
> +	for (i = 0; i < index; ++i) {
> +		dup = &acpi_gbl_root_table_list.tables[i];
> +
> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> +					   ACPI_SIG_PSDT)
> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> +					   ACPI_SIG_OSDT))
> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> +		    || dup->length != table->length) {
> +			continue;
> +		}
> +
> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> +			return TRUE;
> +	}
> +	return FALSE;
> +}
> +
> +/*******************************************************************************
> + *
>   * FUNCTION:    acpi_tb_load_namespace
>   *
>   * PARAMETERS:  None
> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
>  					   ACPI_SIG_PSDT)
>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
>  					   ACPI_SIG_OSDT))
> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
>  			continue;
>  		}
> 
> --
> 2.9.3


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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-02-28  5:19   ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-02-28  5:19 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 2977 bytes --]

Hi,

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Some machines have the exact (byte for byte) same SSDT tables multiple
> times in the root_table_list.

Could you give a machine list here?

> Detect this and silently skip the duplicates
> rather then printing a scary looking set of errors.

Why will this matter to OSPMs?
And should we add non-costless steps just in order to reduce errors,
while the errors are on the contrary useful (indicating platform issues)?

Thanks
Lv

> 
> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> ---
>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> index 82019c0..1971cd7 100644
> --- a/drivers/acpi/acpica/tbxfload.c
> +++ b/drivers/acpi/acpica/tbxfload.c
> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> 
>  /*******************************************************************************
>   *
> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> + *
> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> + *              index         - index of table to find a duplicate of
> + *
> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> + *
> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> + *              avoid trying to load duplicate ssdt tables
> + *
> + ******************************************************************************/
> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> +{
> +	struct acpi_table_desc *dup;
> +	u32 i;
> +
> +	for (i = 0; i < index; ++i) {
> +		dup = &acpi_gbl_root_table_list.tables[i];
> +
> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> +					   ACPI_SIG_PSDT)
> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> +					   ACPI_SIG_OSDT))
> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> +		    || dup->length != table->length) {
> +			continue;
> +		}
> +
> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> +			return TRUE;
> +	}
> +	return FALSE;
> +}
> +
> +/*******************************************************************************
> + *
>   * FUNCTION:    acpi_tb_load_namespace
>   *
>   * PARAMETERS:  None
> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
>  					   ACPI_SIG_PSDT)
>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
>  					   ACPI_SIG_OSDT))
> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
>  			continue;
>  		}
> 
> --
> 2.9.3


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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-02-28  5:19   ` [Devel] " Zheng, Lv
  (?)
@ 2017-02-28 14:31   ` Hans de Goede
  2017-02-28 15:46       ` [Devel] " Moore, Robert
  2017-03-01  3:21       ` [Devel] " Zheng, Lv
  -1 siblings, 2 replies; 51+ messages in thread
From: Hans de Goede @ 2017-02-28 14:31 UTC (permalink / raw)
  To: Zheng, Lv, Rafael J . Wysocki, Len Brown, Moore, Robert; +Cc: linux-acpi, devel

Hi,

On 28-02-17 06:19, Zheng, Lv wrote:
> Hi,
>
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
>>
>> Some machines have the exact (byte for byte) same SSDT tables multiple
>> times in the root_table_list.
>
> Could you give a machine list here?

Currently I'm seeing this on a GPD win machine:

http://www.gpd.hk/gpdwin.asp

I thought I was seeing it on more machines, but those have
different apci table loading errors...

>> Detect this and silently skip the duplicates
>> rather then printing a scary looking set of errors.
>
> Why will this matter to OSPMs?

Not sure what you mean with OSPMs but I can tell you why this
matters in general, Linux distributions like e.g. Fedora have
been putting a lot of work in a smooth boot experience where
end users do not get any scary text messages. For some more
embedded like systems this even is a hard requirement.

The kernel supports quiet kernel cmdline argument to silence
normal kernel messages, which is part of what is needed but
messages with a log level of error still get shown, breaking
the "no scary text messages" product requirement.

> And should we add non-costless steps just in order to reduce errors,

Yes we should, work on that front has been happening for years,
also the CPU cost of this check is quite small, memcmp will
only happen on identically sized tables and even then it will
exit as soon as a single byte differs.

> while the errors are on the contrary useful (in1dicating platform issues)?

These errors are useful for developers / during testing but
not in production setups, esp. in the case of duplicate tables
where not loading the duplicate leads to 0 bad side effects.

I've an alternative proposal though, since this check just fixes
a small part of the early boot messages caused by SSDT loading
and since the code itself chooses to ignore any errors:

         /* Ignore errors while loading tables, get as many as possible */

How about setting a global flag while loading these tables and making

ACPI_EXCEPTION calls log the exceptions with a log level of warning
as well as turning the final:

                 ACPI_ERROR((AE_INFO,
                             "%u table load failures, %u successful",
                             tables_failed, tables_loaded));

Into a warning ?

Regards,

Hans




>
> Thanks
> Lv
>
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
>> index 82019c0..1971cd7 100644
>> --- a/drivers/acpi/acpica/tbxfload.c
>> +++ b/drivers/acpi/acpica/tbxfload.c
>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
>>
>>  /*******************************************************************************
>>   *
>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
>> + *
>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
>> + *              index         - index of table to find a duplicate of
>> + *
>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
>> + *
>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
>> + *              avoid trying to load duplicate ssdt tables
>> + *
>> + ******************************************************************************/
>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
>> +{
>> +	struct acpi_table_desc *dup;
>> +	u32 i;
>> +
>> +	for (i = 0; i < index; ++i) {
>> +		dup = &acpi_gbl_root_table_list.tables[i];
>> +
>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>> +					   ACPI_SIG_PSDT)
>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>> +					   ACPI_SIG_OSDT))
>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
>> +		    || dup->length != table->length) {
>> +			continue;
>> +		}
>> +
>> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
>> +			return TRUE;
>> +	}
>> +	return FALSE;
>> +}
>> +
>> +/*******************************************************************************
>> + *
>>   * FUNCTION:    acpi_tb_load_namespace
>>   *
>>   * PARAMETERS:  None
>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
>>  					   ACPI_SIG_PSDT)
>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
>>  					   ACPI_SIG_OSDT))
>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
>>  			continue;
>>  		}
>>
>> --
>> 2.9.3
>

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-02-28 15:46       ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-02-28 15:46 UTC (permalink / raw)
  To: Hans de Goede, Zheng, Lv, Rafael J . Wysocki, Len Brown; +Cc: linux-acpi, devel

Does the machine or machines work properly with Windows? This is always one of our early questions.
Bob


> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Sent: Tuesday, February 28, 2017 6:32 AM
> To: Zheng, Lv <lv.zheng@intel.com>; Rafael J . Wysocki
> <rjw@rjwysocki.net>; Len Brown <lenb@kernel.org>; Moore, Robert
> <robert.moore@intel.com>
> Cc: linux-acpi@vger.kernel.org; devel@acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 06:19, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Some machines have the exact (byte for byte) same SSDT tables
> >> multiple times in the root_table_list.
> >
> > Could you give a machine list here?
> 
> Currently I'm seeing this on a GPD win machine:
> 
> http://www.gpd.hk/gpdwin.asp
> 
> I thought I was seeing it on more machines, but those have different
> apci table loading errors...
> 
> >> Detect this and silently skip the duplicates rather then printing a
> >> scary looking set of errors.
> >
> > Why will this matter to OSPMs?
> 
> Not sure what you mean with OSPMs but I can tell you why this matters in
> general, Linux distributions like e.g. Fedora have been putting a lot of
> work in a smooth boot experience where end users do not get any scary
> text messages. For some more embedded like systems this even is a hard
> requirement.
> 
> The kernel supports quiet kernel cmdline argument to silence normal
> kernel messages, which is part of what is needed but messages with a log
> level of error still get shown, breaking the "no scary text messages"
> product requirement.
> 
> > And should we add non-costless steps just in order to reduce errors,
> 
> Yes we should, work on that front has been happening for years, also the
> CPU cost of this check is quite small, memcmp will only happen on
> identically sized tables and even then it will exit as soon as a single
> byte differs.
> 
> > while the errors are on the contrary useful (in1dicating platform
> issues)?
> 
> These errors are useful for developers / during testing but not in
> production setups, esp. in the case of duplicate tables where not
> loading the duplicate leads to 0 bad side effects.
> 
> I've an alternative proposal though, since this check just fixes a small
> part of the early boot messages caused by SSDT loading and since the
> code itself chooses to ignore any errors:
> 
>          /* Ignore errors while loading tables, get as many as possible
> */
> 
> How about setting a global flag while loading these tables and making
> 
> ACPI_EXCEPTION calls log the exceptions with a log level of warning as
> well as turning the final:
> 
>                  ACPI_ERROR((AE_INFO,
>                              "%u table load failures, %u successful",
>                              tables_failed, tables_loaded));
> 
> Into a warning ?
> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> >
> > Thanks
> > Lv
> >
> >>
> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >> ---
> >>  drivers/acpi/acpica/tbxfload.c | 41
> >> ++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/acpi/acpica/tbxfload.c
> >> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >> --- a/drivers/acpi/acpica/tbxfload.c
> >> +++ b/drivers/acpi/acpica/tbxfload.c
> >> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>
> >>
> /***********************************************************************
> ********
> >>   *
> >> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >> + *
> >> + * PARAMETERS:  table         - validated acpi_table_desc of table
> to check
> >> + *              index         - index of table to find a duplicate
> of
> >> + *
> >> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >> + *
> >> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> to
> >> + *              avoid trying to load duplicate ssdt tables
> >> + *
> >> +
> >> +********************************************************************
> >> +**********/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >> +acpi_table_desc *table, u32 index) {
> >> +	struct acpi_table_desc *dup;
> >> +	u32 i;
> >> +
> >> +	for (i = 0; i < index; ++i) {
> >> +		dup = &acpi_gbl_root_table_list.tables[i];
> >> +
> >> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_PSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_OSDT))
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >> +		    || dup->length != table->length) {
> >> +			continue;
> >> +		}
> >> +
> >> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> >> +			return TRUE;
> >> +	}
> >> +	return FALSE;
> >> +}
> >> +
> >> +/*******************************************************************
> >> +************
> >> + *
> >>   * FUNCTION:    acpi_tb_load_namespace
> >>   *
> >>   * PARAMETERS:  None
> >> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>  					   ACPI_SIG_PSDT)
> >>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>  					   ACPI_SIG_OSDT))
> >> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>  			continue;
> >>  		}
> >>
> >> --
> >> 2.9.3
> >

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-02-28 15:46       ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-02-28 15:46 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 5782 bytes --]

Does the machine or machines work properly with Windows? This is always one of our early questions.
Bob


> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Sent: Tuesday, February 28, 2017 6:32 AM
> To: Zheng, Lv <lv.zheng(a)intel.com>; Rafael J . Wysocki
> <rjw(a)rjwysocki.net>; Len Brown <lenb(a)kernel.org>; Moore, Robert
> <robert.moore(a)intel.com>
> Cc: linux-acpi(a)vger.kernel.org; devel(a)acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 06:19, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Some machines have the exact (byte for byte) same SSDT tables
> >> multiple times in the root_table_list.
> >
> > Could you give a machine list here?
> 
> Currently I'm seeing this on a GPD win machine:
> 
> http://www.gpd.hk/gpdwin.asp
> 
> I thought I was seeing it on more machines, but those have different
> apci table loading errors...
> 
> >> Detect this and silently skip the duplicates rather then printing a
> >> scary looking set of errors.
> >
> > Why will this matter to OSPMs?
> 
> Not sure what you mean with OSPMs but I can tell you why this matters in
> general, Linux distributions like e.g. Fedora have been putting a lot of
> work in a smooth boot experience where end users do not get any scary
> text messages. For some more embedded like systems this even is a hard
> requirement.
> 
> The kernel supports quiet kernel cmdline argument to silence normal
> kernel messages, which is part of what is needed but messages with a log
> level of error still get shown, breaking the "no scary text messages"
> product requirement.
> 
> > And should we add non-costless steps just in order to reduce errors,
> 
> Yes we should, work on that front has been happening for years, also the
> CPU cost of this check is quite small, memcmp will only happen on
> identically sized tables and even then it will exit as soon as a single
> byte differs.
> 
> > while the errors are on the contrary useful (in1dicating platform
> issues)?
> 
> These errors are useful for developers / during testing but not in
> production setups, esp. in the case of duplicate tables where not
> loading the duplicate leads to 0 bad side effects.
> 
> I've an alternative proposal though, since this check just fixes a small
> part of the early boot messages caused by SSDT loading and since the
> code itself chooses to ignore any errors:
> 
>          /* Ignore errors while loading tables, get as many as possible
> */
> 
> How about setting a global flag while loading these tables and making
> 
> ACPI_EXCEPTION calls log the exceptions with a log level of warning as
> well as turning the final:
> 
>                  ACPI_ERROR((AE_INFO,
>                              "%u table load failures, %u successful",
>                              tables_failed, tables_loaded));
> 
> Into a warning ?
> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> >
> > Thanks
> > Lv
> >
> >>
> >> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >> ---
> >>  drivers/acpi/acpica/tbxfload.c | 41
> >> ++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/acpi/acpica/tbxfload.c
> >> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >> --- a/drivers/acpi/acpica/tbxfload.c
> >> +++ b/drivers/acpi/acpica/tbxfload.c
> >> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>
> >>
> /***********************************************************************
> ********
> >>   *
> >> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >> + *
> >> + * PARAMETERS:  table         - validated acpi_table_desc of table
> to check
> >> + *              index         - index of table to find a duplicate
> of
> >> + *
> >> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >> + *
> >> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> to
> >> + *              avoid trying to load duplicate ssdt tables
> >> + *
> >> +
> >> +********************************************************************
> >> +**********/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >> +acpi_table_desc *table, u32 index) {
> >> +	struct acpi_table_desc *dup;
> >> +	u32 i;
> >> +
> >> +	for (i = 0; i < index; ++i) {
> >> +		dup = &acpi_gbl_root_table_list.tables[i];
> >> +
> >> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_PSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_OSDT))
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >> +		    || dup->length != table->length) {
> >> +			continue;
> >> +		}
> >> +
> >> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> >> +			return TRUE;
> >> +	}
> >> +	return FALSE;
> >> +}
> >> +
> >> +/*******************************************************************
> >> +************
> >> + *
> >>   * FUNCTION:    acpi_tb_load_namespace
> >>   *
> >>   * PARAMETERS:  None
> >> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>  					   ACPI_SIG_PSDT)
> >>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>  					   ACPI_SIG_OSDT))
> >> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>  			continue;
> >>  		}
> >>
> >> --
> >> 2.9.3
> >

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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-02-28 15:46       ` [Devel] " Moore, Robert
  (?)
@ 2017-02-28 23:44       ` Hans de Goede
  2017-03-01  0:11           ` [Devel] " Moore, Robert
  -1 siblings, 1 reply; 51+ messages in thread
From: Hans de Goede @ 2017-02-28 23:44 UTC (permalink / raw)
  To: Moore, Robert, Zheng, Lv, Rafael J . Wysocki, Len Brown; +Cc: linux-acpi, devel

Hi,

On 28-02-17 16:46, Moore, Robert wrote:
> Does the machine or machines work properly with Windows? This is always one of our early questions.

Yes although I do not see how that is really
relevant or a discussion about changing the log
level of certain errors ...

Regards,

Hans



> Bob
>
>
>> -----Original Message-----
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Sent: Tuesday, February 28, 2017 6:32 AM
>> To: Zheng, Lv <lv.zheng@intel.com>; Rafael J . Wysocki
>> <rjw@rjwysocki.net>; Len Brown <lenb@kernel.org>; Moore, Robert
>> <robert.moore@intel.com>
>> Cc: linux-acpi@vger.kernel.org; devel@acpica.org
>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>
>> Hi,
>>
>> On 28-02-17 06:19, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>
>>>> Some machines have the exact (byte for byte) same SSDT tables
>>>> multiple times in the root_table_list.
>>>
>>> Could you give a machine list here?
>>
>> Currently I'm seeing this on a GPD win machine:
>>
>> http://www.gpd.hk/gpdwin.asp
>>
>> I thought I was seeing it on more machines, but those have different
>> apci table loading errors...
>>
>>>> Detect this and silently skip the duplicates rather then printing a
>>>> scary looking set of errors.
>>>
>>> Why will this matter to OSPMs?
>>
>> Not sure what you mean with OSPMs but I can tell you why this matters in
>> general, Linux distributions like e.g. Fedora have been putting a lot of
>> work in a smooth boot experience where end users do not get any scary
>> text messages. For some more embedded like systems this even is a hard
>> requirement.
>>
>> The kernel supports quiet kernel cmdline argument to silence normal
>> kernel messages, which is part of what is needed but messages with a log
>> level of error still get shown, breaking the "no scary text messages"
>> product requirement.
>>
>>> And should we add non-costless steps just in order to reduce errors,
>>
>> Yes we should, work on that front has been happening for years, also the
>> CPU cost of this check is quite small, memcmp will only happen on
>> identically sized tables and even then it will exit as soon as a single
>> byte differs.
>>
>>> while the errors are on the contrary useful (in1dicating platform
>> issues)?
>>
>> These errors are useful for developers / during testing but not in
>> production setups, esp. in the case of duplicate tables where not
>> loading the duplicate leads to 0 bad side effects.
>>
>> I've an alternative proposal though, since this check just fixes a small
>> part of the early boot messages caused by SSDT loading and since the
>> code itself chooses to ignore any errors:
>>
>>          /* Ignore errors while loading tables, get as many as possible
>> */
>>
>> How about setting a global flag while loading these tables and making
>>
>> ACPI_EXCEPTION calls log the exceptions with a log level of warning as
>> well as turning the final:
>>
>>                  ACPI_ERROR((AE_INFO,
>>                              "%u table load failures, %u successful",
>>                              tables_failed, tables_loaded));
>>
>> Into a warning ?
>>
>> Regards,
>>
>> Hans
>>
>>
>>
>>
>>>
>>> Thanks
>>> Lv
>>>
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>> ---
>>>>  drivers/acpi/acpica/tbxfload.c | 41
>>>> ++++++++++++++++++++++++++++++++++++++++-
>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/acpi/acpica/tbxfload.c
>>>> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
>>>> --- a/drivers/acpi/acpica/tbxfload.c
>>>> +++ b/drivers/acpi/acpica/tbxfload.c
>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
>>>>
>>>>
>> /***********************************************************************
>> ********
>>>>   *
>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
>>>> + *
>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table
>> to check
>>>> + *              index         - index of table to find a duplicate
>> of
>>>> + *
>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
>>>> + *
>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
>> to
>>>> + *              avoid trying to load duplicate ssdt tables
>>>> + *
>>>> +
>>>> +********************************************************************
>>>> +**********/ static u8 acpi_tb_find_duplicate_ssdt(struct
>>>> +acpi_table_desc *table, u32 index) {
>>>> +	struct acpi_table_desc *dup;
>>>> +	u32 i;
>>>> +
>>>> +	for (i = 0; i < index; ++i) {
>>>> +		dup = &acpi_gbl_root_table_list.tables[i];
>>>> +
>>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
>>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
>>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>>>> +					   ACPI_SIG_PSDT)
>>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>>>> +					   ACPI_SIG_OSDT))
>>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
>>>> +		    || dup->length != table->length) {
>>>> +			continue;
>>>> +		}
>>>> +
>>>> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
>>>> +			return TRUE;
>>>> +	}
>>>> +	return FALSE;
>>>> +}
>>>> +
>>>> +/*******************************************************************
>>>> +************
>>>> + *
>>>>   * FUNCTION:    acpi_tb_load_namespace
>>>>   *
>>>>   * PARAMETERS:  None
>>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
>>>>  					   ACPI_SIG_PSDT)
>>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
>>>>  					   ACPI_SIG_OSDT))
>>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
>>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
>>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
>>>>  			continue;
>>>>  		}
>>>>
>>>> --
>>>> 2.9.3
>>>

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01  0:11           ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-03-01  0:11 UTC (permalink / raw)
  To: Hans de Goede, Zheng, Lv, Rafael J . Wysocki, Len Brown; +Cc: linux-acpi, devel



> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Sent: Tuesday, February 28, 2017 3:45 PM
> To: Moore, Robert; Zheng, Lv; Rafael J . Wysocki; Len Brown
> Cc: linux-acpi@vger.kernel.org; devel@acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 16:46, Moore, Robert wrote:
> > Does the machine or machines work properly with Windows? This is always
> one of our early questions.
> 
> Yes although I do not see how that is really relevant or a discussion
> about changing the log level of certain errors ...
> 

Gee, I thought the original discussion was about multiple identical SSDTs, which led to this:

    acpi_tb_find_duplicate_ssdt

I would imagine that ACPICA would generate lots of errors as the duplicate symbols were found.

What Windows would do is my question.



> Regards,
> 
> Hans
> 
> 
> 
> > Bob
> >
> >
> >> -----Original Message-----
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Sent: Tuesday, February 28, 2017 6:32 AM
> >> To: Zheng, Lv <lv.zheng@intel.com>; Rafael J . Wysocki
> >> <rjw@rjwysocki.net>; Len Brown <lenb@kernel.org>; Moore, Robert
> >> <robert.moore@intel.com>
> >> Cc: linux-acpi@vger.kernel.org; devel@acpica.org
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables
> >>>> multiple times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have different
> >> apci table loading errors...
> >>
> >>>> Detect this and silently skip the duplicates rather then printing a
> >>>> scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this matters
> >> in general, Linux distributions like e.g. Fedora have been putting a
> >> lot of work in a smooth boot experience where end users do not get
> >> any scary text messages. For some more embedded like systems this
> >> even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence normal
> >> kernel messages, which is part of what is needed but messages with a
> >> log level of error still get shown, breaking the "no scary text
> messages"
> >> product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years, also
> >> the CPU cost of this check is quite small, memcmp will only happen on
> >> identically sized tables and even then it will exit as soon as a
> >> single byte differs.
> >>
> >>> while the errors are on the contrary useful (in1dicating platform
> >> issues)?
> >>
> >> These errors are useful for developers / during testing but not in
> >> production setups, esp. in the case of duplicate tables where not
> >> loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes a
> >> small part of the early boot messages caused by SSDT loading and
> >> since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as
> >> possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >>
> >> Regards,
> >>
> >> Hans
> >>
> >>
> >>
> >>
> >>>
> >>> Thanks
> >>> Lv
> >>>
> >>>>
> >>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41
> >>>> ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c
> >>>> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>
> >> /********************************************************************
> >> ***
> >> ********
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table
> >> to check
> >>>> + *              index         - index of table to find a duplicate
> >> of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> >> to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> +
> >>>> +******************************************************************
> >>>> +** **********/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >>>> +acpi_table_desc *table, u32 index) {
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {
> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii,
> ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length)
> == 0)
> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*****************************************************************
> >>>> +**
> >>>> +************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01  0:11           ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-03-01  0:11 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 7022 bytes --]



> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Sent: Tuesday, February 28, 2017 3:45 PM
> To: Moore, Robert; Zheng, Lv; Rafael J . Wysocki; Len Brown
> Cc: linux-acpi(a)vger.kernel.org; devel(a)acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 16:46, Moore, Robert wrote:
> > Does the machine or machines work properly with Windows? This is always
> one of our early questions.
> 
> Yes although I do not see how that is really relevant or a discussion
> about changing the log level of certain errors ...
> 

Gee, I thought the original discussion was about multiple identical SSDTs, which led to this:

    acpi_tb_find_duplicate_ssdt

I would imagine that ACPICA would generate lots of errors as the duplicate symbols were found.

What Windows would do is my question.



> Regards,
> 
> Hans
> 
> 
> 
> > Bob
> >
> >
> >> -----Original Message-----
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Sent: Tuesday, February 28, 2017 6:32 AM
> >> To: Zheng, Lv <lv.zheng(a)intel.com>; Rafael J . Wysocki
> >> <rjw(a)rjwysocki.net>; Len Brown <lenb(a)kernel.org>; Moore, Robert
> >> <robert.moore(a)intel.com>
> >> Cc: linux-acpi(a)vger.kernel.org; devel(a)acpica.org
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables
> >>>> multiple times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have different
> >> apci table loading errors...
> >>
> >>>> Detect this and silently skip the duplicates rather then printing a
> >>>> scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this matters
> >> in general, Linux distributions like e.g. Fedora have been putting a
> >> lot of work in a smooth boot experience where end users do not get
> >> any scary text messages. For some more embedded like systems this
> >> even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence normal
> >> kernel messages, which is part of what is needed but messages with a
> >> log level of error still get shown, breaking the "no scary text
> messages"
> >> product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years, also
> >> the CPU cost of this check is quite small, memcmp will only happen on
> >> identically sized tables and even then it will exit as soon as a
> >> single byte differs.
> >>
> >>> while the errors are on the contrary useful (in1dicating platform
> >> issues)?
> >>
> >> These errors are useful for developers / during testing but not in
> >> production setups, esp. in the case of duplicate tables where not
> >> loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes a
> >> small part of the early boot messages caused by SSDT loading and
> >> since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as
> >> possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >>
> >> Regards,
> >>
> >> Hans
> >>
> >>
> >>
> >>
> >>>
> >>> Thanks
> >>> Lv
> >>>
> >>>>
> >>>> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41
> >>>> ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c
> >>>> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>
> >> /********************************************************************
> >> ***
> >> ********
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table
> >> to check
> >>>> + *              index         - index of table to find a duplicate
> >> of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> >> to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> +
> >>>> +******************************************************************
> >>>> +** **********/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >>>> +acpi_table_desc *table, u32 index) {
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {
> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii,
> ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length)
> == 0)
> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*****************************************************************
> >>>> +**
> >>>> +************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01  3:21       ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-01  3:21 UTC (permalink / raw)
  To: Hans de Goede, Rafael J . Wysocki, Len Brown, Moore, Robert
  Cc: linux-acpi, devel

Hi,

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 06:19, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Some machines have the exact (byte for byte) same SSDT tables multiple
> >> times in the root_table_list.
> >
> > Could you give a machine list here?
> 
> Currently I'm seeing this on a GPD win machine:
> 
> http://www.gpd.hk/gpdwin.asp
> 
> I thought I was seeing it on more machines, but those have
> different apci table loading errors...

I'm not sure what the Windows clones will behave in this case.
Upon seeing a duplicate table, will Windows:
1. override old namespace node, or
2. discard (maybe silently) new namespace node that has conflict namespace hierarchy position against existing node, or
3. just complain us with a blue screen, or
4. compare all tables first.

Before knowing the de-facto standard behavior, I'm not sure if the behavior introduced by this commit is correct.
We should be able to judge if this case is real after knowing the Windows behavior.

So I don't think this commit goes the right direction on the right track.

> 
> >> Detect this and silently skip the duplicates
> >> rather then printing a scary looking set of errors.
> >
> > Why will this matter to OSPMs?
> 
> Not sure what you mean with OSPMs but I can tell you why this
> matters in general, Linux distributions like e.g. Fedora have
> been putting a lot of work in a smooth boot experience where
> end users do not get any scary text messages. For some more
> embedded like systems this even is a hard requirement.
> 
> The kernel supports quiet kernel cmdline argument to silence
> normal kernel messages, which is part of what is needed but
> messages with a log level of error still get shown, breaking
> the "no scary text messages" product requirement.
> 
> > And should we add non-costless steps just in order to reduce errors,
> 
> Yes we should, work on that front has been happening for years,
> also the CPU cost of this check is quite small, memcmp will
> only happen on identically sized tables and even then it will
> exit as soon as a single byte differs.

Even though, there are server systems containing many tables, almost one/two/three table(s) per CPU.
And you surely need to compare each of them against each of the others.

> 
> > while the errors are on the contrary useful (in1dicating platform issues)?
> 
> These errors are useful for developers / during testing but
> not in production setups, esp. in the case of duplicate tables
> where not loading the duplicate leads to 0 bad side effects.
> 
> I've an alternative proposal though, since this check just fixes
> a small part of the early boot messages caused by SSDT loading
> and since the code itself chooses to ignore any errors:
> 
>          /* Ignore errors while loading tables, get as many as possible */
> 
> How about setting a global flag while loading these tables and making
> 
> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> as well as turning the final:
> 
>                  ACPI_ERROR((AE_INFO,
>                              "%u table load failures, %u successful",
>                              tables_failed, tables_loaded));
> 
> Into a warning ?

So will Linux just unconditionally change pr_err() into pr_warn() in the printk.h?
ACPI_EXCEPTION here actually means blue screen in Windows.
Maybe it's correct, maybe not.
Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux ACPI implementation still has compliance issues against the de-facto standard.
Anyway, we should tune the logging level according to the de-facto standard behavior.

Thanks and best regards
Lv

> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> >
> > Thanks
> > Lv
> >
> >>
> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >> ---
> >>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >> index 82019c0..1971cd7 100644
> >> --- a/drivers/acpi/acpica/tbxfload.c
> >> +++ b/drivers/acpi/acpica/tbxfload.c
> >> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>
> >>  /*******************************************************************************
> >>   *
> >> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >> + *
> >> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >> + *              index         - index of table to find a duplicate of
> >> + *
> >> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >> + *
> >> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >> + *              avoid trying to load duplicate ssdt tables
> >> + *
> >> + ******************************************************************************/
> >> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >> +{
> >> +	struct acpi_table_desc *dup;
> >> +	u32 i;
> >> +
> >> +	for (i = 0; i < index; ++i) {
> >> +		dup = &acpi_gbl_root_table_list.tables[i];
> >> +
> >> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_PSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_OSDT))
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >> +		    || dup->length != table->length) {
> >> +			continue;
> >> +		}
> >> +
> >> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> >> +			return TRUE;
> >> +	}
> >> +	return FALSE;
> >> +}
> >> +
> >> +/*******************************************************************************
> >> + *
> >>   * FUNCTION:    acpi_tb_load_namespace
> >>   *
> >>   * PARAMETERS:  None
> >> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>  					   ACPI_SIG_PSDT)
> >>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>  					   ACPI_SIG_OSDT))
> >> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>  			continue;
> >>  		}
> >>
> >> --
> >> 2.9.3
> >

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01  3:21       ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-01  3:21 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 6593 bytes --]

Hi,

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 28-02-17 06:19, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Some machines have the exact (byte for byte) same SSDT tables multiple
> >> times in the root_table_list.
> >
> > Could you give a machine list here?
> 
> Currently I'm seeing this on a GPD win machine:
> 
> http://www.gpd.hk/gpdwin.asp
> 
> I thought I was seeing it on more machines, but those have
> different apci table loading errors...

I'm not sure what the Windows clones will behave in this case.
Upon seeing a duplicate table, will Windows:
1. override old namespace node, or
2. discard (maybe silently) new namespace node that has conflict namespace hierarchy position against existing node, or
3. just complain us with a blue screen, or
4. compare all tables first.

Before knowing the de-facto standard behavior, I'm not sure if the behavior introduced by this commit is correct.
We should be able to judge if this case is real after knowing the Windows behavior.

So I don't think this commit goes the right direction on the right track.

> 
> >> Detect this and silently skip the duplicates
> >> rather then printing a scary looking set of errors.
> >
> > Why will this matter to OSPMs?
> 
> Not sure what you mean with OSPMs but I can tell you why this
> matters in general, Linux distributions like e.g. Fedora have
> been putting a lot of work in a smooth boot experience where
> end users do not get any scary text messages. For some more
> embedded like systems this even is a hard requirement.
> 
> The kernel supports quiet kernel cmdline argument to silence
> normal kernel messages, which is part of what is needed but
> messages with a log level of error still get shown, breaking
> the "no scary text messages" product requirement.
> 
> > And should we add non-costless steps just in order to reduce errors,
> 
> Yes we should, work on that front has been happening for years,
> also the CPU cost of this check is quite small, memcmp will
> only happen on identically sized tables and even then it will
> exit as soon as a single byte differs.

Even though, there are server systems containing many tables, almost one/two/three table(s) per CPU.
And you surely need to compare each of them against each of the others.

> 
> > while the errors are on the contrary useful (in1dicating platform issues)?
> 
> These errors are useful for developers / during testing but
> not in production setups, esp. in the case of duplicate tables
> where not loading the duplicate leads to 0 bad side effects.
> 
> I've an alternative proposal though, since this check just fixes
> a small part of the early boot messages caused by SSDT loading
> and since the code itself chooses to ignore any errors:
> 
>          /* Ignore errors while loading tables, get as many as possible */
> 
> How about setting a global flag while loading these tables and making
> 
> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> as well as turning the final:
> 
>                  ACPI_ERROR((AE_INFO,
>                              "%u table load failures, %u successful",
>                              tables_failed, tables_loaded));
> 
> Into a warning ?

So will Linux just unconditionally change pr_err() into pr_warn() in the printk.h?
ACPI_EXCEPTION here actually means blue screen in Windows.
Maybe it's correct, maybe not.
Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux ACPI implementation still has compliance issues against the de-facto standard.
Anyway, we should tune the logging level according to the de-facto standard behavior.

Thanks and best regards
Lv

> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> >
> > Thanks
> > Lv
> >
> >>
> >> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >> ---
> >>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >> index 82019c0..1971cd7 100644
> >> --- a/drivers/acpi/acpica/tbxfload.c
> >> +++ b/drivers/acpi/acpica/tbxfload.c
> >> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>
> >>  /*******************************************************************************
> >>   *
> >> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >> + *
> >> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >> + *              index         - index of table to find a duplicate of
> >> + *
> >> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >> + *
> >> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >> + *              avoid trying to load duplicate ssdt tables
> >> + *
> >> + ******************************************************************************/
> >> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >> +{
> >> +	struct acpi_table_desc *dup;
> >> +	u32 i;
> >> +
> >> +	for (i = 0; i < index; ++i) {
> >> +		dup = &acpi_gbl_root_table_list.tables[i];
> >> +
> >> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_PSDT)
> >> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >> +					   ACPI_SIG_OSDT))
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >> +		    || dup->length != table->length) {
> >> +			continue;
> >> +		}
> >> +
> >> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
> >> +			return TRUE;
> >> +	}
> >> +	return FALSE;
> >> +}
> >> +
> >> +/*******************************************************************************
> >> + *
> >>   * FUNCTION:    acpi_tb_load_namespace
> >>   *
> >>   * PARAMETERS:  None
> >> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>  					   ACPI_SIG_PSDT)
> >>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>  					   ACPI_SIG_OSDT))
> >> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>  			continue;
> >>  		}
> >>
> >> --
> >> 2.9.3
> >

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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-03-01  3:21       ` [Devel] " Zheng, Lv
  (?)
@ 2017-03-01  9:19       ` Hans de Goede
  2017-03-01 20:38           ` [Devel] " Moore, Robert
  2017-03-02  1:59           ` [Devel] " Zheng, Lv
  -1 siblings, 2 replies; 51+ messages in thread
From: Hans de Goede @ 2017-03-01  9:19 UTC (permalink / raw)
  To: Zheng, Lv, Rafael J . Wysocki, Len Brown, Moore, Robert; +Cc: linux-acpi, devel

Hi,

On 01-03-17 04:21, Zheng, Lv wrote:
> Hi,
>
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>
>> Hi,
>>
>> On 28-02-17 06:19, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>
>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
>>>> times in the root_table_list.
>>>
>>> Could you give a machine list here?
>>
>> Currently I'm seeing this on a GPD win machine:
>>
>> http://www.gpd.hk/gpdwin.asp
>>
>> I thought I was seeing it on more machines, but those have
>> different apci table loading errors...
>
> I'm not sure what the Windows clones will behave in this case.
> Upon seeing a duplicate table, will Windows:
> 1. override old namespace node, or
> 2. discard (maybe silently) new namespace node that has conflict namespace hierarchy position against existing node, or
> 3. just complain us with a blue screen, or
> 4. compare all tables first.
>
> Before knowing the de-facto standard behavior, I'm not sure if the behavior introduced by this commit is correct.
> We should be able to judge if this case is real after knowing the Windows behavior.

It is impossible to know what Windows does under the hood, but it
does work without complaints on this device, so it certainly does
not do 3. As for 1., 2. and 4. since these are identical tables
the end result is the same in all 3 cases, it is as if only a
single copy was used:

1. Overriding with the exact same table is a no-op
2. Silently discarding means the old copy is used
4. Comparing tables and presumable then not loading duplicate
    ones will result in the old copy being used.

So it really does not matter which route windows goes, the
end result is: Things work without the user being show scary
error messages during boot.

> So I don't think this commit goes the right direction on the right track.
>
>>
>>>> Detect this and silently skip the duplicates
>>>> rather then printing a scary looking set of errors.
>>>
>>> Why will this matter to OSPMs?
>>
>> Not sure what you mean with OSPMs but I can tell you why this
>> matters in general, Linux distributions like e.g. Fedora have
>> been putting a lot of work in a smooth boot experience where
>> end users do not get any scary text messages. For some more
>> embedded like systems this even is a hard requirement.
>>
>> The kernel supports quiet kernel cmdline argument to silence
>> normal kernel messages, which is part of what is needed but
>> messages with a log level of error still get shown, breaking
>> the "no scary text messages" product requirement.
>>
>>> And should we add non-costless steps just in order to reduce errors,
>>
>> Yes we should, work on that front has been happening for years,
>> also the CPU cost of this check is quite small, memcmp will
>> only happen on identically sized tables and even then it will
>> exit as soon as a single byte differs.
>
> Even though, there are server systems containing many tables, almost one/two/three table(s) per CPU.
> And you surely need to compare each of them against each of the others.

And those machines typically take quite a lot time to boot anyways.

Note my patch is only checking previously loaded tables (we do want
to load the first copy). So all it is doing is accessing system memory
from the CPU. I think you will find in impossible to even measure the
extra boot time these few extra (likely cached) system memory accesses
take, let alone that it will be anywhere near relevant for the total
boot time.

>>> while the errors are on the contrary useful (in1dicating platform issues)?
>>
>> These errors are useful for developers / during testing but
>> not in production setups, esp. in the case of duplicate tables
>> where not loading the duplicate leads to 0 bad side effects.
>>
>> I've an alternative proposal though, since this check just fixes
>> a small part of the early boot messages caused by SSDT loading
>> and since the code itself chooses to ignore any errors:
>>
>>          /* Ignore errors while loading tables, get as many as possible */
>>
>> How about setting a global flag while loading these tables and making
>>
>> ACPI_EXCEPTION calls log the exceptions with a log level of warning
>> as well as turning the final:
>>
>>                  ACPI_ERROR((AE_INFO,
>>                              "%u table load failures, %u successful",
>>                              tables_failed, tables_loaded));
>>
>> Into a warning ?
>
> So will Linux just unconditionally change pr_err() into pr_warn() in the printk.h?

I'm not talking about unconditionally doing this, the acpica code itself
contains in drivers/acpi/acpica/tbxfload.c:

         /* Ignore errors while loading tables, get as many as possible */

Since acpica is ignoring errors here, it would seem reasonable to me for
acpica to treat all ACPI_ERROR / ACPI_EXCEPTION calls while doing this
as ACPI_WARNING calls.

> ACPI_EXCEPTION here actually means blue screen in Windows.
> Maybe it's correct, maybe not.
> Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux ACPI implementation still has compliance issues against the de-facto standard.

De-facto standard ? ACPI is a written standard, not a de-facto standard.
I surely hope ACPICA tries to implements the standard as written...

Regards,

Hans



>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>> ---
>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
>>>> index 82019c0..1971cd7 100644
>>>> --- a/drivers/acpi/acpica/tbxfload.c
>>>> +++ b/drivers/acpi/acpica/tbxfload.c
>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
>>>>
>>>>  /*******************************************************************************
>>>>   *
>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
>>>> + *
>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
>>>> + *              index         - index of table to find a duplicate of
>>>> + *
>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
>>>> + *
>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
>>>> + *              avoid trying to load duplicate ssdt tables
>>>> + *
>>>> + ******************************************************************************/
>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
>>>> +{
>>>> +	struct acpi_table_desc *dup;
>>>> +	u32 i;
>>>> +
>>>> +	for (i = 0; i < index; ++i) {
>>>> +		dup = &acpi_gbl_root_table_list.tables[i];
>>>> +
>>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
>>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
>>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>>>> +					   ACPI_SIG_PSDT)
>>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
>>>> +					   ACPI_SIG_OSDT))
>>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
>>>> +		    || dup->length != table->length) {
>>>> +			continue;
>>>> +		}
>>>> +
>>>> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)
>>>> +			return TRUE;
>>>> +	}
>>>> +	return FALSE;
>>>> +}
>>>> +
>>>> +/*******************************************************************************
>>>> + *
>>>>   * FUNCTION:    acpi_tb_load_namespace
>>>>   *
>>>>   * PARAMETERS:  None
>>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
>>>>  					   ACPI_SIG_PSDT)
>>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
>>>>  					   ACPI_SIG_OSDT))
>>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
>>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
>>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
>>>>  			continue;
>>>>  		}
>>>>
>>>> --
>>>> 2.9.3
>>>

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01 20:38           ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-03-01 20:38 UTC (permalink / raw)
  To: Hans de Goede, Zheng, Lv, Rafael J . Wysocki, Len Brown
  Cc: linux-acpi, devel, Box, David E

Sorry if I've missed any of this conversation, but I have a couple of thoughts:

1) It might be sufficient to just compare the incoming table header (36 bytes). The header contains both the table length and the checksum -- as well as the OEM ID and OEM version. I take it that the XSDT pointers to the duplicate tables are different.

2) As far as comparing every incoming SSDT byte-for-byte against all previously loaded SSDTs, I have to think "what about the boot time?". Especially since SSDTs are increasing in both size and number (See example from a real machine below).


ACPI: RSDP 0x0000000000492954 000024 (v02 Intel )
ACPI: XSDT 0x000000000068C938 0000B4 (v00 Intel  AcpiExec 00001001 INTL 20170224)
ACPI: FACP 0x0000000000492978 000114 (v05 Intel  AcpiExec 00001001 INTL 20170224)
ACPI: DSDT 0x0000000000690048 022FD6 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: FACS 0x0000000000492AB0 000040
ACPI: SSDT 0x00000000006B3028 0004B7 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x000000000068D940 000B49 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B34E8 0004A3 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B3998 000E58 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B47F8 00037F (v02 PmRef  Cpu0Cst  00003001 INTL 20121220)
ACPI: SSDT 0x000000000068E498 000660 (v02 PmRef  Cpu0Ist  00003000 INTL 20121220)
ACPI: SSDT 0x00000000006B4B80 0005AA (v02 PmRef  ApIst    00003000 INTL 20121220)
ACPI: SSDT 0x000000000068EB00 000119 (v02 PmRef  ApCst    00003000 INTL 20121220)
ACPI: SSDT 0x000000000068EC28 00004B (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B5138 0052EE (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BA430 002C4A (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BD088 0004C8 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x000000000068EC80 0002D4 (v01 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BD558 002BAE (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006C0110 00019A (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006C02B8 0006DC (v02 LENOVO CB-01    00000001 ACPI 00040000)




> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Sent: Wednesday, March 1, 2017 1:19 AM
> To: Zheng, Lv <lv.zheng@intel.com>; Rafael J . Wysocki
> <rjw@rjwysocki.net>; Len Brown <lenb@kernel.org>; Moore, Robert
> <robert.moore@intel.com>
> Cc: linux-acpi@vger.kernel.org; devel@acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 01-03-17 04:21, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables
> >>>> multiple times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have different
> >> apci table loading errors...
> >
> > I'm not sure what the Windows clones will behave in this case.
> > Upon seeing a duplicate table, will Windows:
> > 1. override old namespace node, or
> > 2. discard (maybe silently) new namespace node that has conflict
> > namespace hierarchy position against existing node, or 3. just
> > complain us with a blue screen, or 4. compare all tables first.
> >
> > Before knowing the de-facto standard behavior, I'm not sure if the
> behavior introduced by this commit is correct.
> > We should be able to judge if this case is real after knowing the
> Windows behavior.
> 
> It is impossible to know what Windows does under the hood, but it does
> work without complaints on this device, so it certainly does not do 3.
> As for 1., 2. and 4. since these are identical tables the end result is
> the same in all 3 cases, it is as if only a single copy was used:
> 
> 1. Overriding with the exact same table is a no-op 2. Silently
> discarding means the old copy is used 4. Comparing tables and presumable
> then not loading duplicate
>     ones will result in the old copy being used.
> 
> So it really does not matter which route windows goes, the end result
> is: Things work without the user being show scary error messages during
> boot.
> 
> > So I don't think this commit goes the right direction on the right
> track.
> >
> >>
> >>>> Detect this and silently skip the duplicates rather then printing a
> >>>> scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this matters
> >> in general, Linux distributions like e.g. Fedora have been putting a
> >> lot of work in a smooth boot experience where end users do not get
> >> any scary text messages. For some more embedded like systems this
> >> even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence normal
> >> kernel messages, which is part of what is needed but messages with a
> >> log level of error still get shown, breaking the "no scary text
> >> messages" product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years, also
> >> the CPU cost of this check is quite small, memcmp will only happen on
> >> identically sized tables and even then it will exit as soon as a
> >> single byte differs.
> >
> > Even though, there are server systems containing many tables, almost
> one/two/three table(s) per CPU.
> > And you surely need to compare each of them against each of the
> others.
> 
> And those machines typically take quite a lot time to boot anyways.
> 
> Note my patch is only checking previously loaded tables (we do want to
> load the first copy). So all it is doing is accessing system memory from
> the CPU. I think you will find in impossible to even measure the extra
> boot time these few extra (likely cached) system memory accesses take,
> let alone that it will be anywhere near relevant for the total boot
> time.
> 
> >>> while the errors are on the contrary useful (in1dicating platform
> issues)?
> >>
> >> These errors are useful for developers / during testing but not in
> >> production setups, esp. in the case of duplicate tables where not
> >> loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes a
> >> small part of the early boot messages caused by SSDT loading and
> >> since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as
> >> possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >
> > So will Linux just unconditionally change pr_err() into pr_warn() in
> the printk.h?
> 
> I'm not talking about unconditionally doing this, the acpica code itself
> contains in drivers/acpi/acpica/tbxfload.c:
> 
>          /* Ignore errors while loading tables, get as many as possible
> */
> 
> Since acpica is ignoring errors here, it would seem reasonable to me for
> acpica to treat all ACPI_ERROR / ACPI_EXCEPTION calls while doing this
> as ACPI_WARNING calls.
> 
> > ACPI_EXCEPTION here actually means blue screen in Windows.
> > Maybe it's correct, maybe not.
> > Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux
> ACPI implementation still has compliance issues against the de-facto
> standard.
> 
> De-facto standard ? ACPI is a written standard, not a de-facto standard.
> I surely hope ACPICA tries to implements the standard as written...
> 
> Regards,
> 
> Hans
> 
> 
> 
> >>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41
> >>>> ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c
> >>>> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>
> /***********************************************************************
> ********
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table
> to check
> >>>> + *              index         - index of table to find a duplicate
> of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> +
> >>>> +******************************************************************
> >>>> +************/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >>>> +acpi_table_desc *table, u32 index) {
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {
> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii,
> ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length)
> == 0)
> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*****************************************************************
> >>>> +**************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-01 20:38           ` Moore, Robert
  0 siblings, 0 replies; 51+ messages in thread
From: Moore, Robert @ 2017-03-01 20:38 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 11307 bytes --]

Sorry if I've missed any of this conversation, but I have a couple of thoughts:

1) It might be sufficient to just compare the incoming table header (36 bytes). The header contains both the table length and the checksum -- as well as the OEM ID and OEM version. I take it that the XSDT pointers to the duplicate tables are different.

2) As far as comparing every incoming SSDT byte-for-byte against all previously loaded SSDTs, I have to think "what about the boot time?". Especially since SSDTs are increasing in both size and number (See example from a real machine below).


ACPI: RSDP 0x0000000000492954 000024 (v02 Intel )
ACPI: XSDT 0x000000000068C938 0000B4 (v00 Intel  AcpiExec 00001001 INTL 20170224)
ACPI: FACP 0x0000000000492978 000114 (v05 Intel  AcpiExec 00001001 INTL 20170224)
ACPI: DSDT 0x0000000000690048 022FD6 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: FACS 0x0000000000492AB0 000040
ACPI: SSDT 0x00000000006B3028 0004B7 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x000000000068D940 000B49 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B34E8 0004A3 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B3998 000E58 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B47F8 00037F (v02 PmRef  Cpu0Cst  00003001 INTL 20121220)
ACPI: SSDT 0x000000000068E498 000660 (v02 PmRef  Cpu0Ist  00003000 INTL 20121220)
ACPI: SSDT 0x00000000006B4B80 0005AA (v02 PmRef  ApIst    00003000 INTL 20121220)
ACPI: SSDT 0x000000000068EB00 000119 (v02 PmRef  ApCst    00003000 INTL 20121220)
ACPI: SSDT 0x000000000068EC28 00004B (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006B5138 0052EE (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BA430 002C4A (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BD088 0004C8 (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x000000000068EC80 0002D4 (v01 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006BD558 002BAE (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006C0110 00019A (v02 LENOVO CB-01    00000001 ACPI 00040000)
ACPI: SSDT 0x00000000006C02B8 0006DC (v02 LENOVO CB-01    00000001 ACPI 00040000)




> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Sent: Wednesday, March 1, 2017 1:19 AM
> To: Zheng, Lv <lv.zheng(a)intel.com>; Rafael J . Wysocki
> <rjw(a)rjwysocki.net>; Len Brown <lenb(a)kernel.org>; Moore, Robert
> <robert.moore(a)intel.com>
> Cc: linux-acpi(a)vger.kernel.org; devel(a)acpica.org
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 01-03-17 04:21, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables
> >>>> multiple times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have different
> >> apci table loading errors...
> >
> > I'm not sure what the Windows clones will behave in this case.
> > Upon seeing a duplicate table, will Windows:
> > 1. override old namespace node, or
> > 2. discard (maybe silently) new namespace node that has conflict
> > namespace hierarchy position against existing node, or 3. just
> > complain us with a blue screen, or 4. compare all tables first.
> >
> > Before knowing the de-facto standard behavior, I'm not sure if the
> behavior introduced by this commit is correct.
> > We should be able to judge if this case is real after knowing the
> Windows behavior.
> 
> It is impossible to know what Windows does under the hood, but it does
> work without complaints on this device, so it certainly does not do 3.
> As for 1., 2. and 4. since these are identical tables the end result is
> the same in all 3 cases, it is as if only a single copy was used:
> 
> 1. Overriding with the exact same table is a no-op 2. Silently
> discarding means the old copy is used 4. Comparing tables and presumable
> then not loading duplicate
>     ones will result in the old copy being used.
> 
> So it really does not matter which route windows goes, the end result
> is: Things work without the user being show scary error messages during
> boot.
> 
> > So I don't think this commit goes the right direction on the right
> track.
> >
> >>
> >>>> Detect this and silently skip the duplicates rather then printing a
> >>>> scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this matters
> >> in general, Linux distributions like e.g. Fedora have been putting a
> >> lot of work in a smooth boot experience where end users do not get
> >> any scary text messages. For some more embedded like systems this
> >> even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence normal
> >> kernel messages, which is part of what is needed but messages with a
> >> log level of error still get shown, breaking the "no scary text
> >> messages" product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years, also
> >> the CPU cost of this check is quite small, memcmp will only happen on
> >> identically sized tables and even then it will exit as soon as a
> >> single byte differs.
> >
> > Even though, there are server systems containing many tables, almost
> one/two/three table(s) per CPU.
> > And you surely need to compare each of them against each of the
> others.
> 
> And those machines typically take quite a lot time to boot anyways.
> 
> Note my patch is only checking previously loaded tables (we do want to
> load the first copy). So all it is doing is accessing system memory from
> the CPU. I think you will find in impossible to even measure the extra
> boot time these few extra (likely cached) system memory accesses take,
> let alone that it will be anywhere near relevant for the total boot
> time.
> 
> >>> while the errors are on the contrary useful (in1dicating platform
> issues)?
> >>
> >> These errors are useful for developers / during testing but not in
> >> production setups, esp. in the case of duplicate tables where not
> >> loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes a
> >> small part of the early boot messages caused by SSDT loading and
> >> since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as
> >> possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >
> > So will Linux just unconditionally change pr_err() into pr_warn() in
> the printk.h?
> 
> I'm not talking about unconditionally doing this, the acpica code itself
> contains in drivers/acpi/acpica/tbxfload.c:
> 
>          /* Ignore errors while loading tables, get as many as possible
> */
> 
> Since acpica is ignoring errors here, it would seem reasonable to me for
> acpica to treat all ACPI_ERROR / ACPI_EXCEPTION calls while doing this
> as ACPI_WARNING calls.
> 
> > ACPI_EXCEPTION here actually means blue screen in Windows.
> > Maybe it's correct, maybe not.
> > Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux
> ACPI implementation still has compliance issues against the de-facto
> standard.
> 
> De-facto standard ? ACPI is a written standard, not a de-facto standard.
> I surely hope ACPICA tries to implements the standard as written...
> 
> Regards,
> 
> Hans
> 
> 
> 
> >>>> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41
> >>>> ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c
> >>>> b/drivers/acpi/acpica/tbxfload.c index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>
> /***********************************************************************
> ********
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table
> to check
> >>>> + *              index         - index of table to find a duplicate
> of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace
> to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> +
> >>>> +******************************************************************
> >>>> +************/ static u8 acpi_tb_find_duplicate_ssdt(struct
> >>>> +acpi_table_desc *table, u32 index) {
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {
> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||
> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii,
> ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))
> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length)
> == 0)
> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*****************************************************************
> >>>> +**************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {
> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-03-01 20:38           ` [Devel] " Moore, Robert
  (?)
@ 2017-03-01 21:56           ` Rafael J. Wysocki
  -1 siblings, 0 replies; 51+ messages in thread
From: Rafael J. Wysocki @ 2017-03-01 21:56 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Hans de Goede, Zheng, Lv, Rafael J . Wysocki, Len Brown,
	linux-acpi, devel, Box, David E

On Wed, Mar 1, 2017 at 9:38 PM, Moore, Robert <robert.moore@intel.com> wrote:
> Sorry if I've missed any of this conversation, but I have a couple of thoughts:
>
> 1) It might be sufficient to just compare the incoming table header (36 bytes). The header contains both the table length and the checksum -- as well as the OEM ID and OEM version. I take it that the XSDT pointers to the duplicate tables are different.
>
> 2) As far as comparing every incoming SSDT byte-for-byte against all previously loaded SSDTs, I have to think "what about the boot time?". Especially since SSDTs are increasing in both size and number (See example from a real machine below).
>
>
> ACPI: RSDP 0x0000000000492954 000024 (v02 Intel )
> ACPI: XSDT 0x000000000068C938 0000B4 (v00 Intel  AcpiExec 00001001 INTL 20170224)
> ACPI: FACP 0x0000000000492978 000114 (v05 Intel  AcpiExec 00001001 INTL 20170224)
> ACPI: DSDT 0x0000000000690048 022FD6 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: FACS 0x0000000000492AB0 000040
> ACPI: SSDT 0x00000000006B3028 0004B7 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x000000000068D940 000B49 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006B34E8 0004A3 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006B3998 000E58 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006B47F8 00037F (v02 PmRef  Cpu0Cst  00003001 INTL 20121220)
> ACPI: SSDT 0x000000000068E498 000660 (v02 PmRef  Cpu0Ist  00003000 INTL 20121220)
> ACPI: SSDT 0x00000000006B4B80 0005AA (v02 PmRef  ApIst    00003000 INTL 20121220)
> ACPI: SSDT 0x000000000068EB00 000119 (v02 PmRef  ApCst    00003000 INTL 20121220)
> ACPI: SSDT 0x000000000068EC28 00004B (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006B5138 0052EE (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006BA430 002C4A (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006BD088 0004C8 (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x000000000068EC80 0002D4 (v01 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006BD558 002BAE (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006C0110 00019A (v02 LENOVO CB-01    00000001 ACPI 00040000)
> ACPI: SSDT 0x00000000006C02B8 0006DC (v02 LENOVO CB-01    00000001 ACPI 00040000)
>

Right.

Whatever allows us to make a "we've loaded this table already, skip
it" decision without comparing byte-for-byte, please.

Thanks,
Rafael

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-02  1:59           ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-02  1:59 UTC (permalink / raw)
  To: Hans de Goede, Rafael J . Wysocki, Len Brown, Moore, Robert
  Cc: linux-acpi, devel

Hi,

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 01-03-17 04:21, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>> times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have
> >> different apci table loading errors...
> >
> > I'm not sure what the Windows clones will behave in this case.
> > Upon seeing a duplicate table, will Windows:
> > 1. override old namespace node, or
> > 2. discard (maybe silently) new namespace node that has conflict namespace hierarchy position
> against existing node, or
> > 3. just complain us with a blue screen, or
> > 4. compare all tables first.
> >
> > Before knowing the de-facto standard behavior, I'm not sure if the behavior introduced by this
> commit is correct.
> > We should be able to judge if this case is real after knowing the Windows behavior.
> 
> It is impossible to know what Windows does under the hood,

It's possible.
By injecting acpitable for qemu and obtain the test result via writing to a debugging port operation region field.
But you won't know if this error is silent or not.

Or if you have checked build windows clones, it is possible to see logs in windbg with amli enabled.
And you'll know if the error is silent or not.

> but it
> does work without complaints on this device, so it certainly does
> not do 3. As for 1., 2. and 4. since these are identical tables
> the end result is the same in all 3 cases, it is as if only a
> single copy was used:
> 
> 1. Overriding with the exact same table is a no-op
> 2. Silently discarding means the old copy is used
> 4. Comparing tables and presumable then not loading duplicate
>     ones will result in the old copy being used.
> 
> So it really does not matter which route windows goes, the
> end result is: Things work without the user being show scary
> error messages during boot.

OK, I can see you really prefer the workaround way rather than the natural way to achieve the same engineering result.
Then I'll give you suggestions on how it could be done better below.

> 
> > So I don't think this commit goes the right direction on the right track.
> >
> >>
> >>>> Detect this and silently skip the duplicates
> >>>> rather then printing a scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this
> >> matters in general, Linux distributions like e.g. Fedora have
> >> been putting a lot of work in a smooth boot experience where
> >> end users do not get any scary text messages. For some more
> >> embedded like systems this even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence
> >> normal kernel messages, which is part of what is needed but
> >> messages with a log level of error still get shown, breaking
> >> the "no scary text messages" product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years,
> >> also the CPU cost of this check is quite small, memcmp will
> >> only happen on identically sized tables and even then it will
> >> exit as soon as a single byte differs.
> >
> > Even though, there are server systems containing many tables, almost one/two/three table(s) per CPU.
> > And you surely need to compare each of them against each of the others.
> 
> And those machines typically take quite a lot time to boot anyways.
> 
> Note my patch is only checking previously loaded tables (we do want
> to load the first copy). So all it is doing is accessing system memory
> from the CPU. I think you will find in impossible to even measure the
> extra boot time these few extra (likely cached) system memory accesses
> take, let alone that it will be anywhere near relevant for the total
> boot time.

But if it is not done in natural way, I'm afraid other functionality won't get any benefit from doing this.
And after the root cause is determined and the right approach is upstreamed, the workarounds will need a cleanup.

So the whole thing looks to me is:
It's just increase a burden of maintenance by adding useless logics in order to reduce several error messages.
If it's not done in the right place, it's affection won't be minimized and actually makes things worse.

> 
> >>> while the errors are on the contrary useful (in1dicating platform issues)?
> >>
> >> These errors are useful for developers / during testing but
> >> not in production setups, esp. in the case of duplicate tables
> >> where not loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes
> >> a small part of the early boot messages caused by SSDT loading
> >> and since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >
> > So will Linux just unconditionally change pr_err() into pr_warn() in the printk.h?
> 
> I'm not talking about unconditionally doing this,

OK, I see.

> the acpica code itself
> contains in drivers/acpi/acpica/tbxfload.c:
> 
>          /* Ignore errors while loading tables, get as many as possible */

Actually, if Windows interpreter encounters an error during table load, there is only 1 result - blue screen.
During runtime, there is no blue screen but only exceptions returned to the drivers who call the method evaluations.
So this comment just means a compromise to me.

> 
> Since acpica is ignoring errors here, it would seem reasonable to me for
> acpica to treat all ACPI_ERROR / ACPI_EXCEPTION calls while doing this
> as ACPI_WARNING calls.
> 
> > ACPI_EXCEPTION here actually means blue screen in Windows.
> > Maybe it's correct, maybe not.
> > Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux ACPI implementation still has
> compliance issues against the de-facto standard.
> 
> De-facto standard ? ACPI is a written standard, not a de-facto standard.
> I surely hope ACPICA tries to implements the standard as written...

By calling de-facto standard, I mean Windows interpreter behavior.
Windows is the de-facto standard and almost all BIOSen are tested by running one of Windows clones.
And we are following Windows behavior rather than following the spec words.

> >>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>> index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>  /*******************************************************************************
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>> + *              index         - index of table to find a duplicate of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> + ******************************************************************************/
> >>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)

If you really want to add this.
My suggestion is:
Invoke this function in acpi_tb_verify_temp_table().
This is the function we use to verify if a table is OK.
Otherwise it won't be installed to the global table list.

And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.

> >>>> +{
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {

Parameter of index is not useful here.
You should use acpi_gbl_root_table_list.current_table_count instead.

> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||

The address check then is useless as for now we never uninstall tables once they are in acpi_gbl_root_table_list.

> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))

All above ones might be changed to just check if it is an AML table.
You can enable the function of acpi_ut_is_aml_table() for linux and invoke it here.

> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))

You won't need this, as you should invoke this function from a point in acpi_tb_verify_temp_table() where the table should have already been validated. 

> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)

I'm not sure if you know the story of acpi_gbl_verify_table_checksum.
IMO, you can only do this when acpi_gbl_verify_table_checksum is TRUE.
So in early stage, the functionality you introduced may still be a no-op for the same reason.

> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*******************************************************************************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {

So it shouldn't be invoked in acpi_tb_load_namespace().
If you really want it to be verified in case "acpi_gbl_verify_table_checksum=false" skipped the check.
You should find a right position (should be where the acpi_gbl_verify_table_checksum is set to TRUE),
Invoking acpi_tb_verify_temp_table() for those unverified tables (maybe a flag in acpi_table_desc).

That could be the right approach.

Thanks
Lv

> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-02  1:59           ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-02  1:59 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 11762 bytes --]

Hi,

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 01-03-17 04:21, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 28-02-17 06:19, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>> times in the root_table_list.
> >>>
> >>> Could you give a machine list here?
> >>
> >> Currently I'm seeing this on a GPD win machine:
> >>
> >> http://www.gpd.hk/gpdwin.asp
> >>
> >> I thought I was seeing it on more machines, but those have
> >> different apci table loading errors...
> >
> > I'm not sure what the Windows clones will behave in this case.
> > Upon seeing a duplicate table, will Windows:
> > 1. override old namespace node, or
> > 2. discard (maybe silently) new namespace node that has conflict namespace hierarchy position
> against existing node, or
> > 3. just complain us with a blue screen, or
> > 4. compare all tables first.
> >
> > Before knowing the de-facto standard behavior, I'm not sure if the behavior introduced by this
> commit is correct.
> > We should be able to judge if this case is real after knowing the Windows behavior.
> 
> It is impossible to know what Windows does under the hood,

It's possible.
By injecting acpitable for qemu and obtain the test result via writing to a debugging port operation region field.
But you won't know if this error is silent or not.

Or if you have checked build windows clones, it is possible to see logs in windbg with amli enabled.
And you'll know if the error is silent or not.

> but it
> does work without complaints on this device, so it certainly does
> not do 3. As for 1., 2. and 4. since these are identical tables
> the end result is the same in all 3 cases, it is as if only a
> single copy was used:
> 
> 1. Overriding with the exact same table is a no-op
> 2. Silently discarding means the old copy is used
> 4. Comparing tables and presumable then not loading duplicate
>     ones will result in the old copy being used.
> 
> So it really does not matter which route windows goes, the
> end result is: Things work without the user being show scary
> error messages during boot.

OK, I can see you really prefer the workaround way rather than the natural way to achieve the same engineering result.
Then I'll give you suggestions on how it could be done better below.

> 
> > So I don't think this commit goes the right direction on the right track.
> >
> >>
> >>>> Detect this and silently skip the duplicates
> >>>> rather then printing a scary looking set of errors.
> >>>
> >>> Why will this matter to OSPMs?
> >>
> >> Not sure what you mean with OSPMs but I can tell you why this
> >> matters in general, Linux distributions like e.g. Fedora have
> >> been putting a lot of work in a smooth boot experience where
> >> end users do not get any scary text messages. For some more
> >> embedded like systems this even is a hard requirement.
> >>
> >> The kernel supports quiet kernel cmdline argument to silence
> >> normal kernel messages, which is part of what is needed but
> >> messages with a log level of error still get shown, breaking
> >> the "no scary text messages" product requirement.
> >>
> >>> And should we add non-costless steps just in order to reduce errors,
> >>
> >> Yes we should, work on that front has been happening for years,
> >> also the CPU cost of this check is quite small, memcmp will
> >> only happen on identically sized tables and even then it will
> >> exit as soon as a single byte differs.
> >
> > Even though, there are server systems containing many tables, almost one/two/three table(s) per CPU.
> > And you surely need to compare each of them against each of the others.
> 
> And those machines typically take quite a lot time to boot anyways.
> 
> Note my patch is only checking previously loaded tables (we do want
> to load the first copy). So all it is doing is accessing system memory
> from the CPU. I think you will find in impossible to even measure the
> extra boot time these few extra (likely cached) system memory accesses
> take, let alone that it will be anywhere near relevant for the total
> boot time.

But if it is not done in natural way, I'm afraid other functionality won't get any benefit from doing this.
And after the root cause is determined and the right approach is upstreamed, the workarounds will need a cleanup.

So the whole thing looks to me is:
It's just increase a burden of maintenance by adding useless logics in order to reduce several error messages.
If it's not done in the right place, it's affection won't be minimized and actually makes things worse.

> 
> >>> while the errors are on the contrary useful (in1dicating platform issues)?
> >>
> >> These errors are useful for developers / during testing but
> >> not in production setups, esp. in the case of duplicate tables
> >> where not loading the duplicate leads to 0 bad side effects.
> >>
> >> I've an alternative proposal though, since this check just fixes
> >> a small part of the early boot messages caused by SSDT loading
> >> and since the code itself chooses to ignore any errors:
> >>
> >>          /* Ignore errors while loading tables, get as many as possible */
> >>
> >> How about setting a global flag while loading these tables and making
> >>
> >> ACPI_EXCEPTION calls log the exceptions with a log level of warning
> >> as well as turning the final:
> >>
> >>                  ACPI_ERROR((AE_INFO,
> >>                              "%u table load failures, %u successful",
> >>                              tables_failed, tables_loaded));
> >>
> >> Into a warning ?
> >
> > So will Linux just unconditionally change pr_err() into pr_warn() in the printk.h?
> 
> I'm not talking about unconditionally doing this,

OK, I see.

> the acpica code itself
> contains in drivers/acpi/acpica/tbxfload.c:
> 
>          /* Ignore errors while loading tables, get as many as possible */

Actually, if Windows interpreter encounters an error during table load, there is only 1 result - blue screen.
During runtime, there is no blue screen but only exceptions returned to the drivers who call the method evaluations.
So this comment just means a compromise to me.

> 
> Since acpica is ignoring errors here, it would seem reasonable to me for
> acpica to treat all ACPI_ERROR / ACPI_EXCEPTION calls while doing this
> as ACPI_WARNING calls.
> 
> > ACPI_EXCEPTION here actually means blue screen in Windows.
> > Maybe it's correct, maybe not.
> > Linux doesn't run into panic in ACPI_EXCEPTIION just because Linux ACPI implementation still has
> compliance issues against the de-facto standard.
> 
> De-facto standard ? ACPI is a written standard, not a de-facto standard.
> I surely hope ACPICA tries to implements the standard as written...

By calling de-facto standard, I mean Windows interpreter behavior.
Windows is the de-facto standard and almost all BIOSen are tested by running one of Windows clones.
And we are following Windows behavior rather than following the spec words.

> >>>> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >>>> ---
> >>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>> index 82019c0..1971cd7 100644
> >>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>
> >>>>  /*******************************************************************************
> >>>>   *
> >>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>> + *
> >>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>> + *              index         - index of table to find a duplicate of
> >>>> + *
> >>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>> + *
> >>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>> + *              avoid trying to load duplicate ssdt tables
> >>>> + *
> >>>> + ******************************************************************************/
> >>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)

If you really want to add this.
My suggestion is:
Invoke this function in acpi_tb_verify_temp_table().
This is the function we use to verify if a table is OK.
Otherwise it won't be installed to the global table list.

And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.

> >>>> +{
> >>>> +	struct acpi_table_desc *dup;
> >>>> +	u32 i;
> >>>> +
> >>>> +	for (i = 0; i < index; ++i) {

Parameter of index is not useful here.
You should use acpi_gbl_root_table_list.current_table_count instead.

> >>>> +		dup = &acpi_gbl_root_table_list.tables[i];
> >>>> +
> >>>> +		if (!acpi_gbl_root_table_list.tables[i].address ||

The address check then is useless as for now we never uninstall tables once they are in acpi_gbl_root_table_list.

> >>>> +		    (!ACPI_COMPARE_NAME(dup->signature.ascii, ACPI_SIG_SSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_PSDT)
> >>>> +		     && !ACPI_COMPARE_NAME(dup->signature.ascii,
> >>>> +					   ACPI_SIG_OSDT))

All above ones might be changed to just check if it is an AML table.
You can enable the function of acpi_ut_is_aml_table() for linux and invoke it here.

> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(dup))

You won't need this, as you should invoke this function from a point in acpi_tb_verify_temp_table() where the table should have already been validated. 

> >>>> +		    || dup->length != table->length) {
> >>>> +			continue;
> >>>> +		}
> >>>> +
> >>>> +		if (memcmp(dup->pointer, table->pointer, table->length) == 0)

I'm not sure if you know the story of acpi_gbl_verify_table_checksum.
IMO, you can only do this when acpi_gbl_verify_table_checksum is TRUE.
So in early stage, the functionality you introduced may still be a no-op for the same reason.

> >>>> +			return TRUE;
> >>>> +	}
> >>>> +	return FALSE;
> >>>> +}
> >>>> +
> >>>> +/*******************************************************************************
> >>>> + *
> >>>>   * FUNCTION:    acpi_tb_load_namespace
> >>>>   *
> >>>>   * PARAMETERS:  None
> >>>> @@ -212,7 +250,8 @@ acpi_status acpi_tb_load_namespace(void)
> >>>>  					   ACPI_SIG_PSDT)
> >>>>  		     && !ACPI_COMPARE_NAME(table->signature.ascii,
> >>>>  					   ACPI_SIG_OSDT))
> >>>> -		    || ACPI_FAILURE(acpi_tb_validate_table(table))) {
> >>>> +		    || ACPI_FAILURE(acpi_tb_validate_table(table))
> >>>> +		    || acpi_tb_find_duplicate_ssdt(table, i)) {

So it shouldn't be invoked in acpi_tb_load_namespace().
If you really want it to be verified in case "acpi_gbl_verify_table_checksum=false" skipped the check.
You should find a right position (should be where the acpi_gbl_verify_table_checksum is set to TRUE),
Invoking acpi_tb_verify_temp_table() for those unverified tables (maybe a flag in acpi_table_desc).

That could be the right approach.

Thanks
Lv

> >>>>  			continue;
> >>>>  		}
> >>>>
> >>>> --
> >>>> 2.9.3
> >>>

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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-03-02  1:59           ` [Devel] " Zheng, Lv
  (?)
@ 2017-03-02 15:24           ` Hans de Goede
  2017-03-03  2:50               ` [Devel] " Zheng, Lv
  -1 siblings, 1 reply; 51+ messages in thread
From: Hans de Goede @ 2017-03-02 15:24 UTC (permalink / raw)
  To: Zheng, Lv, Rafael J . Wysocki, Len Brown, Moore, Robert; +Cc: linux-acpi, devel

Hi,

On 02-03-17 02:59, Zheng, Lv wrote:
> Hi,
>
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>
>> Hi,
>>
>> On 01-03-17 04:21, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>
>>>> Hi,
>>>>
>>>> On 28-02-17 06:19, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>>>
>>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
>>>>>> times in the root_table_list.

<snip>

>>>>>> Detect this and silently skip the duplicates
>>>>>> rather then printing a scary looking set of errors.

<snip>

>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>>> ---
>>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
>>>>>> index 82019c0..1971cd7 100644
>>>>>> --- a/drivers/acpi/acpica/tbxfload.c
>>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
>>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
>>>>>>
>>>>>>  /*******************************************************************************
>>>>>>   *
>>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
>>>>>> + *
>>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
>>>>>> + *              index         - index of table to find a duplicate of
>>>>>> + *
>>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
>>>>>> + *
>>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
>>>>>> + *              avoid trying to load duplicate ssdt tables
>>>>>> + *
>>>>>> + ******************************************************************************/
>>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
>
> If you really want to add this.
> My suggestion is:
> Invoke this function in acpi_tb_verify_temp_table().
> This is the function we use to verify if a table is OK.
> Otherwise it won't be installed to the global table list.
>
> And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.

Ok, when I've some time I will do a new version moving the functionality
to acpi_tb_verify_temp_table(). I will post a v2 with this change when
it is ready. I will also just compare the headers then as suggested in
other replies in this thread.

Regards,

Hans

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-03  2:50               ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-03  2:50 UTC (permalink / raw)
  To: Hans de Goede, Rafael J . Wysocki, Len Brown, Moore, Robert
  Cc: linux-acpi, devel

Hi,

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 02-03-17 02:59, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 01-03-17 04:21, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 28-02-17 06:19, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>
> >>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>>>> times in the root_table_list.
> 
> <snip>
> 
> >>>>>> Detect this and silently skip the duplicates
> >>>>>> rather then printing a scary looking set of errors.
> 
> <snip>
> 
> >>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>>>> ---
> >>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>>>
> >>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>>>> index 82019c0..1971cd7 100644
> >>>>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>>>
> >>>>>>  /*******************************************************************************
> >>>>>>   *
> >>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>>>> + *
> >>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>>>> + *              index         - index of table to find a duplicate of
> >>>>>> + *
> >>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>>>> + *
> >>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>>>> + *              avoid trying to load duplicate ssdt tables
> >>>>>> + *
> >>>>>> + ******************************************************************************/
> >>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >
> > If you really want to add this.
> > My suggestion is:
> > Invoke this function in acpi_tb_verify_temp_table().
> > This is the function we use to verify if a table is OK.
> > Otherwise it won't be installed to the global table list.
> >
> > And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.
> 
> Ok, when I've some time I will do a new version moving the functionality
> to acpi_tb_verify_temp_table(). I will post a v2 with this change when
> it is ready. I will also just compare the headers then as suggested in
> other replies in this thread.

If you wish, I can offer help here.
It actually won't take me much time to generate such a change.

Thanks and best regards
Lv

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-03  2:50               ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-03  2:50 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3100 bytes --]

Hi,

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 02-03-17 02:59, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 01-03-17 04:21, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 28-02-17 06:19, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>
> >>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>>>> times in the root_table_list.
> 
> <snip>
> 
> >>>>>> Detect this and silently skip the duplicates
> >>>>>> rather then printing a scary looking set of errors.
> 
> <snip>
> 
> >>>>>> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >>>>>> ---
> >>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>>>
> >>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>>>> index 82019c0..1971cd7 100644
> >>>>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>>>
> >>>>>>  /*******************************************************************************
> >>>>>>   *
> >>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>>>> + *
> >>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>>>> + *              index         - index of table to find a duplicate of
> >>>>>> + *
> >>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>>>> + *
> >>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>>>> + *              avoid trying to load duplicate ssdt tables
> >>>>>> + *
> >>>>>> + ******************************************************************************/
> >>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >
> > If you really want to add this.
> > My suggestion is:
> > Invoke this function in acpi_tb_verify_temp_table().
> > This is the function we use to verify if a table is OK.
> > Otherwise it won't be installed to the global table list.
> >
> > And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.
> 
> Ok, when I've some time I will do a new version moving the functionality
> to acpi_tb_verify_temp_table(). I will post a v2 with this change when
> it is ready. I will also just compare the headers then as suggested in
> other replies in this thread.

If you wish, I can offer help here.
It actually won't take me much time to generate such a change.

Thanks and best regards
Lv

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

* Re: [PATCH] ACPICA: Detect duplicate SSDT tables
  2017-03-03  2:50               ` [Devel] " Zheng, Lv
  (?)
@ 2017-03-03 13:52               ` Hans de Goede
  2017-03-13  6:01                   ` [Devel] " Zheng, Lv
  -1 siblings, 1 reply; 51+ messages in thread
From: Hans de Goede @ 2017-03-03 13:52 UTC (permalink / raw)
  To: Zheng, Lv, Rafael J . Wysocki, Len Brown, Moore, Robert; +Cc: linux-acpi, devel

Hi,

On 03-03-17 03:50, Zheng, Lv wrote:
> Hi,
>
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>
>> Hi,
>>
>> On 02-03-17 02:59, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>
>>>> Hi,
>>>>
>>>> On 01-03-17 04:21, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On 28-02-17 06:19, Zheng, Lv wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>>>>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
>>>>>>>>
>>>>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
>>>>>>>> times in the root_table_list.
>>
>> <snip>
>>
>>>>>>>> Detect this and silently skip the duplicates
>>>>>>>> rather then printing a scary looking set of errors.
>>
>> <snip>
>>
>>>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>>>>> ---
>>>>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>>>>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
>>>>>>>> index 82019c0..1971cd7 100644
>>>>>>>> --- a/drivers/acpi/acpica/tbxfload.c
>>>>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
>>>>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
>>>>>>>>
>>>>>>>>  /*******************************************************************************
>>>>>>>>   *
>>>>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
>>>>>>>> + *
>>>>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
>>>>>>>> + *              index         - index of table to find a duplicate of
>>>>>>>> + *
>>>>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
>>>>>>>> + *
>>>>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
>>>>>>>> + *              avoid trying to load duplicate ssdt tables
>>>>>>>> + *
>>>>>>>> + ******************************************************************************/
>>>>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
>>>
>>> If you really want to add this.
>>> My suggestion is:
>>> Invoke this function in acpi_tb_verify_temp_table().
>>> This is the function we use to verify if a table is OK.
>>> Otherwise it won't be installed to the global table list.
>>>
>>> And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.
>>
>> Ok, when I've some time I will do a new version moving the functionality
>> to acpi_tb_verify_temp_table(). I will post a v2 with this change when
>> it is ready. I will also just compare the headers then as suggested in
>> other replies in this thread.
>
> If you wish, I can offer help here.
> It actually won't take me much time to generate such a change.

Great, if you can send me a new patch to test I'm more then willing
to make time to test it.

Thanks & Regards,

Hans

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

* RE: [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-13  6:01                   ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-13  6:01 UTC (permalink / raw)
  To: Hans de Goede, Rafael J . Wysocki, Len Brown, Moore, Robert
  Cc: linux-acpi, devel

Hi, Hans

I noticed that in AcpiTbInstallStandardTable(), there is a similar check:
        for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
        {
            /*
             * Check for a table match on the entire table length,
             * not just the header.
             */
            if (!AcpiTbCompareTables (&NewTableDesc, i))
            {
                continue;
            }
Could you check and tell us why this cannot cover your use case?
Is your use case related to the LoadTable opcode?
Thanks in advance.

Best regards
Lv

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 03-03-17 03:50, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 02-03-17 02:59, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 01-03-17 04:21, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>
> >>>>>> Hi,
> >>>>>>
> >>>>>> On 28-02-17 06:19, Zheng, Lv wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>>> From: Hans de Goede [mailto:hdegoede@redhat.com]
> >>>>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>>>
> >>>>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>>>>>> times in the root_table_list.
> >>
> >> <snip>
> >>
> >>>>>>>> Detect this and silently skip the duplicates
> >>>>>>>> rather then printing a scary looking set of errors.
> >>
> >> <snip>
> >>
> >>>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>>>>>> ---
> >>>>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>>>>>
> >>>>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> index 82019c0..1971cd7 100644
> >>>>>>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>>>>>
> >>>>>>>>  /*******************************************************************************
> >>>>>>>>   *
> >>>>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>>>>>> + *
> >>>>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>>>>>> + *              index         - index of table to find a duplicate of
> >>>>>>>> + *
> >>>>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>>>>>> + *
> >>>>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>>>>>> + *              avoid trying to load duplicate ssdt tables
> >>>>>>>> + *
> >>>>>>>> + ******************************************************************************/
> >>>>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >>>
> >>> If you really want to add this.
> >>> My suggestion is:
> >>> Invoke this function in acpi_tb_verify_temp_table().
> >>> This is the function we use to verify if a table is OK.
> >>> Otherwise it won't be installed to the global table list.
> >>>
> >>> And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.
> >>
> >> Ok, when I've some time I will do a new version moving the functionality
> >> to acpi_tb_verify_temp_table(). I will post a v2 with this change when
> >> it is ready. I will also just compare the headers then as suggested in
> >> other replies in this thread.
> >
> > If you wish, I can offer help here.
> > It actually won't take me much time to generate such a change.
> 
> Great, if you can send me a new patch to test I'm more then willing
> to make time to test it.
> 
> Thanks & Regards,
> 
> Hans

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

* Re: [Devel] [PATCH] ACPICA: Detect duplicate SSDT tables
@ 2017-03-13  6:01                   ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-03-13  6:01 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 4137 bytes --]

Hi, Hans

I noticed that in AcpiTbInstallStandardTable(), there is a similar check:
        for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
        {
            /*
             * Check for a table match on the entire table length,
             * not just the header.
             */
            if (!AcpiTbCompareTables (&NewTableDesc, i))
            {
                continue;
            }
Could you check and tell us why this cannot cover your use case?
Is your use case related to the LoadTable opcode?
Thanks in advance.

Best regards
Lv

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> 
> Hi,
> 
> On 03-03-17 03:50, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>
> >> Hi,
> >>
> >> On 02-03-17 02:59, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 01-03-17 04:21, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>>>> Subject: Re: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>
> >>>>>> Hi,
> >>>>>>
> >>>>>> On 28-02-17 06:19, Zheng, Lv wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>>> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> >>>>>>>> Subject: [PATCH] ACPICA: Detect duplicate SSDT tables
> >>>>>>>>
> >>>>>>>> Some machines have the exact (byte for byte) same SSDT tables multiple
> >>>>>>>> times in the root_table_list.
> >>
> >> <snip>
> >>
> >>>>>>>> Detect this and silently skip the duplicates
> >>>>>>>> rather then printing a scary looking set of errors.
> >>
> >> <snip>
> >>
> >>>>>>>> Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
> >>>>>>>> ---
> >>>>>>>>  drivers/acpi/acpica/tbxfload.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>>>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>>>>>
> >>>>>>>> diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> index 82019c0..1971cd7 100644
> >>>>>>>> --- a/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> +++ b/drivers/acpi/acpica/tbxfload.c
> >>>>>>>> @@ -125,6 +125,44 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
> >>>>>>>>
> >>>>>>>>  /*******************************************************************************
> >>>>>>>>   *
> >>>>>>>> + * FUNCTION:    acpi_tb_find_duplicate_ssdt
> >>>>>>>> + *
> >>>>>>>> + * PARAMETERS:  table         - validated acpi_table_desc of table to check
> >>>>>>>> + *              index         - index of table to find a duplicate of
> >>>>>>>> + *
> >>>>>>>> + * RETURN:      TRUE if a duplicate is found, FALSE if not
> >>>>>>>> + *
> >>>>>>>> + * DESCRIPTION: Private helper function for acpi_tb_load_namespace to
> >>>>>>>> + *              avoid trying to load duplicate ssdt tables
> >>>>>>>> + *
> >>>>>>>> + ******************************************************************************/
> >>>>>>>> +static u8 acpi_tb_find_duplicate_ssdt(struct acpi_table_desc *table, u32 index)
> >>>
> >>> If you really want to add this.
> >>> My suggestion is:
> >>> Invoke this function in acpi_tb_verify_temp_table().
> >>> This is the function we use to verify if a table is OK.
> >>> Otherwise it won't be installed to the global table list.
> >>>
> >>> And the name should contain "aml_table" or "aml" rather than "ssdt" according to your check below.
> >>
> >> Ok, when I've some time I will do a new version moving the functionality
> >> to acpi_tb_verify_temp_table(). I will post a v2 with this change when
> >> it is ready. I will also just compare the headers then as suggested in
> >> other replies in this thread.
> >
> > If you wish, I can offer help here.
> > It actually won't take me much time to generate such a change.
> 
> Great, if you can send me a new patch to test I'm more then willing
> to make time to test it.
> 
> Thanks & Regards,
> 
> Hans

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

* [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-16  7:13   ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

On linux, we can not verify ACPI tables before installing them into the
global table list in early stage due to the number of slot limitations for
early ioremap. This leaves a problem that we cannot detect duplicated
tables in early stage, causing unwanted error messages seen when the
duplicated tables are failed to be loaded [link #1].

This patchset as ACPICA PR [link #2] adds support to verify tables in
acpi_reallocate_root_tables() which is invoked after installing tables in
early stage, being ready for late ioremap and beofre loading table in late
stage. If duplicated tables are detected, acpi_reallocate_root_tables()
stops installing them to the final reallocated global table list.

In v1 patchset [link #3], problems can be seen for dynamic loading tables
which are allocated as virtuall allocated tables. Such tables are
incremented in the global table list as the sanity check done in install
step only compares the table addresses while the virtual allocated
addresses are not stable.
In v2 patchset, we follow original design discussion made in ACPICA devel
mailing list, implements deferred table verification so that duplicate
tables are still can be detected in install step rather than in load step.
Also we removed table signature check according to verified windows
behavior [link #4] and reported issues [link #5].

Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
Link: https://github.com//acpica/acpica/pull/265            [#2]
Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
Link: https://github.com//acpica/acpica/pull/121            [#4]
      https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]

Lv Zheng (5):
  ACPICA: Tables: Cleanup table handler invokers
  ACPICA: Tables: Do not validate signature for dynamic table load
  ACPICA: Tables: Change table duplication check to be related to
    acpi_gbl_verify_table_checksum
  ACPICA: Tables: Combine checksum/duplication verification together
  ACPICA: Tables: Add deferred table verification support

 drivers/acpi/acpica/actables.h |   5 +-
 drivers/acpi/acpica/tbdata.c   | 222 ++++++++++++++++++++++++++++++++++++-----
 drivers/acpi/acpica/tbinstal.c | 161 ++++--------------------------
 drivers/acpi/acpica/tbxface.c  |  36 ++++++-
 drivers/acpi/acpica/tbxfload.c |   2 +-
 drivers/acpi/bus.c             |   3 -
 drivers/acpi/tables.c          |   4 +-
 include/acpi/acpixf.h          |  15 +--
 include/acpi/actbl.h           |   1 +
 9 files changed, 266 insertions(+), 183 deletions(-)

-- 
2.7.4


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

* [Devel] [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-16  7:13   ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 2585 bytes --]

On linux, we can not verify ACPI tables before installing them into the
global table list in early stage due to the number of slot limitations for
early ioremap. This leaves a problem that we cannot detect duplicated
tables in early stage, causing unwanted error messages seen when the
duplicated tables are failed to be loaded [link #1].

This patchset as ACPICA PR [link #2] adds support to verify tables in
acpi_reallocate_root_tables() which is invoked after installing tables in
early stage, being ready for late ioremap and beofre loading table in late
stage. If duplicated tables are detected, acpi_reallocate_root_tables()
stops installing them to the final reallocated global table list.

In v1 patchset [link #3], problems can be seen for dynamic loading tables
which are allocated as virtuall allocated tables. Such tables are
incremented in the global table list as the sanity check done in install
step only compares the table addresses while the virtual allocated
addresses are not stable.
In v2 patchset, we follow original design discussion made in ACPICA devel
mailing list, implements deferred table verification so that duplicate
tables are still can be detected in install step rather than in load step.
Also we removed table signature check according to verified windows
behavior [link #4] and reported issues [link #5].

Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
Link: https://github.com//acpica/acpica/pull/265            [#2]
Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
Link: https://github.com//acpica/acpica/pull/121            [#4]
      https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]

Lv Zheng (5):
  ACPICA: Tables: Cleanup table handler invokers
  ACPICA: Tables: Do not validate signature for dynamic table load
  ACPICA: Tables: Change table duplication check to be related to
    acpi_gbl_verify_table_checksum
  ACPICA: Tables: Combine checksum/duplication verification together
  ACPICA: Tables: Add deferred table verification support

 drivers/acpi/acpica/actables.h |   5 +-
 drivers/acpi/acpica/tbdata.c   | 222 ++++++++++++++++++++++++++++++++++++-----
 drivers/acpi/acpica/tbinstal.c | 161 ++++--------------------------
 drivers/acpi/acpica/tbxface.c  |  36 ++++++-
 drivers/acpi/acpica/tbxfload.c |   2 +-
 drivers/acpi/bus.c             |   3 -
 drivers/acpi/tables.c          |   4 +-
 include/acpi/acpixf.h          |  15 +--
 include/acpi/actbl.h           |   1 +
 9 files changed, 266 insertions(+), 183 deletions(-)

-- 
2.7.4


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

* [RFC PATCH v2 1/5] ACPICA: Tables: Cleanup table handler invokers
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

Recently, we allows the table mutex to be held in both early and late stage
APIs. This patch further cleans up the related code to reduce redundant
code related to acpi_gbl_table_handler. Lv Zheng.

Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/actables.h |  2 ++
 drivers/acpi/acpica/tbdata.c   | 43 ++++++++++++++++++++++++++++--------------
 drivers/acpi/acpica/tbinstal.c |  8 ++------
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index c8da453..89ed31b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -132,6 +132,8 @@ acpi_tb_install_and_load_table(acpi_physical_address address,
 
 acpi_status acpi_tb_unload_table(u32 table_index);
 
+void acpi_tb_notify_table(u32 event, void *table);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 27c5c27..42ea044 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -818,13 +818,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
 		acpi_ev_update_gpes(owner_id);
 	}
 
-	/* Invoke table handler if present */
-
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
-					     acpi_gbl_table_handler_context);
-	}
+	/* Invoke table handler */
 
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
 	return_ACPI_STATUS(status);
 }
 
@@ -892,15 +888,11 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
-	if (acpi_gbl_table_handler) {
-		status = acpi_get_table_by_index(table_index, &table);
-		if (ACPI_SUCCESS(status)) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     table,
-						     acpi_gbl_table_handler_context);
-		}
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
 	}
 
 	/* Delete the portion of the namespace owned by this table */
@@ -914,3 +906,26 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 	return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_notify_table
+ *
+ * PARAMETERS:  event               - Table event
+ *              table               - Validated table pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Notify a table event to the users.
+ *
+ ******************************************************************************/
+
+void acpi_tb_notify_table(u32 event, void *table)
+{
+	/* Invoke table handler if present */
+
+	if (acpi_gbl_table_handler) {
+		(void)acpi_gbl_table_handler(event, table,
+					     acpi_gbl_table_handler_context);
+	}
+}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 4620f3c..ee74515 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -306,14 +306,10 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	acpi_tb_install_table_with_override(&new_table_desc, override,
 					    table_index);
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_INSTALL,
-					     new_table_desc.pointer,
-					     acpi_gbl_table_handler_context);
-	}
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 unlock_and_exit:
-- 
2.7.4


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

* [Devel] [RFC PATCH v2 1/5] ACPICA: Tables: Cleanup table handler invokers
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3965 bytes --]

Recently, we allows the table mutex to be held in both early and late stage
APIs. This patch further cleans up the related code to reduce redundant
code related to acpi_gbl_table_handler. Lv Zheng.

Tested-by: Hans de Goede <hdegoede(a)redhat.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/actables.h |  2 ++
 drivers/acpi/acpica/tbdata.c   | 43 ++++++++++++++++++++++++++++--------------
 drivers/acpi/acpica/tbinstal.c |  8 ++------
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index c8da453..89ed31b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -132,6 +132,8 @@ acpi_tb_install_and_load_table(acpi_physical_address address,
 
 acpi_status acpi_tb_unload_table(u32 table_index);
 
+void acpi_tb_notify_table(u32 event, void *table);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 27c5c27..42ea044 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -818,13 +818,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
 		acpi_ev_update_gpes(owner_id);
 	}
 
-	/* Invoke table handler if present */
-
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
-					     acpi_gbl_table_handler_context);
-	}
+	/* Invoke table handler */
 
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
 	return_ACPI_STATUS(status);
 }
 
@@ -892,15 +888,11 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
-	if (acpi_gbl_table_handler) {
-		status = acpi_get_table_by_index(table_index, &table);
-		if (ACPI_SUCCESS(status)) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     table,
-						     acpi_gbl_table_handler_context);
-		}
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
 	}
 
 	/* Delete the portion of the namespace owned by this table */
@@ -914,3 +906,26 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 	return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_notify_table
+ *
+ * PARAMETERS:  event               - Table event
+ *              table               - Validated table pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Notify a table event to the users.
+ *
+ ******************************************************************************/
+
+void acpi_tb_notify_table(u32 event, void *table)
+{
+	/* Invoke table handler if present */
+
+	if (acpi_gbl_table_handler) {
+		(void)acpi_gbl_table_handler(event, table,
+					     acpi_gbl_table_handler_context);
+	}
+}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 4620f3c..ee74515 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -306,14 +306,10 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	acpi_tb_install_table_with_override(&new_table_desc, override,
 					    table_index);
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_INSTALL,
-					     new_table_desc.pointer,
-					     acpi_gbl_table_handler_context);
-	}
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 unlock_and_exit:
-- 
2.7.4


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

* [RFC PATCH v2 2/5] ACPICA: Tables: Do not validate signature for dynamic table load
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

Windows seems to allow arbitrary table signatures for Load/load_table
opcodes:
  ACPI BIOS Error (bug): Table has invalid signature [PRAD] (0x44415250)
So this patch removes dynamic load signature checks. However we need to
find a way to avoid table loading against tables like MADT. This is not
covered by this commit.

This Windows behavior has been validated on link #1. An end user bug
report can also be found on link #2.

This patch also includes simple cleanup for static load signature check
code. Reported by Ye Xiaolong, Fixed by Lv Zheng.

Link: https://github.com/acpica/acpica/pull/121 [#1]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=118601 [#2]
Reported-by: Ye Xiaolong <xiaolong.ye@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbinstal.c | 28 ----------------------------
 drivers/acpi/acpica/tbxfload.c |  2 +-
 2 files changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index ee74515..9d21296 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -222,34 +222,6 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 	if (reload) {
-		/*
-		 * Validate the incoming table signature.
-		 *
-		 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
-		 * 2) We added support for OEMx tables, signature "OEM".
-		 * 3) Valid tables were encountered with a null signature, so we just
-		 *    gave up on validating the signature, (05/2008).
-		 * 4) We encountered non-AML tables such as the MADT, which caused
-		 *    interpreter errors and kernel faults. So now, we once again allow
-		 *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
-		 */
-		if ((new_table_desc.signature.ascii[0] != 0x00) &&
-		    (!ACPI_COMPARE_NAME
-		     (&new_table_desc.signature, ACPI_SIG_SSDT))
-		    && (strncmp(new_table_desc.signature.ascii, "OEM", 3))) {
-			ACPI_BIOS_ERROR((AE_INFO,
-					 "Table has invalid signature [%4.4s] (0x%8.8X), "
-					 "must be SSDT or OEMx",
-					 acpi_ut_valid_nameseg(new_table_desc.
-							       signature.
-							       ascii) ?
-					 new_table_desc.signature.
-					 ascii : "????",
-					 new_table_desc.signature.integer));
-
-			status = AE_BAD_SIGNATURE;
-			goto unlock_and_exit;
-		}
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index b71ce3b..d81f442 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -206,7 +206,7 @@ acpi_status acpi_tb_load_namespace(void)
 	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
 		table = &acpi_gbl_root_table_list.tables[i];
 
-		if (!acpi_gbl_root_table_list.tables[i].address ||
+		if (!table->address ||
 		    (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
 		     && !ACPI_COMPARE_NAME(table->signature.ascii,
 					   ACPI_SIG_PSDT)
-- 
2.7.4


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

* [Devel] [RFC PATCH v2 2/5] ACPICA: Tables: Do not validate signature for dynamic table load
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3100 bytes --]

Windows seems to allow arbitrary table signatures for Load/load_table
opcodes:
  ACPI BIOS Error (bug): Table has invalid signature [PRAD] (0x44415250)
So this patch removes dynamic load signature checks. However we need to
find a way to avoid table loading against tables like MADT. This is not
covered by this commit.

This Windows behavior has been validated on link #1. An end user bug
report can also be found on link #2.

This patch also includes simple cleanup for static load signature check
code. Reported by Ye Xiaolong, Fixed by Lv Zheng.

Link: https://github.com/acpica/acpica/pull/121 [#1]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=118601 [#2]
Reported-by: Ye Xiaolong <xiaolong.ye(a)intel.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbinstal.c | 28 ----------------------------
 drivers/acpi/acpica/tbxfload.c |  2 +-
 2 files changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index ee74515..9d21296 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -222,34 +222,6 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 	if (reload) {
-		/*
-		 * Validate the incoming table signature.
-		 *
-		 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
-		 * 2) We added support for OEMx tables, signature "OEM".
-		 * 3) Valid tables were encountered with a null signature, so we just
-		 *    gave up on validating the signature, (05/2008).
-		 * 4) We encountered non-AML tables such as the MADT, which caused
-		 *    interpreter errors and kernel faults. So now, we once again allow
-		 *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
-		 */
-		if ((new_table_desc.signature.ascii[0] != 0x00) &&
-		    (!ACPI_COMPARE_NAME
-		     (&new_table_desc.signature, ACPI_SIG_SSDT))
-		    && (strncmp(new_table_desc.signature.ascii, "OEM", 3))) {
-			ACPI_BIOS_ERROR((AE_INFO,
-					 "Table has invalid signature [%4.4s] (0x%8.8X), "
-					 "must be SSDT or OEMx",
-					 acpi_ut_valid_nameseg(new_table_desc.
-							       signature.
-							       ascii) ?
-					 new_table_desc.signature.
-					 ascii : "????",
-					 new_table_desc.signature.integer));
-
-			status = AE_BAD_SIGNATURE;
-			goto unlock_and_exit;
-		}
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index b71ce3b..d81f442 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -206,7 +206,7 @@ acpi_status acpi_tb_load_namespace(void)
 	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
 		table = &acpi_gbl_root_table_list.tables[i];
 
-		if (!acpi_gbl_root_table_list.tables[i].address ||
+		if (!table->address ||
 		    (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
 		     && !ACPI_COMPARE_NAME(table->signature.ascii,
 					   ACPI_SIG_PSDT)
-- 
2.7.4


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

* [RFC PATCH v2 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

acpi_gbl_verify_table_checksum is used to avoid validating (mapping) an entire
table in OS boot stage. 2nd "Reload" check in acpi_tb_install_standard_table()
is prepared for the same purpose. So this patch combines them together
using a renamed acpi_gbl_enable_table_validation flag. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbdata.c   |  4 ++--
 drivers/acpi/acpica/tbinstal.c |  2 +-
 drivers/acpi/acpica/tbxface.c  |  8 ++++++++
 drivers/acpi/bus.c             |  2 +-
 drivers/acpi/tables.c          |  4 ++--
 include/acpi/acpixf.h          | 15 ++++++++-------
 6 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 42ea044..e81355b 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -338,7 +338,7 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 {
 
-	if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) {
+	if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
 		/*
 		 * Only validates the header of the table.
 		 * Note that Length contains the size of the mapping after invoking
@@ -394,7 +394,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 	/* Verify the checksum */
 
-	if (acpi_gbl_verify_table_checksum) {
+	if (acpi_gbl_enable_table_validation) {
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9d21296..f7bc362 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -221,7 +221,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (reload) {
+	if (acpi_gbl_enable_table_validation) {
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 010b1c43..b0dc841 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -194,6 +194,14 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 		}
 	}
 
+	if (!acpi_gbl_enable_table_validation) {
+		/*
+		 * Now it's safe to do full table validation. We can do deferred
+		 * table initilization here once the flag is set.
+		 */
+		acpi_gbl_enable_table_validation = TRUE;
+	}
+
 	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
 	status = acpi_tb_resize_root_table_list();
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 34fbe02..c26342f 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1010,7 +1010,7 @@ void __init acpi_early_init(void)
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
 	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_verify_table_checksum = TRUE;
+	acpi_gbl_enable_table_validation = TRUE;
 
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 0dae722..b5cc09c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -740,10 +740,10 @@ int __init acpi_table_init(void)
 
 	if (acpi_verify_table_checksum) {
 		pr_info("Early table checksum verification enabled\n");
-		acpi_gbl_verify_table_checksum = TRUE;
+		acpi_gbl_enable_table_validation = TRUE;
 	} else {
 		pr_info("Early table checksum verification disabled\n");
-		acpi_gbl_verify_table_checksum = FALSE;
+		acpi_gbl_enable_table_validation = FALSE;
 	}
 
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 15c86ce..88a1de8 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -160,13 +160,14 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
 
 /*
- * Whether or not to verify the table checksum before installation. Set
- * this to TRUE to verify the table checksum before install it to the table
- * manager. Note that enabling this option causes errors to happen in some
- * OSPMs during early initialization stages. Default behavior is to do such
- * verification.
- */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE);
+ * Whether or not to validate (map) an entire table to verify
+ * checksum/duplication in early stage before install. Set this to TRUE to
+ * allow early table validation before install it to the table manager.
+ * Note that enabling this option causes errors to happen in some OSPMs
+ * during early initialization stages. Default behavior is to allow such
+ * validation.
+ */
+ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE);
 
 /*
  * Optionally enable output from the AML Debug Object.
-- 
2.7.4


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

* [Devel] [RFC PATCH v2 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 5034 bytes --]

acpi_gbl_verify_table_checksum is used to avoid validating (mapping) an entire
table in OS boot stage. 2nd "Reload" check in acpi_tb_install_standard_table()
is prepared for the same purpose. So this patch combines them together
using a renamed acpi_gbl_enable_table_validation flag. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbdata.c   |  4 ++--
 drivers/acpi/acpica/tbinstal.c |  2 +-
 drivers/acpi/acpica/tbxface.c  |  8 ++++++++
 drivers/acpi/bus.c             |  2 +-
 drivers/acpi/tables.c          |  4 ++--
 include/acpi/acpixf.h          | 15 ++++++++-------
 6 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 42ea044..e81355b 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -338,7 +338,7 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 {
 
-	if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) {
+	if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
 		/*
 		 * Only validates the header of the table.
 		 * Note that Length contains the size of the mapping after invoking
@@ -394,7 +394,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 	/* Verify the checksum */
 
-	if (acpi_gbl_verify_table_checksum) {
+	if (acpi_gbl_enable_table_validation) {
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9d21296..f7bc362 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -221,7 +221,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (reload) {
+	if (acpi_gbl_enable_table_validation) {
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 010b1c43..b0dc841 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -194,6 +194,14 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 		}
 	}
 
+	if (!acpi_gbl_enable_table_validation) {
+		/*
+		 * Now it's safe to do full table validation. We can do deferred
+		 * table initilization here once the flag is set.
+		 */
+		acpi_gbl_enable_table_validation = TRUE;
+	}
+
 	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
 	status = acpi_tb_resize_root_table_list();
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 34fbe02..c26342f 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1010,7 +1010,7 @@ void __init acpi_early_init(void)
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
 	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_verify_table_checksum = TRUE;
+	acpi_gbl_enable_table_validation = TRUE;
 
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 0dae722..b5cc09c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -740,10 +740,10 @@ int __init acpi_table_init(void)
 
 	if (acpi_verify_table_checksum) {
 		pr_info("Early table checksum verification enabled\n");
-		acpi_gbl_verify_table_checksum = TRUE;
+		acpi_gbl_enable_table_validation = TRUE;
 	} else {
 		pr_info("Early table checksum verification disabled\n");
-		acpi_gbl_verify_table_checksum = FALSE;
+		acpi_gbl_enable_table_validation = FALSE;
 	}
 
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 15c86ce..88a1de8 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -160,13 +160,14 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
 
 /*
- * Whether or not to verify the table checksum before installation. Set
- * this to TRUE to verify the table checksum before install it to the table
- * manager. Note that enabling this option causes errors to happen in some
- * OSPMs during early initialization stages. Default behavior is to do such
- * verification.
- */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE);
+ * Whether or not to validate (map) an entire table to verify
+ * checksum/duplication in early stage before install. Set this to TRUE to
+ * allow early table validation before install it to the table manager.
+ * Note that enabling this option causes errors to happen in some OSPMs
+ * during early initialization stages. Default behavior is to allow such
+ * validation.
+ */
+ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE);
 
 /*
  * Optionally enable output from the AML Debug Object.
-- 
2.7.4


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

* [RFC PATCH v2 4/5] ACPICA: Tables: Combine checksum/duplication verification together
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

They are all mechanism used to verify if a table is qualified to be
installed and controlled by acpi_gbl_enable_table_validation, so combine
them together. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/actables.h |   3 +-
 drivers/acpi/acpica/tbdata.c   | 148 +++++++++++++++++++++++++++++++++++++++--
 drivers/acpi/acpica/tbinstal.c | 124 ++++++----------------------------
 3 files changed, 165 insertions(+), 110 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 89ed31b..84a3ceb 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -76,7 +76,8 @@ void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc);
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature);
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index);
 
 u8 acpi_tb_is_table_loaded(u32 table_index);
 
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index e81355b..2dee2cd 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -50,6 +50,57 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbdata")
 
+/* Local prototypes */
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_compare_tables
+ *
+ * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
+ *              table_index         - Index of table 2 to be compared
+ *
+ * RETURN:      TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ *              already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
+{
+	acpi_status status = AE_OK;
+	u8 is_identical;
+	struct acpi_table_header *table;
+	u32 table_length;
+	u8 table_flags;
+
+	status =
+	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
+				  &table, &table_length, &table_flags);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	/*
+	 * Check for a table match on the entire table length,
+	 * not just the header.
+	 */
+	is_identical = (u8)((table_desc->length != table_length ||
+			     memcmp(table_desc->pointer, table, table_length)) ?
+			    FALSE : TRUE);
+
+	/* Release the acquired table */
+
+	acpi_tb_release_table(table, table_length, table_flags);
+	return (is_identical);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_init_table_descriptor
@@ -64,6 +115,7 @@ ACPI_MODULE_NAME("tbdata")
  * DESCRIPTION: Initialize a new table descriptor
  *
  ******************************************************************************/
+
 void
 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
 			      acpi_physical_address address,
@@ -354,12 +406,78 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 	return (acpi_tb_validate_table(table_desc));
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_check_duplication
+ *
+ * PARAMETERS:  table_desc          - Table descriptor
+ *              table_index         - Where the table index is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Avoid installing duplicated tables. However table override and
+ *              user aided dynamic table load is allowed, thus comparing the
+ *              address of the table is not sufficient, and checking the entire
+ *              table content is required.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
+{
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(tb_check_duplication);
+
+	/* Check if table is already registered */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+		/*
+		 * Check for a table match on the entire table length,
+		 * not just the header.
+		 */
+		if (!acpi_tb_compare_tables(table_desc, i)) {
+			continue;
+		}
+
+		/*
+		 * Note: the current mechanism does not unregister a table if it is
+		 * dynamically unloaded. The related namespace entries are deleted,
+		 * but the table remains in the root table list.
+		 *
+		 * The assumption here is that the number of different tables that
+		 * will be loaded is actually small, and there is minimal overhead
+		 * in just keeping the table in case it is needed again.
+		 *
+		 * If this assumption changes in the future (perhaps on large
+		 * machines with many table load/unload operations), tables will
+		 * need to be unregistered when they are unloaded, and slots in the
+		 * root table list should be reused when empty.
+		 */
+		if (acpi_gbl_root_table_list.tables[i].flags &
+		    ACPI_TABLE_IS_LOADED) {
+
+			/* Table is still loaded, this is an error */
+
+			return_ACPI_STATUS(AE_ALREADY_EXISTS);
+		} else {
+			*table_index = i;
+			return_ACPI_STATUS(AE_CTRL_TERMINATE);
+		}
+	}
+
+	/* Indicate no duplication to the caller */
+
+	return_ACPI_STATUS(AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_tb_verify_temp_table
  *
  * PARAMETERS:  table_desc          - Table descriptor
  *              signature           - Table signature to verify
+ *              table_index         - Where the table index is returned
  *
  * RETURN:      Status
  *
@@ -369,7 +487,8 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
  *****************************************************************************/
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index)
 {
 	acpi_status status = AE_OK;
 
@@ -392,9 +511,10 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 		goto invalidate_and_exit;
 	}
 
-	/* Verify the checksum */
-
 	if (acpi_gbl_enable_table_validation) {
+
+		/* Verify the checksum */
+
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
@@ -411,9 +531,29 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 			goto invalidate_and_exit;
 		}
+
+		/* Avoid duplications */
+
+		if (table_index) {
+			status =
+			    acpi_tb_check_duplication(table_desc, table_index);
+			if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
+				ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
+						"%4.4s 0x%8.8X%8.8X"
+						" Table is duplicated",
+						acpi_ut_valid_nameseg
+						(table_desc->signature.
+						 ascii) ? table_desc->signature.
+						ascii : "????",
+						ACPI_FORMAT_UINT64(table_desc->
+								   address)));
+
+				goto invalidate_and_exit;
+			}
+		}
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 
 invalidate_and_exit:
 	acpi_tb_invalidate_table(table_desc);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f7bc362..9404801 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -48,54 +48,6 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")
 
-/* Local prototypes */
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_compare_tables
- *
- * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
- *              table_index         - Index of table 2 to be compared
- *
- * RETURN:      TRUE if both tables are identical.
- *
- * DESCRIPTION: This function compares a table with another table that has
- *              already been installed in the root table list.
- *
- ******************************************************************************/
-
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
-{
-	acpi_status status = AE_OK;
-	u8 is_identical;
-	struct acpi_table_header *table;
-	u32 table_length;
-	u8 table_flags;
-
-	status =
-	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
-				  &table, &table_length, &table_flags);
-	if (ACPI_FAILURE(status)) {
-		return (FALSE);
-	}
-
-	/*
-	 * Check for a table match on the entire table length,
-	 * not just the header.
-	 */
-	is_identical = (u8)((table_desc->length != table_length ||
-			     memcmp(table_desc->pointer, table, table_length)) ?
-			    FALSE : TRUE);
-
-	/* Release the acquired table */
-
-	acpi_tb_release_table(table, table_length, table_flags);
-	return (is_identical);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_install_table_with_override
@@ -112,7 +64,6 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
  *              table array.
  *
  ******************************************************************************/
-
 void
 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
 				    u8 override, u32 *table_index)
@@ -210,67 +161,28 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 		goto release_and_exit;
 	}
 
-	/* Validate and verify a table before installation */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
-	if (ACPI_FAILURE(status)) {
-		goto release_and_exit;
-	}
-
 	/* Acquire the table lock */
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (acpi_gbl_enable_table_validation) {
-
-		/* Check if table is already registered */
-
-		for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
-		     ++i) {
-			/*
-			 * Check for a table match on the entire table length,
-			 * not just the header.
-			 */
-			if (!acpi_tb_compare_tables(&new_table_desc, i)) {
-				continue;
-			}
+	/* Validate and verify a table before installation */
 
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_CTRL_TERMINATE) {
 			/*
-			 * Note: the current mechanism does not unregister a table if it is
-			 * dynamically unloaded. The related namespace entries are deleted,
-			 * but the table remains in the root table list.
-			 *
-			 * The assumption here is that the number of different tables that
-			 * will be loaded is actually small, and there is minimal overhead
-			 * in just keeping the table in case it is needed again.
-			 *
-			 * If this assumption changes in the future (perhaps on large
-			 * machines with many table load/unload operations), tables will
-			 * need to be unregistered when they are unloaded, and slots in the
-			 * root table list should be reused when empty.
+			 * Table was unloaded, allow it to be reloaded.
+			 * As we are going to return AE_OK to the caller, we should
+			 * take the responsibility of freeing the input descriptor.
+			 * Refill the input descriptor to ensure
+			 * acpi_tb_install_table_with_override() can be called again to
+			 * indicate the re-installation.
 			 */
-			if (acpi_gbl_root_table_list.tables[i].flags &
-			    ACPI_TABLE_IS_LOADED) {
-
-				/* Table is still loaded, this is an error */
-
-				status = AE_ALREADY_EXISTS;
-				goto unlock_and_exit;
-			} else {
-				/*
-				 * Table was unloaded, allow it to be reloaded.
-				 * As we are going to return AE_OK to the caller, we should
-				 * take the responsibility of freeing the input descriptor.
-				 * Refill the input descriptor to ensure
-				 * acpi_tb_install_table_with_override() can be called again to
-				 * indicate the re-installation.
-				 */
-				acpi_tb_uninstall_table(&new_table_desc);
-				(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-				*table_index = i;
-				return_ACPI_STATUS(AE_OK);
-			}
+			acpi_tb_uninstall_table(&new_table_desc);
+			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+			return_ACPI_STATUS(AE_OK);
 		}
+		goto unlock_and_exit;
 	}
 
 	/* Add the table to the global root table list */
@@ -350,9 +262,11 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
 
 finish_override:
 
-	/* Validate and verify a table before overriding */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
+	/*
+	 * Validate and verify a table before overriding, no nested table
+	 * duplication check as it's too complicated and unnecessary.
+	 */
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
 	if (ACPI_FAILURE(status)) {
 		return;
 	}
-- 
2.7.4


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

* [Devel] [RFC PATCH v2 4/5] ACPICA: Tables: Combine checksum/duplication verification together
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 13438 bytes --]

They are all mechanism used to verify if a table is qualified to be
installed and controlled by acpi_gbl_enable_table_validation, so combine
them together. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/actables.h |   3 +-
 drivers/acpi/acpica/tbdata.c   | 148 +++++++++++++++++++++++++++++++++++++++--
 drivers/acpi/acpica/tbinstal.c | 124 ++++++----------------------------
 3 files changed, 165 insertions(+), 110 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 89ed31b..84a3ceb 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -76,7 +76,8 @@ void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc);
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature);
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index);
 
 u8 acpi_tb_is_table_loaded(u32 table_index);
 
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index e81355b..2dee2cd 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -50,6 +50,57 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbdata")
 
+/* Local prototypes */
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_compare_tables
+ *
+ * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
+ *              table_index         - Index of table 2 to be compared
+ *
+ * RETURN:      TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ *              already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
+{
+	acpi_status status = AE_OK;
+	u8 is_identical;
+	struct acpi_table_header *table;
+	u32 table_length;
+	u8 table_flags;
+
+	status =
+	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
+				  &table, &table_length, &table_flags);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	/*
+	 * Check for a table match on the entire table length,
+	 * not just the header.
+	 */
+	is_identical = (u8)((table_desc->length != table_length ||
+			     memcmp(table_desc->pointer, table, table_length)) ?
+			    FALSE : TRUE);
+
+	/* Release the acquired table */
+
+	acpi_tb_release_table(table, table_length, table_flags);
+	return (is_identical);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_init_table_descriptor
@@ -64,6 +115,7 @@ ACPI_MODULE_NAME("tbdata")
  * DESCRIPTION: Initialize a new table descriptor
  *
  ******************************************************************************/
+
 void
 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
 			      acpi_physical_address address,
@@ -354,12 +406,78 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 	return (acpi_tb_validate_table(table_desc));
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_check_duplication
+ *
+ * PARAMETERS:  table_desc          - Table descriptor
+ *              table_index         - Where the table index is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Avoid installing duplicated tables. However table override and
+ *              user aided dynamic table load is allowed, thus comparing the
+ *              address of the table is not sufficient, and checking the entire
+ *              table content is required.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
+{
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(tb_check_duplication);
+
+	/* Check if table is already registered */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+		/*
+		 * Check for a table match on the entire table length,
+		 * not just the header.
+		 */
+		if (!acpi_tb_compare_tables(table_desc, i)) {
+			continue;
+		}
+
+		/*
+		 * Note: the current mechanism does not unregister a table if it is
+		 * dynamically unloaded. The related namespace entries are deleted,
+		 * but the table remains in the root table list.
+		 *
+		 * The assumption here is that the number of different tables that
+		 * will be loaded is actually small, and there is minimal overhead
+		 * in just keeping the table in case it is needed again.
+		 *
+		 * If this assumption changes in the future (perhaps on large
+		 * machines with many table load/unload operations), tables will
+		 * need to be unregistered when they are unloaded, and slots in the
+		 * root table list should be reused when empty.
+		 */
+		if (acpi_gbl_root_table_list.tables[i].flags &
+		    ACPI_TABLE_IS_LOADED) {
+
+			/* Table is still loaded, this is an error */
+
+			return_ACPI_STATUS(AE_ALREADY_EXISTS);
+		} else {
+			*table_index = i;
+			return_ACPI_STATUS(AE_CTRL_TERMINATE);
+		}
+	}
+
+	/* Indicate no duplication to the caller */
+
+	return_ACPI_STATUS(AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_tb_verify_temp_table
  *
  * PARAMETERS:  table_desc          - Table descriptor
  *              signature           - Table signature to verify
+ *              table_index         - Where the table index is returned
  *
  * RETURN:      Status
  *
@@ -369,7 +487,8 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
  *****************************************************************************/
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index)
 {
 	acpi_status status = AE_OK;
 
@@ -392,9 +511,10 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 		goto invalidate_and_exit;
 	}
 
-	/* Verify the checksum */
-
 	if (acpi_gbl_enable_table_validation) {
+
+		/* Verify the checksum */
+
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
@@ -411,9 +531,29 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 			goto invalidate_and_exit;
 		}
+
+		/* Avoid duplications */
+
+		if (table_index) {
+			status =
+			    acpi_tb_check_duplication(table_desc, table_index);
+			if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
+				ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
+						"%4.4s 0x%8.8X%8.8X"
+						" Table is duplicated",
+						acpi_ut_valid_nameseg
+						(table_desc->signature.
+						 ascii) ? table_desc->signature.
+						ascii : "????",
+						ACPI_FORMAT_UINT64(table_desc->
+								   address)));
+
+				goto invalidate_and_exit;
+			}
+		}
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 
 invalidate_and_exit:
 	acpi_tb_invalidate_table(table_desc);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f7bc362..9404801 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -48,54 +48,6 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")
 
-/* Local prototypes */
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_compare_tables
- *
- * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
- *              table_index         - Index of table 2 to be compared
- *
- * RETURN:      TRUE if both tables are identical.
- *
- * DESCRIPTION: This function compares a table with another table that has
- *              already been installed in the root table list.
- *
- ******************************************************************************/
-
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
-{
-	acpi_status status = AE_OK;
-	u8 is_identical;
-	struct acpi_table_header *table;
-	u32 table_length;
-	u8 table_flags;
-
-	status =
-	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
-				  &table, &table_length, &table_flags);
-	if (ACPI_FAILURE(status)) {
-		return (FALSE);
-	}
-
-	/*
-	 * Check for a table match on the entire table length,
-	 * not just the header.
-	 */
-	is_identical = (u8)((table_desc->length != table_length ||
-			     memcmp(table_desc->pointer, table, table_length)) ?
-			    FALSE : TRUE);
-
-	/* Release the acquired table */
-
-	acpi_tb_release_table(table, table_length, table_flags);
-	return (is_identical);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_install_table_with_override
@@ -112,7 +64,6 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
  *              table array.
  *
  ******************************************************************************/
-
 void
 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
 				    u8 override, u32 *table_index)
@@ -210,67 +161,28 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 		goto release_and_exit;
 	}
 
-	/* Validate and verify a table before installation */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
-	if (ACPI_FAILURE(status)) {
-		goto release_and_exit;
-	}
-
 	/* Acquire the table lock */
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (acpi_gbl_enable_table_validation) {
-
-		/* Check if table is already registered */
-
-		for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
-		     ++i) {
-			/*
-			 * Check for a table match on the entire table length,
-			 * not just the header.
-			 */
-			if (!acpi_tb_compare_tables(&new_table_desc, i)) {
-				continue;
-			}
+	/* Validate and verify a table before installation */
 
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_CTRL_TERMINATE) {
 			/*
-			 * Note: the current mechanism does not unregister a table if it is
-			 * dynamically unloaded. The related namespace entries are deleted,
-			 * but the table remains in the root table list.
-			 *
-			 * The assumption here is that the number of different tables that
-			 * will be loaded is actually small, and there is minimal overhead
-			 * in just keeping the table in case it is needed again.
-			 *
-			 * If this assumption changes in the future (perhaps on large
-			 * machines with many table load/unload operations), tables will
-			 * need to be unregistered when they are unloaded, and slots in the
-			 * root table list should be reused when empty.
+			 * Table was unloaded, allow it to be reloaded.
+			 * As we are going to return AE_OK to the caller, we should
+			 * take the responsibility of freeing the input descriptor.
+			 * Refill the input descriptor to ensure
+			 * acpi_tb_install_table_with_override() can be called again to
+			 * indicate the re-installation.
 			 */
-			if (acpi_gbl_root_table_list.tables[i].flags &
-			    ACPI_TABLE_IS_LOADED) {
-
-				/* Table is still loaded, this is an error */
-
-				status = AE_ALREADY_EXISTS;
-				goto unlock_and_exit;
-			} else {
-				/*
-				 * Table was unloaded, allow it to be reloaded.
-				 * As we are going to return AE_OK to the caller, we should
-				 * take the responsibility of freeing the input descriptor.
-				 * Refill the input descriptor to ensure
-				 * acpi_tb_install_table_with_override() can be called again to
-				 * indicate the re-installation.
-				 */
-				acpi_tb_uninstall_table(&new_table_desc);
-				(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-				*table_index = i;
-				return_ACPI_STATUS(AE_OK);
-			}
+			acpi_tb_uninstall_table(&new_table_desc);
+			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+			return_ACPI_STATUS(AE_OK);
 		}
+		goto unlock_and_exit;
 	}
 
 	/* Add the table to the global root table list */
@@ -350,9 +262,11 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
 
 finish_override:
 
-	/* Validate and verify a table before overriding */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
+	/*
+	 * Validate and verify a table before overriding, no nested table
+	 * duplication check as it's too complicated and unnecessary.
+	 */
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
 	if (ACPI_FAILURE(status)) {
 		return;
 	}
-- 
2.7.4


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

* [RFC PATCH v2 5/5] ACPICA: Tables: Add deferred table verification support
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

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.

Reported-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbdata.c   | 31 ++++++++++++++++++++++++-------
 drivers/acpi/acpica/tbinstal.c |  1 +
 drivers/acpi/acpica/tbxface.c  | 28 +++++++++++++++++++++++-----
 drivers/acpi/bus.c             |  3 ---
 include/acpi/actbl.h           |  1 +
 5 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 2dee2cd..f58e209 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -426,12 +426,18 @@ acpi_status
 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
 {
 	u32 i;
+	u32 max_table_index;
 
 	ACPI_FUNCTION_TRACE(tb_check_duplication);
 
 	/* Check if table is already registered */
 
-	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+	if (table_index) {
+		max_table_index = *table_index;
+	} else {
+		max_table_index = acpi_gbl_root_table_list.current_table_count;
+	}
+	for (i = 0; i < max_table_index; ++i) {
 		/*
 		 * Check for a table match on the entire table length,
 		 * not just the header.
@@ -551,6 +557,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);
@@ -576,6 +584,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);
 
@@ -595,8 +605,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,
@@ -606,9 +616,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);
@@ -616,8 +633,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);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9404801..5ef0f91 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -167,6 +167,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	/* Validate and verify a table before installation */
 
+	i = acpi_gbl_root_table_list.current_table_count;
 	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_CTRL_TERMINATE) {
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index b0dc841..a6da41d 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -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,26 @@ 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)) {
+				j = i;
+				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);
 }
 
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c26342f..93c7c5b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1009,9 +1009,6 @@ void __init acpi_early_init(void)
 
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
-	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_enable_table_validation = TRUE;
-
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index d92543f..d10a172 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -380,6 +380,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)
 
 /*
-- 
2.7.4


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

* [Devel] [RFC PATCH v2 5/5] ACPICA: Tables: Add deferred table verification support
@ 2017-05-16  7:13     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-16  7:13 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 7371 bytes --]

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.

Reported-by: Hans de Goede <hdegoede(a)redhat.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbdata.c   | 31 ++++++++++++++++++++++++-------
 drivers/acpi/acpica/tbinstal.c |  1 +
 drivers/acpi/acpica/tbxface.c  | 28 +++++++++++++++++++++++-----
 drivers/acpi/bus.c             |  3 ---
 include/acpi/actbl.h           |  1 +
 5 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 2dee2cd..f58e209 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -426,12 +426,18 @@ acpi_status
 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
 {
 	u32 i;
+	u32 max_table_index;
 
 	ACPI_FUNCTION_TRACE(tb_check_duplication);
 
 	/* Check if table is already registered */
 
-	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+	if (table_index) {
+		max_table_index = *table_index;
+	} else {
+		max_table_index = acpi_gbl_root_table_list.current_table_count;
+	}
+	for (i = 0; i < max_table_index; ++i) {
 		/*
 		 * Check for a table match on the entire table length,
 		 * not just the header.
@@ -551,6 +557,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);
@@ -576,6 +584,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);
 
@@ -595,8 +605,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,
@@ -606,9 +616,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);
@@ -616,8 +633,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);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9404801..5ef0f91 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -167,6 +167,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	/* Validate and verify a table before installation */
 
+	i = acpi_gbl_root_table_list.current_table_count;
 	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_CTRL_TERMINATE) {
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index b0dc841..a6da41d 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -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,26 @@ 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)) {
+				j = i;
+				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);
 }
 
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c26342f..93c7c5b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1009,9 +1009,6 @@ void __init acpi_early_init(void)
 
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
-	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_enable_table_validation = TRUE;
-
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index d92543f..d10a172 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -380,6 +380,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)
 
 /*
-- 
2.7.4


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

* [RFC PATCH v3 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-18  9:57   ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel, Hans de Goede

On linux, we can not verify ACPI tables before installing them into the
global table list in early stage due to the number of slot limitations for
early ioremap. This leaves a problem that we cannot detect duplicated
tables in early stage, causing unwanted error messages seen when the
duplicated tables are failed to be loaded [link #1].

This patchset as ACPICA PR [link #2] adds support to verify tables in
acpi_reallocate_root_tables() which is invoked after installing tables in
early stage, being ready for late ioremap and beofre loading table in late
stage. If duplicated tables are detected, acpi_reallocate_root_tables()
stops installing them to the final reallocated global table list.

In v1 patchset [link #3], problems can be seen for dynamic loading tables
which are allocated as virtuall allocated tables. Such tables are
incremented in the global table list as the sanity check done in install
step only compares the table addresses while the virtual allocated
addresses are not stable.
In v2 patchset, we follow original design discussion made in ACPICA devel
mailing list, implements deferred table verification so that duplicate
tables are still can be detected in install step rather than in load step.
Also we removed table signature check according to verified windows
behavior [link #4] and reported issues [link #5].
In v3 patchset, one serious problem is detected around returning
AE_CTRL_TERMINATE for duplicate tables. The problem is detected by ASLTS.
Also it contains small improvements. ACPICA pull request [link #2] is
also updated.

Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
Link: https://github.com//acpica/acpica/pull/265            [#2]
Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
Link: https://github.com//acpica/acpica/pull/121            [#4]
      https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]

Lv Zheng (5):
  ACPICA: Tables: Cleanup table handler invokers
  ACPICA: Tables: Do not validate signature for dynamic table load
  ACPICA: Tables: Change table duplication check to be related to
    acpi_gbl_verify_table_checksum
  ACPICA: Tables: Combine checksum/duplication verification together
  ACPICA: Tables: Add deferred table verification support

 drivers/acpi/acpica/actables.h |   5 +-
 drivers/acpi/acpica/tbdata.c   | 228 ++++++++++++++++++++++++++++++++++++-----
 drivers/acpi/acpica/tbinstal.c | 161 ++++-------------------------
 drivers/acpi/acpica/tbxface.c  |  33 +++++-
 drivers/acpi/acpica/tbxfload.c |   2 +-
 drivers/acpi/bus.c             |   3 -
 drivers/acpi/tables.c          |   4 +-
 include/acpi/acpixf.h          |  15 +--
 include/acpi/actbl.h           |   1 +
 9 files changed, 270 insertions(+), 182 deletions(-)

-- 
2.7.4


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

* [Devel] [RFC PATCH v3 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-18  9:57   ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 2810 bytes --]

On linux, we can not verify ACPI tables before installing them into the
global table list in early stage due to the number of slot limitations for
early ioremap. This leaves a problem that we cannot detect duplicated
tables in early stage, causing unwanted error messages seen when the
duplicated tables are failed to be loaded [link #1].

This patchset as ACPICA PR [link #2] adds support to verify tables in
acpi_reallocate_root_tables() which is invoked after installing tables in
early stage, being ready for late ioremap and beofre loading table in late
stage. If duplicated tables are detected, acpi_reallocate_root_tables()
stops installing them to the final reallocated global table list.

In v1 patchset [link #3], problems can be seen for dynamic loading tables
which are allocated as virtuall allocated tables. Such tables are
incremented in the global table list as the sanity check done in install
step only compares the table addresses while the virtual allocated
addresses are not stable.
In v2 patchset, we follow original design discussion made in ACPICA devel
mailing list, implements deferred table verification so that duplicate
tables are still can be detected in install step rather than in load step.
Also we removed table signature check according to verified windows
behavior [link #4] and reported issues [link #5].
In v3 patchset, one serious problem is detected around returning
AE_CTRL_TERMINATE for duplicate tables. The problem is detected by ASLTS.
Also it contains small improvements. ACPICA pull request [link #2] is
also updated.

Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
Link: https://github.com//acpica/acpica/pull/265            [#2]
Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
Link: https://github.com//acpica/acpica/pull/121            [#4]
      https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]

Lv Zheng (5):
  ACPICA: Tables: Cleanup table handler invokers
  ACPICA: Tables: Do not validate signature for dynamic table load
  ACPICA: Tables: Change table duplication check to be related to
    acpi_gbl_verify_table_checksum
  ACPICA: Tables: Combine checksum/duplication verification together
  ACPICA: Tables: Add deferred table verification support

 drivers/acpi/acpica/actables.h |   5 +-
 drivers/acpi/acpica/tbdata.c   | 228 ++++++++++++++++++++++++++++++++++++-----
 drivers/acpi/acpica/tbinstal.c | 161 ++++-------------------------
 drivers/acpi/acpica/tbxface.c  |  33 +++++-
 drivers/acpi/acpica/tbxfload.c |   2 +-
 drivers/acpi/bus.c             |   3 -
 drivers/acpi/tables.c          |   4 +-
 include/acpi/acpixf.h          |  15 +--
 include/acpi/actbl.h           |   1 +
 9 files changed, 270 insertions(+), 182 deletions(-)

-- 
2.7.4


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

* [RFC PATCH v3 1/5] ACPICA: Tables: Cleanup table handler invokers
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

Recently, we allows the table mutex to be held in both early and late stage
APIs. This patch further cleans up the related code to reduce redundant
code related to acpi_gbl_table_handler. Lv Zheng.

Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/actables.h |  2 ++
 drivers/acpi/acpica/tbdata.c   | 43 ++++++++++++++++++++++++++++--------------
 drivers/acpi/acpica/tbinstal.c |  8 ++------
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index c8da453..89ed31b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -132,6 +132,8 @@ acpi_tb_install_and_load_table(acpi_physical_address address,
 
 acpi_status acpi_tb_unload_table(u32 table_index);
 
+void acpi_tb_notify_table(u32 event, void *table);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 27c5c27..42ea044 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -818,13 +818,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
 		acpi_ev_update_gpes(owner_id);
 	}
 
-	/* Invoke table handler if present */
-
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
-					     acpi_gbl_table_handler_context);
-	}
+	/* Invoke table handler */
 
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
 	return_ACPI_STATUS(status);
 }
 
@@ -892,15 +888,11 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
-	if (acpi_gbl_table_handler) {
-		status = acpi_get_table_by_index(table_index, &table);
-		if (ACPI_SUCCESS(status)) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     table,
-						     acpi_gbl_table_handler_context);
-		}
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
 	}
 
 	/* Delete the portion of the namespace owned by this table */
@@ -914,3 +906,26 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 	return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_notify_table
+ *
+ * PARAMETERS:  event               - Table event
+ *              table               - Validated table pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Notify a table event to the users.
+ *
+ ******************************************************************************/
+
+void acpi_tb_notify_table(u32 event, void *table)
+{
+	/* Invoke table handler if present */
+
+	if (acpi_gbl_table_handler) {
+		(void)acpi_gbl_table_handler(event, table,
+					     acpi_gbl_table_handler_context);
+	}
+}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 4620f3c..ee74515 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -306,14 +306,10 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	acpi_tb_install_table_with_override(&new_table_desc, override,
 					    table_index);
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_INSTALL,
-					     new_table_desc.pointer,
-					     acpi_gbl_table_handler_context);
-	}
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 unlock_and_exit:
-- 
2.7.4


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

* [Devel] [RFC PATCH v3 1/5] ACPICA: Tables: Cleanup table handler invokers
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3965 bytes --]

Recently, we allows the table mutex to be held in both early and late stage
APIs. This patch further cleans up the related code to reduce redundant
code related to acpi_gbl_table_handler. Lv Zheng.

Tested-by: Hans de Goede <hdegoede(a)redhat.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/actables.h |  2 ++
 drivers/acpi/acpica/tbdata.c   | 43 ++++++++++++++++++++++++++++--------------
 drivers/acpi/acpica/tbinstal.c |  8 ++------
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index c8da453..89ed31b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -132,6 +132,8 @@ acpi_tb_install_and_load_table(acpi_physical_address address,
 
 acpi_status acpi_tb_unload_table(u32 table_index);
 
+void acpi_tb_notify_table(u32 event, void *table);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 27c5c27..42ea044 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -818,13 +818,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
 		acpi_ev_update_gpes(owner_id);
 	}
 
-	/* Invoke table handler if present */
-
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
-					     acpi_gbl_table_handler_context);
-	}
+	/* Invoke table handler */
 
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
 	return_ACPI_STATUS(status);
 }
 
@@ -892,15 +888,11 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
-	if (acpi_gbl_table_handler) {
-		status = acpi_get_table_by_index(table_index, &table);
-		if (ACPI_SUCCESS(status)) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     table,
-						     acpi_gbl_table_handler_context);
-		}
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
 	}
 
 	/* Delete the portion of the namespace owned by this table */
@@ -914,3 +906,26 @@ acpi_status acpi_tb_unload_table(u32 table_index)
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 	return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_notify_table
+ *
+ * PARAMETERS:  event               - Table event
+ *              table               - Validated table pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Notify a table event to the users.
+ *
+ ******************************************************************************/
+
+void acpi_tb_notify_table(u32 event, void *table)
+{
+	/* Invoke table handler if present */
+
+	if (acpi_gbl_table_handler) {
+		(void)acpi_gbl_table_handler(event, table,
+					     acpi_gbl_table_handler_context);
+	}
+}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 4620f3c..ee74515 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -306,14 +306,10 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	acpi_tb_install_table_with_override(&new_table_desc, override,
 					    table_index);
 
-	/* Invoke table handler if present */
+	/* Invoke table handler */
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-	if (acpi_gbl_table_handler) {
-		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_INSTALL,
-					     new_table_desc.pointer,
-					     acpi_gbl_table_handler_context);
-	}
+	acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 unlock_and_exit:
-- 
2.7.4


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

* [RFC PATCH v3 2/5] ACPICA: Tables: Do not validate signature for dynamic table load
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

Windows seems to allow arbitrary table signatures for Load/load_table
opcodes:
  ACPI BIOS Error (bug): Table has invalid signature [PRAD] (0x44415250)
So this patch removes dynamic load signature checks. However we need to
find a way to avoid table loading against tables like MADT. This is not
covered by this commit.

This Windows behavior has been validated on link #1. An end user bug
report can also be found on link #2.

This patch also includes simple cleanup for static load signature check
code. Reported by Ye Xiaolong, Fixed by Lv Zheng.

Link: https://github.com/acpica/acpica/pull/121 [#1]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=118601 [#2]
Reported-by: Ye Xiaolong <xiaolong.ye@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbinstal.c | 28 ----------------------------
 drivers/acpi/acpica/tbxfload.c |  2 +-
 2 files changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index ee74515..9d21296 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -222,34 +222,6 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 	if (reload) {
-		/*
-		 * Validate the incoming table signature.
-		 *
-		 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
-		 * 2) We added support for OEMx tables, signature "OEM".
-		 * 3) Valid tables were encountered with a null signature, so we just
-		 *    gave up on validating the signature, (05/2008).
-		 * 4) We encountered non-AML tables such as the MADT, which caused
-		 *    interpreter errors and kernel faults. So now, we once again allow
-		 *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
-		 */
-		if ((new_table_desc.signature.ascii[0] != 0x00) &&
-		    (!ACPI_COMPARE_NAME
-		     (&new_table_desc.signature, ACPI_SIG_SSDT))
-		    && (strncmp(new_table_desc.signature.ascii, "OEM", 3))) {
-			ACPI_BIOS_ERROR((AE_INFO,
-					 "Table has invalid signature [%4.4s] (0x%8.8X), "
-					 "must be SSDT or OEMx",
-					 acpi_ut_valid_nameseg(new_table_desc.
-							       signature.
-							       ascii) ?
-					 new_table_desc.signature.
-					 ascii : "????",
-					 new_table_desc.signature.integer));
-
-			status = AE_BAD_SIGNATURE;
-			goto unlock_and_exit;
-		}
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index b71ce3b..d81f442 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -206,7 +206,7 @@ acpi_status acpi_tb_load_namespace(void)
 	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
 		table = &acpi_gbl_root_table_list.tables[i];
 
-		if (!acpi_gbl_root_table_list.tables[i].address ||
+		if (!table->address ||
 		    (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
 		     && !ACPI_COMPARE_NAME(table->signature.ascii,
 					   ACPI_SIG_PSDT)
-- 
2.7.4


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

* [Devel] [RFC PATCH v3 2/5] ACPICA: Tables: Do not validate signature for dynamic table load
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3100 bytes --]

Windows seems to allow arbitrary table signatures for Load/load_table
opcodes:
  ACPI BIOS Error (bug): Table has invalid signature [PRAD] (0x44415250)
So this patch removes dynamic load signature checks. However we need to
find a way to avoid table loading against tables like MADT. This is not
covered by this commit.

This Windows behavior has been validated on link #1. An end user bug
report can also be found on link #2.

This patch also includes simple cleanup for static load signature check
code. Reported by Ye Xiaolong, Fixed by Lv Zheng.

Link: https://github.com/acpica/acpica/pull/121 [#1]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=118601 [#2]
Reported-by: Ye Xiaolong <xiaolong.ye(a)intel.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbinstal.c | 28 ----------------------------
 drivers/acpi/acpica/tbxfload.c |  2 +-
 2 files changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index ee74515..9d21296 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -222,34 +222,6 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
 	if (reload) {
-		/*
-		 * Validate the incoming table signature.
-		 *
-		 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
-		 * 2) We added support for OEMx tables, signature "OEM".
-		 * 3) Valid tables were encountered with a null signature, so we just
-		 *    gave up on validating the signature, (05/2008).
-		 * 4) We encountered non-AML tables such as the MADT, which caused
-		 *    interpreter errors and kernel faults. So now, we once again allow
-		 *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
-		 */
-		if ((new_table_desc.signature.ascii[0] != 0x00) &&
-		    (!ACPI_COMPARE_NAME
-		     (&new_table_desc.signature, ACPI_SIG_SSDT))
-		    && (strncmp(new_table_desc.signature.ascii, "OEM", 3))) {
-			ACPI_BIOS_ERROR((AE_INFO,
-					 "Table has invalid signature [%4.4s] (0x%8.8X), "
-					 "must be SSDT or OEMx",
-					 acpi_ut_valid_nameseg(new_table_desc.
-							       signature.
-							       ascii) ?
-					 new_table_desc.signature.
-					 ascii : "????",
-					 new_table_desc.signature.integer));
-
-			status = AE_BAD_SIGNATURE;
-			goto unlock_and_exit;
-		}
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index b71ce3b..d81f442 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -206,7 +206,7 @@ acpi_status acpi_tb_load_namespace(void)
 	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
 		table = &acpi_gbl_root_table_list.tables[i];
 
-		if (!acpi_gbl_root_table_list.tables[i].address ||
+		if (!table->address ||
 		    (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
 		     && !ACPI_COMPARE_NAME(table->signature.ascii,
 					   ACPI_SIG_PSDT)
-- 
2.7.4


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

* [RFC PATCH v3 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

acpi_gbl_verify_table_checksum is used to avoid validating (mapping) an entire
table in OS boot stage. 2nd "Reload" check in acpi_tb_install_standard_table()
is prepared for the same purpose. So this patch combines them together
using a renamed acpi_gbl_enable_table_validation flag. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbdata.c   |  4 ++--
 drivers/acpi/acpica/tbinstal.c |  2 +-
 drivers/acpi/acpica/tbxface.c  |  8 ++++++++
 drivers/acpi/bus.c             |  3 ---
 drivers/acpi/tables.c          |  4 ++--
 include/acpi/acpixf.h          | 15 ++++++++-------
 6 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 42ea044..e81355b 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -338,7 +338,7 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 {
 
-	if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) {
+	if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
 		/*
 		 * Only validates the header of the table.
 		 * Note that Length contains the size of the mapping after invoking
@@ -394,7 +394,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 	/* Verify the checksum */
 
-	if (acpi_gbl_verify_table_checksum) {
+	if (acpi_gbl_enable_table_validation) {
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9d21296..f7bc362 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -221,7 +221,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (reload) {
+	if (acpi_gbl_enable_table_validation) {
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 010b1c43..b0dc841 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -194,6 +194,14 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 		}
 	}
 
+	if (!acpi_gbl_enable_table_validation) {
+		/*
+		 * Now it's safe to do full table validation. We can do deferred
+		 * table initilization here once the flag is set.
+		 */
+		acpi_gbl_enable_table_validation = TRUE;
+	}
+
 	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
 	status = acpi_tb_resize_root_table_list();
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 34fbe02..93c7c5b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1009,9 +1009,6 @@ void __init acpi_early_init(void)
 
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
-	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_verify_table_checksum = TRUE;
-
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 0dae722..b5cc09c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -740,10 +740,10 @@ int __init acpi_table_init(void)
 
 	if (acpi_verify_table_checksum) {
 		pr_info("Early table checksum verification enabled\n");
-		acpi_gbl_verify_table_checksum = TRUE;
+		acpi_gbl_enable_table_validation = TRUE;
 	} else {
 		pr_info("Early table checksum verification disabled\n");
-		acpi_gbl_verify_table_checksum = FALSE;
+		acpi_gbl_enable_table_validation = FALSE;
 	}
 
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 15c86ce..88a1de8 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -160,13 +160,14 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
 
 /*
- * Whether or not to verify the table checksum before installation. Set
- * this to TRUE to verify the table checksum before install it to the table
- * manager. Note that enabling this option causes errors to happen in some
- * OSPMs during early initialization stages. Default behavior is to do such
- * verification.
- */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE);
+ * Whether or not to validate (map) an entire table to verify
+ * checksum/duplication in early stage before install. Set this to TRUE to
+ * allow early table validation before install it to the table manager.
+ * Note that enabling this option causes errors to happen in some OSPMs
+ * during early initialization stages. Default behavior is to allow such
+ * validation.
+ */
+ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE);
 
 /*
  * Optionally enable output from the AML Debug Object.
-- 
2.7.4


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

* [Devel] [RFC PATCH v3 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 5040 bytes --]

acpi_gbl_verify_table_checksum is used to avoid validating (mapping) an entire
table in OS boot stage. 2nd "Reload" check in acpi_tb_install_standard_table()
is prepared for the same purpose. So this patch combines them together
using a renamed acpi_gbl_enable_table_validation flag. Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbdata.c   |  4 ++--
 drivers/acpi/acpica/tbinstal.c |  2 +-
 drivers/acpi/acpica/tbxface.c  |  8 ++++++++
 drivers/acpi/bus.c             |  3 ---
 drivers/acpi/tables.c          |  4 ++--
 include/acpi/acpixf.h          | 15 ++++++++-------
 6 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 42ea044..e81355b 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -338,7 +338,7 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 {
 
-	if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) {
+	if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
 		/*
 		 * Only validates the header of the table.
 		 * Note that Length contains the size of the mapping after invoking
@@ -394,7 +394,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 	/* Verify the checksum */
 
-	if (acpi_gbl_verify_table_checksum) {
+	if (acpi_gbl_enable_table_validation) {
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 9d21296..f7bc362 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -221,7 +221,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (reload) {
+	if (acpi_gbl_enable_table_validation) {
 
 		/* Check if table is already registered */
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 010b1c43..b0dc841 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -194,6 +194,14 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 		}
 	}
 
+	if (!acpi_gbl_enable_table_validation) {
+		/*
+		 * Now it's safe to do full table validation. We can do deferred
+		 * table initilization here once the flag is set.
+		 */
+		acpi_gbl_enable_table_validation = TRUE;
+	}
+
 	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
 	status = acpi_tb_resize_root_table_list();
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 34fbe02..93c7c5b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1009,9 +1009,6 @@ void __init acpi_early_init(void)
 
 	printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
 
-	/* It's safe to verify table checksums during late stage */
-	acpi_gbl_verify_table_checksum = TRUE;
-
 	/* enable workarounds, unless strict ACPI spec. compliance */
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 0dae722..b5cc09c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -740,10 +740,10 @@ int __init acpi_table_init(void)
 
 	if (acpi_verify_table_checksum) {
 		pr_info("Early table checksum verification enabled\n");
-		acpi_gbl_verify_table_checksum = TRUE;
+		acpi_gbl_enable_table_validation = TRUE;
 	} else {
 		pr_info("Early table checksum verification disabled\n");
-		acpi_gbl_verify_table_checksum = FALSE;
+		acpi_gbl_enable_table_validation = FALSE;
 	}
 
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 15c86ce..88a1de8 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -160,13 +160,14 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
 
 /*
- * Whether or not to verify the table checksum before installation. Set
- * this to TRUE to verify the table checksum before install it to the table
- * manager. Note that enabling this option causes errors to happen in some
- * OSPMs during early initialization stages. Default behavior is to do such
- * verification.
- */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE);
+ * Whether or not to validate (map) an entire table to verify
+ * checksum/duplication in early stage before install. Set this to TRUE to
+ * allow early table validation before install it to the table manager.
+ * Note that enabling this option causes errors to happen in some OSPMs
+ * during early initialization stages. Default behavior is to allow such
+ * validation.
+ */
+ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE);
 
 /*
  * Optionally enable output from the AML Debug Object.
-- 
2.7.4


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

* [RFC PATCH v3 4/5] ACPICA: Tables: Combine checksum/duplication verification together
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

They are all mechanisms used to verify if a table is qualified to be
installed and controlled by acpi_gbl_enable_table_validation, so combine them
together. By doing so, table duplication check is applied to the statically
loaded tables (however whether it is actually enabled is still determined
by acpi_gbl_enable_table_validation). Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/actables.h |   3 +-
 drivers/acpi/acpica/tbdata.c   | 151 +++++++++++++++++++++++++++++++++++++++--
 drivers/acpi/acpica/tbinstal.c | 125 ++++++----------------------------
 3 files changed, 169 insertions(+), 110 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 89ed31b..84a3ceb 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -76,7 +76,8 @@ void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc);
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature);
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index);
 
 u8 acpi_tb_is_table_loaded(u32 table_index);
 
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index e81355b..659d362 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -50,6 +50,57 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbdata")
 
+/* Local prototypes */
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_compare_tables
+ *
+ * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
+ *              table_index         - Index of table 2 to be compared
+ *
+ * RETURN:      TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ *              already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
+{
+	acpi_status status = AE_OK;
+	u8 is_identical;
+	struct acpi_table_header *table;
+	u32 table_length;
+	u8 table_flags;
+
+	status =
+	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
+				  &table, &table_length, &table_flags);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	/*
+	 * Check for a table match on the entire table length,
+	 * not just the header.
+	 */
+	is_identical = (u8)((table_desc->length != table_length ||
+			     memcmp(table_desc->pointer, table, table_length)) ?
+			    FALSE : TRUE);
+
+	/* Release the acquired table */
+
+	acpi_tb_release_table(table, table_length, table_flags);
+	return (is_identical);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_init_table_descriptor
@@ -64,6 +115,7 @@ ACPI_MODULE_NAME("tbdata")
  * DESCRIPTION: Initialize a new table descriptor
  *
  ******************************************************************************/
+
 void
 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
 			      acpi_physical_address address,
@@ -354,12 +406,78 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 	return (acpi_tb_validate_table(table_desc));
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_check_duplication
+ *
+ * PARAMETERS:  table_desc          - Table descriptor
+ *              table_index         - Where the table index is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Avoid installing duplicated tables. However table override and
+ *              user aided dynamic table load is allowed, thus comparing the
+ *              address of the table is not sufficient, and checking the entire
+ *              table content is required.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
+{
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(tb_check_duplication);
+
+	/* Check if table is already registered */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+		/*
+		 * Check for a table match on the entire table length,
+		 * not just the header.
+		 */
+		if (!acpi_tb_compare_tables(table_desc, i)) {
+			continue;
+		}
+
+		/*
+		 * Note: the current mechanism does not unregister a table if it is
+		 * dynamically unloaded. The related namespace entries are deleted,
+		 * but the table remains in the root table list.
+		 *
+		 * The assumption here is that the number of different tables that
+		 * will be loaded is actually small, and there is minimal overhead
+		 * in just keeping the table in case it is needed again.
+		 *
+		 * If this assumption changes in the future (perhaps on large
+		 * machines with many table load/unload operations), tables will
+		 * need to be unregistered when they are unloaded, and slots in the
+		 * root table list should be reused when empty.
+		 */
+		if (acpi_gbl_root_table_list.tables[i].flags &
+		    ACPI_TABLE_IS_LOADED) {
+
+			/* Table is still loaded, this is an error */
+
+			return_ACPI_STATUS(AE_ALREADY_EXISTS);
+		} else {
+			*table_index = i;
+			return_ACPI_STATUS(AE_CTRL_TERMINATE);
+		}
+	}
+
+	/* Indicate no duplication to the caller */
+
+	return_ACPI_STATUS(AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_tb_verify_temp_table
  *
  * PARAMETERS:  table_desc          - Table descriptor
  *              signature           - Table signature to verify
+ *              table_index         - Where the table index is returned
  *
  * RETURN:      Status
  *
@@ -369,7 +487,8 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
  *****************************************************************************/
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index)
 {
 	acpi_status status = AE_OK;
 
@@ -392,9 +511,10 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 		goto invalidate_and_exit;
 	}
 
-	/* Verify the checksum */
-
 	if (acpi_gbl_enable_table_validation) {
+
+		/* Verify the checksum */
+
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
@@ -411,9 +531,32 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 			goto invalidate_and_exit;
 		}
+
+		/* Avoid duplications */
+
+		if (table_index) {
+			status =
+			    acpi_tb_check_duplication(table_desc, table_index);
+			if (ACPI_FAILURE(status)) {
+				if (status != AE_CTRL_TERMINATE) {
+					ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
+							"%4.4s 0x%8.8X%8.8X"
+							" Table is duplicated",
+							acpi_ut_valid_nameseg
+							(table_desc->signature.
+							 ascii) ? table_desc->
+							signature.
+							ascii : "????",
+							ACPI_FORMAT_UINT64
+							(table_desc->address)));
+				}
+
+				goto invalidate_and_exit;
+			}
+		}
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 
 invalidate_and_exit:
 	acpi_tb_invalidate_table(table_desc);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f7bc362..0dfc0ac 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -48,54 +48,6 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")
 
-/* Local prototypes */
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_compare_tables
- *
- * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
- *              table_index         - Index of table 2 to be compared
- *
- * RETURN:      TRUE if both tables are identical.
- *
- * DESCRIPTION: This function compares a table with another table that has
- *              already been installed in the root table list.
- *
- ******************************************************************************/
-
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
-{
-	acpi_status status = AE_OK;
-	u8 is_identical;
-	struct acpi_table_header *table;
-	u32 table_length;
-	u8 table_flags;
-
-	status =
-	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
-				  &table, &table_length, &table_flags);
-	if (ACPI_FAILURE(status)) {
-		return (FALSE);
-	}
-
-	/*
-	 * Check for a table match on the entire table length,
-	 * not just the header.
-	 */
-	is_identical = (u8)((table_desc->length != table_length ||
-			     memcmp(table_desc->pointer, table, table_length)) ?
-			    FALSE : TRUE);
-
-	/* Release the acquired table */
-
-	acpi_tb_release_table(table, table_length, table_flags);
-	return (is_identical);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_install_table_with_override
@@ -112,7 +64,6 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
  *              table array.
  *
  ******************************************************************************/
-
 void
 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
 				    u8 override, u32 *table_index)
@@ -210,67 +161,29 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 		goto release_and_exit;
 	}
 
-	/* Validate and verify a table before installation */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
-	if (ACPI_FAILURE(status)) {
-		goto release_and_exit;
-	}
-
 	/* Acquire the table lock */
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (acpi_gbl_enable_table_validation) {
-
-		/* Check if table is already registered */
-
-		for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
-		     ++i) {
-			/*
-			 * Check for a table match on the entire table length,
-			 * not just the header.
-			 */
-			if (!acpi_tb_compare_tables(&new_table_desc, i)) {
-				continue;
-			}
+	/* Validate and verify a table before installation */
 
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_CTRL_TERMINATE) {
 			/*
-			 * Note: the current mechanism does not unregister a table if it is
-			 * dynamically unloaded. The related namespace entries are deleted,
-			 * but the table remains in the root table list.
-			 *
-			 * The assumption here is that the number of different tables that
-			 * will be loaded is actually small, and there is minimal overhead
-			 * in just keeping the table in case it is needed again.
-			 *
-			 * If this assumption changes in the future (perhaps on large
-			 * machines with many table load/unload operations), tables will
-			 * need to be unregistered when they are unloaded, and slots in the
-			 * root table list should be reused when empty.
+			 * Table was unloaded, allow it to be reloaded.
+			 * As we are going to return AE_OK to the caller, we should
+			 * take the responsibility of freeing the input descriptor.
+			 * Refill the input descriptor to ensure
+			 * acpi_tb_install_table_with_override() can be called again to
+			 * indicate the re-installation.
 			 */
-			if (acpi_gbl_root_table_list.tables[i].flags &
-			    ACPI_TABLE_IS_LOADED) {
-
-				/* Table is still loaded, this is an error */
-
-				status = AE_ALREADY_EXISTS;
-				goto unlock_and_exit;
-			} else {
-				/*
-				 * Table was unloaded, allow it to be reloaded.
-				 * As we are going to return AE_OK to the caller, we should
-				 * take the responsibility of freeing the input descriptor.
-				 * Refill the input descriptor to ensure
-				 * acpi_tb_install_table_with_override() can be called again to
-				 * indicate the re-installation.
-				 */
-				acpi_tb_uninstall_table(&new_table_desc);
-				(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-				*table_index = i;
-				return_ACPI_STATUS(AE_OK);
-			}
+			acpi_tb_uninstall_table(&new_table_desc);
+			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+			*table_index = i;
+			return_ACPI_STATUS(AE_OK);
 		}
+		goto unlock_and_exit;
 	}
 
 	/* Add the table to the global root table list */
@@ -350,9 +263,11 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
 
 finish_override:
 
-	/* Validate and verify a table before overriding */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
+	/*
+	 * Validate and verify a table before overriding, no nested table
+	 * duplication check as it's too complicated and unnecessary.
+	 */
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
 	if (ACPI_FAILURE(status)) {
 		return;
 	}
-- 
2.7.4


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

* [Devel] [RFC PATCH v3 4/5] ACPICA: Tables: Combine checksum/duplication verification together
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 13681 bytes --]

They are all mechanisms used to verify if a table is qualified to be
installed and controlled by acpi_gbl_enable_table_validation, so combine them
together. By doing so, table duplication check is applied to the statically
loaded tables (however whether it is actually enabled is still determined
by acpi_gbl_enable_table_validation). Lv Zheng.

Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/actables.h |   3 +-
 drivers/acpi/acpica/tbdata.c   | 151 +++++++++++++++++++++++++++++++++++++++--
 drivers/acpi/acpica/tbinstal.c | 125 ++++++----------------------------
 3 files changed, 169 insertions(+), 110 deletions(-)

diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 89ed31b..84a3ceb 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -76,7 +76,8 @@ void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc);
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature);
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index);
 
 u8 acpi_tb_is_table_loaded(u32 table_index);
 
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index e81355b..659d362 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -50,6 +50,57 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbdata")
 
+/* Local prototypes */
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_compare_tables
+ *
+ * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
+ *              table_index         - Index of table 2 to be compared
+ *
+ * RETURN:      TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ *              already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
+{
+	acpi_status status = AE_OK;
+	u8 is_identical;
+	struct acpi_table_header *table;
+	u32 table_length;
+	u8 table_flags;
+
+	status =
+	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
+				  &table, &table_length, &table_flags);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	/*
+	 * Check for a table match on the entire table length,
+	 * not just the header.
+	 */
+	is_identical = (u8)((table_desc->length != table_length ||
+			     memcmp(table_desc->pointer, table, table_length)) ?
+			    FALSE : TRUE);
+
+	/* Release the acquired table */
+
+	acpi_tb_release_table(table, table_length, table_flags);
+	return (is_identical);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_init_table_descriptor
@@ -64,6 +115,7 @@ ACPI_MODULE_NAME("tbdata")
  * DESCRIPTION: Initialize a new table descriptor
  *
  ******************************************************************************/
+
 void
 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
 			      acpi_physical_address address,
@@ -354,12 +406,78 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
 	return (acpi_tb_validate_table(table_desc));
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_check_duplication
+ *
+ * PARAMETERS:  table_desc          - Table descriptor
+ *              table_index         - Where the table index is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Avoid installing duplicated tables. However table override and
+ *              user aided dynamic table load is allowed, thus comparing the
+ *              address of the table is not sufficient, and checking the entire
+ *              table content is required.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
+{
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(tb_check_duplication);
+
+	/* Check if table is already registered */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+		/*
+		 * Check for a table match on the entire table length,
+		 * not just the header.
+		 */
+		if (!acpi_tb_compare_tables(table_desc, i)) {
+			continue;
+		}
+
+		/*
+		 * Note: the current mechanism does not unregister a table if it is
+		 * dynamically unloaded. The related namespace entries are deleted,
+		 * but the table remains in the root table list.
+		 *
+		 * The assumption here is that the number of different tables that
+		 * will be loaded is actually small, and there is minimal overhead
+		 * in just keeping the table in case it is needed again.
+		 *
+		 * If this assumption changes in the future (perhaps on large
+		 * machines with many table load/unload operations), tables will
+		 * need to be unregistered when they are unloaded, and slots in the
+		 * root table list should be reused when empty.
+		 */
+		if (acpi_gbl_root_table_list.tables[i].flags &
+		    ACPI_TABLE_IS_LOADED) {
+
+			/* Table is still loaded, this is an error */
+
+			return_ACPI_STATUS(AE_ALREADY_EXISTS);
+		} else {
+			*table_index = i;
+			return_ACPI_STATUS(AE_CTRL_TERMINATE);
+		}
+	}
+
+	/* Indicate no duplication to the caller */
+
+	return_ACPI_STATUS(AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_tb_verify_temp_table
  *
  * PARAMETERS:  table_desc          - Table descriptor
  *              signature           - Table signature to verify
+ *              table_index         - Where the table index is returned
  *
  * RETURN:      Status
  *
@@ -369,7 +487,8 @@ acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
  *****************************************************************************/
 
 acpi_status
-acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
+acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
+			  char *signature, u32 *table_index)
 {
 	acpi_status status = AE_OK;
 
@@ -392,9 +511,10 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 		goto invalidate_and_exit;
 	}
 
-	/* Verify the checksum */
-
 	if (acpi_gbl_enable_table_validation) {
+
+		/* Verify the checksum */
+
 		status =
 		    acpi_tb_verify_checksum(table_desc->pointer,
 					    table_desc->length);
@@ -411,9 +531,32 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature)
 
 			goto invalidate_and_exit;
 		}
+
+		/* Avoid duplications */
+
+		if (table_index) {
+			status =
+			    acpi_tb_check_duplication(table_desc, table_index);
+			if (ACPI_FAILURE(status)) {
+				if (status != AE_CTRL_TERMINATE) {
+					ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
+							"%4.4s 0x%8.8X%8.8X"
+							" Table is duplicated",
+							acpi_ut_valid_nameseg
+							(table_desc->signature.
+							 ascii) ? table_desc->
+							signature.
+							ascii : "????",
+							ACPI_FORMAT_UINT64
+							(table_desc->address)));
+				}
+
+				goto invalidate_and_exit;
+			}
+		}
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 
 invalidate_and_exit:
 	acpi_tb_invalidate_table(table_desc);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f7bc362..0dfc0ac 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -48,54 +48,6 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")
 
-/* Local prototypes */
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_compare_tables
- *
- * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
- *              table_index         - Index of table 2 to be compared
- *
- * RETURN:      TRUE if both tables are identical.
- *
- * DESCRIPTION: This function compares a table with another table that has
- *              already been installed in the root table list.
- *
- ******************************************************************************/
-
-static u8
-acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
-{
-	acpi_status status = AE_OK;
-	u8 is_identical;
-	struct acpi_table_header *table;
-	u32 table_length;
-	u8 table_flags;
-
-	status =
-	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
-				  &table, &table_length, &table_flags);
-	if (ACPI_FAILURE(status)) {
-		return (FALSE);
-	}
-
-	/*
-	 * Check for a table match on the entire table length,
-	 * not just the header.
-	 */
-	is_identical = (u8)((table_desc->length != table_length ||
-			     memcmp(table_desc->pointer, table, table_length)) ?
-			    FALSE : TRUE);
-
-	/* Release the acquired table */
-
-	acpi_tb_release_table(table, table_length, table_flags);
-	return (is_identical);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_install_table_with_override
@@ -112,7 +64,6 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
  *              table array.
  *
  ******************************************************************************/
-
 void
 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
 				    u8 override, u32 *table_index)
@@ -210,67 +161,29 @@ acpi_tb_install_standard_table(acpi_physical_address address,
 		goto release_and_exit;
 	}
 
-	/* Validate and verify a table before installation */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
-	if (ACPI_FAILURE(status)) {
-		goto release_and_exit;
-	}
-
 	/* Acquire the table lock */
 
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (acpi_gbl_enable_table_validation) {
-
-		/* Check if table is already registered */
-
-		for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
-		     ++i) {
-			/*
-			 * Check for a table match on the entire table length,
-			 * not just the header.
-			 */
-			if (!acpi_tb_compare_tables(&new_table_desc, i)) {
-				continue;
-			}
+	/* Validate and verify a table before installation */
 
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_CTRL_TERMINATE) {
 			/*
-			 * Note: the current mechanism does not unregister a table if it is
-			 * dynamically unloaded. The related namespace entries are deleted,
-			 * but the table remains in the root table list.
-			 *
-			 * The assumption here is that the number of different tables that
-			 * will be loaded is actually small, and there is minimal overhead
-			 * in just keeping the table in case it is needed again.
-			 *
-			 * If this assumption changes in the future (perhaps on large
-			 * machines with many table load/unload operations), tables will
-			 * need to be unregistered when they are unloaded, and slots in the
-			 * root table list should be reused when empty.
+			 * Table was unloaded, allow it to be reloaded.
+			 * As we are going to return AE_OK to the caller, we should
+			 * take the responsibility of freeing the input descriptor.
+			 * Refill the input descriptor to ensure
+			 * acpi_tb_install_table_with_override() can be called again to
+			 * indicate the re-installation.
 			 */
-			if (acpi_gbl_root_table_list.tables[i].flags &
-			    ACPI_TABLE_IS_LOADED) {
-
-				/* Table is still loaded, this is an error */
-
-				status = AE_ALREADY_EXISTS;
-				goto unlock_and_exit;
-			} else {
-				/*
-				 * Table was unloaded, allow it to be reloaded.
-				 * As we are going to return AE_OK to the caller, we should
-				 * take the responsibility of freeing the input descriptor.
-				 * Refill the input descriptor to ensure
-				 * acpi_tb_install_table_with_override() can be called again to
-				 * indicate the re-installation.
-				 */
-				acpi_tb_uninstall_table(&new_table_desc);
-				(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-				*table_index = i;
-				return_ACPI_STATUS(AE_OK);
-			}
+			acpi_tb_uninstall_table(&new_table_desc);
+			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+			*table_index = i;
+			return_ACPI_STATUS(AE_OK);
 		}
+		goto unlock_and_exit;
 	}
 
 	/* Add the table to the global root table list */
@@ -350,9 +263,11 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
 
 finish_override:
 
-	/* Validate and verify a table before overriding */
-
-	status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
+	/*
+	 * Validate and verify a table before overriding, no nested table
+	 * duplication check as it's too complicated and unnecessary.
+	 */
+	status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
 	if (ACPI_FAILURE(status)) {
 		return;
 	}
-- 
2.7.4


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

* [RFC PATCH v3 5/5] ACPICA: Tables: Add deferred table verification support
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Lv Zheng, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

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.

Reported-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/acpica/tbdata.c  | 32 ++++++++++++++++++++++++++------
 drivers/acpi/acpica/tbxface.c | 25 +++++++++++++++++++++----
 include/acpi/actbl.h          |  1 +
 3 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 659d362..abe1052 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.
@@ -554,6 +563,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 +590,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 +611,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 +622,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 +639,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);
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index b0dc841..70cd581 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -167,6 +167,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
 acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 {
 	acpi_status status;
+	struct acpi_table_desc *table_desc;
 	u32 i;
 
 	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,
+							      NULL);
+				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);
 }
 
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index d92543f..d10a172 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -380,6 +380,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)
 
 /*
-- 
2.7.4


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

* [Devel] [RFC PATCH v3 5/5] ACPICA: Tables: Add deferred table verification support
@ 2017-05-18  9:57     ` Lv Zheng
  0 siblings, 0 replies; 51+ messages in thread
From: Lv Zheng @ 2017-05-18  9:57 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 6112 bytes --]

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.

Reported-by: Hans de Goede <hdegoede(a)redhat.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
---
 drivers/acpi/acpica/tbdata.c  | 32 ++++++++++++++++++++++++++------
 drivers/acpi/acpica/tbxface.c | 25 +++++++++++++++++++++----
 include/acpi/actbl.h          |  1 +
 3 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 659d362..abe1052 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.
@@ -554,6 +563,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 +590,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 +611,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 +622,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 +639,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);
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index b0dc841..70cd581 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -167,6 +167,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
 acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 {
 	acpi_status status;
+	struct acpi_table_desc *table_desc;
 	u32 i;
 
 	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,
+							      NULL);
+				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);
 }
 
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index d92543f..d10a172 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -380,6 +380,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)
 
 /*
-- 
2.7.4


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

* Re: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
  2017-05-16  7:13   ` [Devel] " Lv Zheng
                     ` (5 preceding siblings ...)
  (?)
@ 2017-05-18 14:01   ` Hans de Goede
  2017-05-19  7:59       ` [Devel] " Zheng, Lv
  -1 siblings, 1 reply; 51+ messages in thread
From: Hans de Goede @ 2017-05-18 14:01 UTC (permalink / raw)
  To: Lv Zheng, Rafael J . Wysocki, Len Brown, Robert Moore, David E . Box
  Cc: Lv Zheng, linux-acpi, devel

Hi,

On 16-05-17 09:13, Lv Zheng wrote:
> On linux, we can not verify ACPI tables before installing them into the
> global table list in early stage due to the number of slot limitations for
> early ioremap. This leaves a problem that we cannot detect duplicated
> tables in early stage, causing unwanted error messages seen when the
> duplicated tables are failed to be loaded [link #1].
> 
> This patchset as ACPICA PR [link #2] adds support to verify tables in
> acpi_reallocate_root_tables() which is invoked after installing tables in
> early stage, being ready for late ioremap and beofre loading table in late
> stage. If duplicated tables are detected, acpi_reallocate_root_tables()
> stops installing them to the final reallocated global table list.
> 
> In v1 patchset [link #3], problems can be seen for dynamic loading tables
> which are allocated as virtuall allocated tables. Such tables are
> incremented in the global table list as the sanity check done in install
> step only compares the table addresses while the virtual allocated
> addresses are not stable.
> In v2 patchset, we follow original design discussion made in ACPICA devel
> mailing list, implements deferred table verification so that duplicate
> tables are still can be detected in install step rather than in load step.
> Also we removed table signature check according to verified windows
> behavior [link #4] and reported issues [link #5].
> 
> Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
> Link: https://github.com//acpica/acpica/pull/265            [#2]
> Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
> Link: https://github.com//acpica/acpica/pull/121            [#4]
>        https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]
> 
> Lv Zheng (5):
>    ACPICA: Tables: Cleanup table handler invokers
>    ACPICA: Tables: Do not validate signature for dynamic table load
>    ACPICA: Tables: Change table duplication check to be related to
>      acpi_gbl_verify_table_checksum
>    ACPICA: Tables: Combine checksum/duplication verification together
>    ACPICA: Tables: Add deferred table verification support

I've tested these patches and can confirm that they fix the ACPI
errors on the system which started this all.

Note I've tested "v2" of the patch-set, I was on the Cc for the
cover letter for v3, but I did not receive the actual patches,
if you want me test v3 please send me the patches (or point
me to a git branch with them).

Regards,

Hans

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

* RE: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-19  7:59       ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-05-19  7:59 UTC (permalink / raw)
  To: Hans de Goede, Wysocki, Rafael J, Brown, Len, Moore, Robert, Box,
	David E
  Cc: Lv Zheng, linux-acpi, devel

Hi, Hans

> From: Hans de Goede [mailto:hdegoede@redhat.com]
> Subject: Re: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
> 
> Hi,
> 
> On 16-05-17 09:13, Lv Zheng wrote:
> > On linux, we can not verify ACPI tables before installing them into the
> > global table list in early stage due to the number of slot limitations for
> > early ioremap. This leaves a problem that we cannot detect duplicated
> > tables in early stage, causing unwanted error messages seen when the
> > duplicated tables are failed to be loaded [link #1].
> >
> > This patchset as ACPICA PR [link #2] adds support to verify tables in
> > acpi_reallocate_root_tables() which is invoked after installing tables in
> > early stage, being ready for late ioremap and beofre loading table in late
> > stage. If duplicated tables are detected, acpi_reallocate_root_tables()
> > stops installing them to the final reallocated global table list.
> >
> > In v1 patchset [link #3], problems can be seen for dynamic loading tables
> > which are allocated as virtuall allocated tables. Such tables are
> > incremented in the global table list as the sanity check done in install
> > step only compares the table addresses while the virtual allocated
> > addresses are not stable.
> > In v2 patchset, we follow original design discussion made in ACPICA devel
> > mailing list, implements deferred table verification so that duplicate
> > tables are still can be detected in install step rather than in load step.
> > Also we removed table signature check according to verified windows
> > behavior [link #4] and reported issues [link #5].
> >
> > Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
> > Link: https://github.com//acpica/acpica/pull/265            [#2]
> > Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
> > Link: https://github.com//acpica/acpica/pull/121            [#4]
> >        https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]
> >
> > Lv Zheng (5):
> >    ACPICA: Tables: Cleanup table handler invokers
> >    ACPICA: Tables: Do not validate signature for dynamic table load
> >    ACPICA: Tables: Change table duplication check to be related to
> >      acpi_gbl_verify_table_checksum
> >    ACPICA: Tables: Combine checksum/duplication verification together
> >    ACPICA: Tables: Add deferred table verification support
> 
> I've tested these patches and can confirm that they fix the ACPI
> errors on the system which started this all.
> 
> Note I've tested "v2" of the patch-set, I was on the Cc for the
> cover letter for v3, but I did not receive the actual patches,
> if you want me test v3 please send me the patches (or point
> me to a git branch with them).

What I added is:
		*table_index = i;
In acpi_tb_install_standard_table().
Without this line, Load a table 2nd time after the 1st time Load/Unload will fail.
Other changes are not functional. I'm sorry for that mistake.

Testing v2 can be sufficient as what v3 improves is not strictly related to your issue.
And we can ensure the v3 improvement's quality locally while for your issue I cannot.

So it's OK if you don't do any further testing, but if you want to try:
You can reach the code via the following git repository:
https://github.com/zetalog/linux/
They are top 5 commits in acpica-tables2 branch:
https://github.com/zetalog/linux/commits/acpica-tables2

# git remote add linux-acpica https://github.com/zetalog/linux/
# git fetch linux-acpica
# git checkout acpica-tables2

Thanks and best regards
Lv

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

* Re: [Devel] [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
@ 2017-05-19  7:59       ` Zheng, Lv
  0 siblings, 0 replies; 51+ messages in thread
From: Zheng, Lv @ 2017-05-19  7:59 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 3602 bytes --]

Hi, Hans

> From: Hans de Goede [mailto:hdegoede(a)redhat.com]
> Subject: Re: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
> 
> Hi,
> 
> On 16-05-17 09:13, Lv Zheng wrote:
> > On linux, we can not verify ACPI tables before installing them into the
> > global table list in early stage due to the number of slot limitations for
> > early ioremap. This leaves a problem that we cannot detect duplicated
> > tables in early stage, causing unwanted error messages seen when the
> > duplicated tables are failed to be loaded [link #1].
> >
> > This patchset as ACPICA PR [link #2] adds support to verify tables in
> > acpi_reallocate_root_tables() which is invoked after installing tables in
> > early stage, being ready for late ioremap and beofre loading table in late
> > stage. If duplicated tables are detected, acpi_reallocate_root_tables()
> > stops installing them to the final reallocated global table list.
> >
> > In v1 patchset [link #3], problems can be seen for dynamic loading tables
> > which are allocated as virtuall allocated tables. Such tables are
> > incremented in the global table list as the sanity check done in install
> > step only compares the table addresses while the virtual allocated
> > addresses are not stable.
> > In v2 patchset, we follow original design discussion made in ACPICA devel
> > mailing list, implements deferred table verification so that duplicate
> > tables are still can be detected in install step rather than in load step.
> > Also we removed table signature check according to verified windows
> > behavior [link #4] and reported issues [link #5].
> >
> > Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
> > Link: https://github.com//acpica/acpica/pull/265            [#2]
> > Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
> > Link: https://github.com//acpica/acpica/pull/121            [#4]
> >        https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]
> >
> > Lv Zheng (5):
> >    ACPICA: Tables: Cleanup table handler invokers
> >    ACPICA: Tables: Do not validate signature for dynamic table load
> >    ACPICA: Tables: Change table duplication check to be related to
> >      acpi_gbl_verify_table_checksum
> >    ACPICA: Tables: Combine checksum/duplication verification together
> >    ACPICA: Tables: Add deferred table verification support
> 
> I've tested these patches and can confirm that they fix the ACPI
> errors on the system which started this all.
> 
> Note I've tested "v2" of the patch-set, I was on the Cc for the
> cover letter for v3, but I did not receive the actual patches,
> if you want me test v3 please send me the patches (or point
> me to a git branch with them).

What I added is:
		*table_index = i;
In acpi_tb_install_standard_table().
Without this line, Load a table 2nd time after the 1st time Load/Unload will fail.
Other changes are not functional. I'm sorry for that mistake.

Testing v2 can be sufficient as what v3 improves is not strictly related to your issue.
And we can ensure the v3 improvement's quality locally while for your issue I cannot.

So it's OK if you don't do any further testing, but if you want to try:
You can reach the code via the following git repository:
https://github.com/zetalog/linux/
They are top 5 commits in acpica-tables2 branch:
https://github.com/zetalog/linux/commits/acpica-tables2

# git remote add linux-acpica https://github.com/zetalog/linux/
# git fetch linux-acpica
# git checkout acpica-tables2

Thanks and best regards
Lv

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

* Re: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
  2017-05-19  7:59       ` [Devel] " Zheng, Lv
  (?)
@ 2017-05-19  9:49       ` Hans de Goede
  -1 siblings, 0 replies; 51+ messages in thread
From: Hans de Goede @ 2017-05-19  9:49 UTC (permalink / raw)
  To: Zheng, Lv, Wysocki, Rafael J, Brown, Len, Moore, Robert, Box, David E
  Cc: Lv Zheng, linux-acpi, devel

Hi,

On 19-05-17 09:59, Zheng, Lv wrote:
> Hi, Hans
> 
>> From: Hans de Goede [mailto:hdegoede@redhat.com]
>> Subject: Re: [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support
>>
>> Hi,
>>
>> On 16-05-17 09:13, Lv Zheng wrote:
>>> On linux, we can not verify ACPI tables before installing them into the
>>> global table list in early stage due to the number of slot limitations for
>>> early ioremap. This leaves a problem that we cannot detect duplicated
>>> tables in early stage, causing unwanted error messages seen when the
>>> duplicated tables are failed to be loaded [link #1].
>>>
>>> This patchset as ACPICA PR [link #2] adds support to verify tables in
>>> acpi_reallocate_root_tables() which is invoked after installing tables in
>>> early stage, being ready for late ioremap and beofre loading table in late
>>> stage. If duplicated tables are detected, acpi_reallocate_root_tables()
>>> stops installing them to the final reallocated global table list.
>>>
>>> In v1 patchset [link #3], problems can be seen for dynamic loading tables
>>> which are allocated as virtuall allocated tables. Such tables are
>>> incremented in the global table list as the sanity check done in install
>>> step only compares the table addresses while the virtual allocated
>>> addresses are not stable.
>>> In v2 patchset, we follow original design discussion made in ACPICA devel
>>> mailing list, implements deferred table verification so that duplicate
>>> tables are still can be detected in install step rather than in load step.
>>> Also we removed table signature check according to verified windows
>>> behavior [link #4] and reported issues [link #5].
>>>
>>> Link: http://www.spinics.net/lists/linux-acpi/msg72215.html [#1]
>>> Link: https://github.com//acpica/acpica/pull/265            [#2]
>>> Link: http://www.spinics.net/lists/linux-acpi/msg72589.html [#3]
>>> Link: https://github.com//acpica/acpica/pull/121            [#4]
>>>         https://bugzilla.kernel.org/show_bug.cgi?id=118601    [#5]
>>>
>>> Lv Zheng (5):
>>>     ACPICA: Tables: Cleanup table handler invokers
>>>     ACPICA: Tables: Do not validate signature for dynamic table load
>>>     ACPICA: Tables: Change table duplication check to be related to
>>>       acpi_gbl_verify_table_checksum
>>>     ACPICA: Tables: Combine checksum/duplication verification together
>>>     ACPICA: Tables: Add deferred table verification support
>>
>> I've tested these patches and can confirm that they fix the ACPI
>> errors on the system which started this all.
>>
>> Note I've tested "v2" of the patch-set, I was on the Cc for the
>> cover letter for v3, but I did not receive the actual patches,
>> if you want me test v3 please send me the patches (or point
>> me to a git branch with them).
> 
> What I added is:
> 		*table_index = i;
> In acpi_tb_install_standard_table().
> Without this line, Load a table 2nd time after the 1st time Load/Unload will fail.
> Other changes are not functional. I'm sorry for that mistake.
> 
> Testing v2 can be sufficient as what v3 improves is not strictly related to your issue.
> And we can ensure the v3 improvement's quality locally while for your issue I cannot.
> 
> So it's OK if you don't do any further testing, but if you want to try:
> You can reach the code via the following git repository:
> https://github.com/zetalog/linux/
> They are top 5 commits in acpica-tables2 branch:
> https://github.com/zetalog/linux/commits/acpica-tables2
> 
> # git remote add linux-acpica https://github.com/zetalog/linux/
> # git fetch linux-acpica
> # git checkout acpica-tables2

Thank you for the info. I've added the missing *table_index = i; statement
to my local tree. I will let you know if I hit any issues with this
patch-set.

Regards,

Hans

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

end of thread, other threads:[~2017-05-19  9:49 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-27  9:34 [PATCH] ACPICA: Detect duplicate SSDT tables Hans de Goede
2017-02-28  5:19 ` Zheng, Lv
2017-02-28  5:19   ` [Devel] " Zheng, Lv
2017-02-28 14:31   ` Hans de Goede
2017-02-28 15:46     ` Moore, Robert
2017-02-28 15:46       ` [Devel] " Moore, Robert
2017-02-28 23:44       ` Hans de Goede
2017-03-01  0:11         ` Moore, Robert
2017-03-01  0:11           ` [Devel] " Moore, Robert
2017-03-01  3:21     ` Zheng, Lv
2017-03-01  3:21       ` [Devel] " Zheng, Lv
2017-03-01  9:19       ` Hans de Goede
2017-03-01 20:38         ` Moore, Robert
2017-03-01 20:38           ` [Devel] " Moore, Robert
2017-03-01 21:56           ` Rafael J. Wysocki
2017-03-02  1:59         ` Zheng, Lv
2017-03-02  1:59           ` [Devel] " Zheng, Lv
2017-03-02 15:24           ` Hans de Goede
2017-03-03  2:50             ` Zheng, Lv
2017-03-03  2:50               ` [Devel] " Zheng, Lv
2017-03-03 13:52               ` Hans de Goede
2017-03-13  6:01                 ` Zheng, Lv
2017-03-13  6:01                   ` [Devel] " Zheng, Lv
2017-05-16  7:13 ` [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred verification support Lv Zheng
2017-05-16  7:13   ` [Devel] " Lv Zheng
2017-05-16  7:13   ` [RFC PATCH v2 1/5] ACPICA: Tables: Cleanup table handler invokers Lv Zheng
2017-05-16  7:13     ` [Devel] " Lv Zheng
2017-05-16  7:13   ` [RFC PATCH v2 2/5] ACPICA: Tables: Do not validate signature for dynamic table load Lv Zheng
2017-05-16  7:13     ` [Devel] " Lv Zheng
2017-05-16  7:13   ` [RFC PATCH v2 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum Lv Zheng
2017-05-16  7:13     ` [Devel] " Lv Zheng
2017-05-16  7:13   ` [RFC PATCH v2 4/5] ACPICA: Tables: Combine checksum/duplication verification together Lv Zheng
2017-05-16  7:13     ` [Devel] " Lv Zheng
2017-05-16  7:13   ` [RFC PATCH v2 5/5] ACPICA: Tables: Add deferred table verification support Lv Zheng
2017-05-16  7:13     ` [Devel] " Lv Zheng
2017-05-18 14:01   ` [RFC PATCH v2 0/5] ACPICA: Tables: Add deferred " Hans de Goede
2017-05-19  7:59     ` Zheng, Lv
2017-05-19  7:59       ` [Devel] " Zheng, Lv
2017-05-19  9:49       ` Hans de Goede
2017-05-18  9:57 ` [RFC PATCH v3 " Lv Zheng
2017-05-18  9:57   ` [Devel] " Lv Zheng
2017-05-18  9:57   ` [RFC PATCH v3 1/5] ACPICA: Tables: Cleanup table handler invokers Lv Zheng
2017-05-18  9:57     ` [Devel] " Lv Zheng
2017-05-18  9:57   ` [RFC PATCH v3 2/5] ACPICA: Tables: Do not validate signature for dynamic table load Lv Zheng
2017-05-18  9:57     ` [Devel] " Lv Zheng
2017-05-18  9:57   ` [RFC PATCH v3 3/5] ACPICA: Tables: Change table duplication check to be related to acpi_gbl_verify_table_checksum Lv Zheng
2017-05-18  9:57     ` [Devel] " Lv Zheng
2017-05-18  9:57   ` [RFC PATCH v3 4/5] ACPICA: Tables: Combine checksum/duplication verification together Lv Zheng
2017-05-18  9:57     ` [Devel] " Lv Zheng
2017-05-18  9:57   ` [RFC PATCH v3 5/5] ACPICA: Tables: Add deferred table verification support Lv Zheng
2017-05-18  9:57     ` [Devel] " Lv Zheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.