cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

osi.rst (8469B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3==========================
      4ACPI _OSI and _REV methods
      5==========================
      6
      7An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
      8to find out what the operating system supports. Eg. If BIOS
      9AML code includes _OSI("XYZ"), the kernel's AML interpreter
     10can evaluate that method, look to see if it supports 'XYZ'
     11and answer YES or NO to the BIOS.
     12
     13The ACPI _REV method returns the "Revision of the ACPI specification
     14that OSPM supports"
     15
     16This document explains how and why the BIOS and Linux should use these methods.
     17It also explains how and why they are widely misused.
     18
     19How to use _OSI
     20===============
     21
     22Linux runs on two groups of machines -- those that are tested by the OEM
     23to be compatible with Linux, and those that were never tested with Linux,
     24but where Linux was installed to replace the original OS (Windows or OSX).
     25
     26The larger group is the systems tested to run only Windows.  Not only that,
     27but many were tested to run with just one specific version of Windows.
     28So even though the BIOS may use _OSI to query what version of Windows is running,
     29only a single path through the BIOS has actually been tested.
     30Experience shows that taking untested paths through the BIOS
     31exposes Linux to an entire category of BIOS bugs.
     32For this reason, Linux _OSI defaults must continue to claim compatibility
     33with all versions of Windows.
     34
     35But Linux isn't actually compatible with Windows, and the Linux community
     36has also been hurt with regressions when Linux adds the latest version of
     37Windows to its list of _OSI strings.  So it is possible that additional strings
     38will be more thoroughly vetted before shipping upstream in the future.
     39But it is likely that they will all eventually be added.
     40
     41What should an OEM do if they want to support Linux and Windows
     42using the same BIOS image?  Often they need to do something different
     43for Linux to deal with how Linux is different from Windows.
     44Here the BIOS should ask exactly what it wants to know:
     45
     46_OSI("Linux-OEM-my_interface_name")
     47where 'OEM' is needed if this is an OEM-specific hook,
     48and 'my_interface_name' describes the hook, which could be a
     49quirk, a bug, or a bug-fix.
     50
     51In addition, the OEM should send a patch to upstream Linux
     52via the linux-acpi@vger.kernel.org mailing list.  When that patch
     53is checked into Linux, the OS will answer "YES" when the BIOS
     54on the OEM's system uses _OSI to ask if the interface is supported
     55by the OS.  Linux distributors can back-port that patch for Linux
     56pre-installs, and it will be included by all distributions that
     57re-base to upstream.  If the distribution can not update the kernel binary,
     58they can also add an acpi_osi=Linux-OEM-my_interface_name
     59cmdline parameter to the boot loader, as needed.
     60
     61If the string refers to a feature where the upstream kernel
     62eventually grows support, a patch should be sent to remove
     63the string when that support is added to the kernel.
     64
     65That was easy.  Read on, to find out how to do it wrong.
     66
     67Before _OSI, there was _OS
     68==========================
     69
     70ACPI 1.0 specified "_OS" as an
     71"object that evaluates to a string that identifies the operating system."
     72
     73The ACPI BIOS flow would include an evaluation of _OS, and the AML
     74interpreter in the kernel would return to it a string identifying the OS:
     75
     76Windows 98, SE: "Microsoft Windows"
     77Windows ME: "Microsoft WindowsME:Millennium Edition"
     78Windows NT: "Microsoft Windows NT"
     79
     80The idea was on a platform tasked with running multiple OS's,
     81the BIOS could use _OS to enable devices that an OS
     82might support, or enable quirks or bug workarounds
     83necessary to make the platform compatible with that pre-existing OS.
     84
     85But _OS had fundamental problems.  First, the BIOS needed to know the name
     86of every possible version of the OS that would run on it, and needed to know
     87all the quirks of those OS's.  Certainly it would make more sense
     88for the BIOS to ask *specific* things of the OS, such
     89"do you support a specific interface", and thus in ACPI 3.0,
     90_OSI was born to replace _OS.
     91
     92_OS was abandoned, though even today, many BIOS look for
     93_OS "Microsoft Windows NT", though it seems somewhat far-fetched
     94that anybody would install those old operating systems
     95over what came with the machine.
     96
     97Linux answers "Microsoft Windows NT" to please that BIOS idiom.
     98That is the *only* viable strategy, as that is what modern Windows does,
     99and so doing otherwise could steer the BIOS down an untested path.
    100
    101_OSI is born, and immediately misused
    102=====================================
    103
    104With _OSI, the *BIOS* provides the string describing an interface,
    105and asks the OS: "YES/NO, are you compatible with this interface?"
    106
    107eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
    108to deal with the thermal extensions made to the ACPI 3.0 specification.
    109An old OS that doesn't know about those extensions would answer FALSE,
    110and a new OS may be able to return TRUE.
    111
    112For an OS-specific interface, the ACPI spec said that the BIOS and the OS
    113were to agree on a string of the form such as "Windows-interface_name".
    114
    115But two bad things happened.  First, the Windows ecosystem used _OSI
    116not as designed, but as a direct replacement for _OS -- identifying
    117the OS version, rather than an OS supported interface.  Indeed, right
    118from the start, the ACPI 3.0 spec itself codified this misuse
    119in example code using _OSI("Windows 2001").
    120
    121This misuse was adopted and continues today.
    122
    123Linux had no choice but to also return TRUE to _OSI("Windows 2001")
    124and its successors.  To do otherwise would virtually guarantee breaking
    125a BIOS that has been tested only with that _OSI returning TRUE.
    126
    127This strategy is problematic, as Linux is never completely compatible with
    128the latest version of Windows, and sometimes it takes more than a year
    129to iron out incompatibilities.
    130
    131Not to be out-done, the Linux community made things worse by returning TRUE
    132to _OSI("Linux").  Doing so is even worse than the Windows misuse
    133of _OSI, as "Linux" does not even contain any version information.
    134_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
    135using it in untested BIOS flows.  But some OEM's used _OSI("Linux")
    136in tested flows to support real Linux features.  In 2009, Linux
    137removed _OSI("Linux"), and added a cmdline parameter to restore it
    138for legacy systems still needed it.  Further a BIOS_BUG warning prints
    139for all BIOS's that invoke it.
    140
    141No BIOS should use _OSI("Linux").
    142
    143The result is a strategy for Linux to maximize compatibility with
    144ACPI BIOS that are tested on Windows machines.  There is a real risk
    145of over-stating that compatibility; but the alternative has often been
    146catastrophic failure resulting from the BIOS taking paths that
    147were never validated under *any* OS.
    148
    149Do not use _REV
    150===============
    151
    152Since _OSI("Linux") went away, some BIOS writers used _REV
    153to support Linux and Windows differences in the same BIOS.
    154
    155_REV was defined in ACPI 1.0 to return the version of ACPI
    156supported by the OS and the OS AML interpreter.
    157
    158Modern Windows returns _REV = 2.  Linux used ACPI_CA_SUPPORT_LEVEL,
    159which would increment, based on the version of the spec supported.
    160
    161Unfortunately, _REV was also misused.  eg. some BIOS would check
    162for _REV = 3, and do something for Linux, but when Linux returned
    163_REV = 4, that support broke.
    164
    165In response to this problem, Linux returns _REV = 2 always,
    166from mid-2015 onward.  The ACPI specification will also be updated
    167to reflect that _REV is deprecated, and always returns 2.
    168
    169Apple Mac and _OSI("Darwin")
    170============================
    171
    172On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
    173to determine if the machine is running Apple OSX.
    174
    175Like Linux's _OSI("*Windows*") strategy, Linux defaults to
    176answering YES to _OSI("Darwin") to enable full access
    177to the hardware and validated BIOS paths seen by OSX.
    178Just like on Windows-tested platforms, this strategy has risks.
    179
    180Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
    181for the purpose of enabling Mac Thunderbolt support.  Further,
    182if the kernel noticed _OSI("Darwin") being invoked, it additionally
    183disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
    184from going down untested combinations of paths.
    185
    186The Linux-3.18 change in default caused power regressions on Mac
    187laptops, and the 3.18 implementation did not allow changing
    188the default via cmdline "acpi_osi=!Darwin".  Linux-4.7 fixed
    189the ability to use acpi_osi=!Darwin as a workaround, and
    190we hope to see Mac Thunderbolt power management support in Linux-4.11.