Friday, July 7, 2017

Why cannot ACPI _REV object be used to detect Linux anymore?

Linux community is never a fan of distinguishing Windows & Linux in BIOS (see my 2012's blog Why does Linux Say It Is not Linux in _OSI("Linux")?). However, many BIOS engineers seem to see the needs of to workaround BIOS bugs for Linux regardlessly. After realising _OSI("Linux") cannot be used by default, some creative BIOS engineers figured ACPI's _REV object could be used for this purpose some years ago, based on the following facts:

1. _REV definition in ACPI spec 5.1


2. Windows returns 2 & Linux returns ACPI revision


While it is obvious it was Windows which did not follow ACPI spec, nothing can stop BIOS engineers from mis-using _REV as a mechanism to detect Linux in BIOS ASL codes.

It did not take long when ACPI Spec Work Group (ASWG), the owner and the publisher of ACPI spec, realised that many systems are mis-using _REV objects in their firmware. Eventually a spec contributer submitted a change to _REV object in ACPI 6.0 and later, and the _REV object is now defined as below:



After ACPI 6.0 was published, the corresponding changes are also made to Linux kernel - the evaluation of _REV now returns 2 in kernel 4.1 and later (for example, Ubuntu 15.10 with kernel 4.2).

In order to provide backward compatibility, a new kernel parameter "acpi_rev_override" was introduced for those who still want to use _REV = 5 in their BIOS ASL code, but most of major Linux distributions do not include this kernel parameter by default, and it should be used with cautions.

If you are using one of the systems with _REV in the firmware, you can develop a kernel patch to add your system to the _REV quirk list acpi_rev_dmi_table in drivers/acpi/blacklist.c as below, like the patch I submitted.

static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
        {
         .callback = dmi_enable_rev_override,
         .ident = "DELL XPS 13 (2015)",
         .matches = {
                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
                      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
                },
        },
        ...
  • DMI_SYS_VENDOR can be identified by sudo dmidecode -s system-manufacturer 
  • DMI_PRODUCT_NAME can be identified by sudo dmidecode -s system-product-name.

No comments:

Post a Comment