RE: [PATCH] ACPICA: Detect duplicate SSDT tables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx]
> Sent: Wednesday, March 1, 2017 1:19 AM
> To: Zheng, Lv <lv.zheng@xxxxxxxxx>; Rafael J . Wysocki
> <rjw@xxxxxxxxxxxxx>; Len Brown <lenb@xxxxxxxxxx>; Moore, Robert
> <robert.moore@xxxxxxxxx>
> Cc: linux-acpi@xxxxxxxxxxxxxxx; devel@xxxxxxxxxx
> 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@xxxxxxxxxx]
> >> 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@xxxxxxxxxx]
> >>>> 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@xxxxxxxxxx>
> >>>> ---
> >>>>  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
> >>>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux