From patchwork Thu Dec 1 04:00:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Len Brown X-Patchwork-Id: 9455327 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 37D4B60515 for ; Thu, 1 Dec 2016 04:15:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2802128471 for ; Thu, 1 Dec 2016 04:15:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B149284BF; Thu, 1 Dec 2016 04:15:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA5B928471 for ; Thu, 1 Dec 2016 04:15:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754577AbcLAEPs (ORCPT ); Wed, 30 Nov 2016 23:15:48 -0500 Received: from mail-qk0-f194.google.com ([209.85.220.194]:32774 "EHLO mail-qk0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753591AbcLAEPr (ORCPT ); Wed, 30 Nov 2016 23:15:47 -0500 Received: by mail-qk0-f194.google.com with SMTP id x190so24719042qkb.0; Wed, 30 Nov 2016 20:15:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:reply-to:organization; bh=RWzvZFXlVd++NMVAT94nvMTrGns4Vy3+kdp44l9+v5w=; b=G3pnv/BDEZUwgfyjucdrssFhivNGT63rk3+Ixqd2VHlNi/4gv6foiGwKs/jQ0/O/m3 Xk+7NtH9sHQe27ybzLOBsfxI4++xW59NxlWfatIXVtFlnBurMQ2yL0YrncnRcy00C9ix cHheTf39Sf19XiC1U3ecXabur8RcgBtvAtRJ1SjU+HbZRPIqwvMA8g136i3U2rWdJiPf RJudV1hLewHcKstW1V+s7pcNolGqiEIm5lespDNWXWthhCcBraEw+X/7fYjMojLFNxro B89a4Rn6u/FHJetJvEncynHYSe1886gbdl8akvQk7+gPFik0ZC+hIS+9CHE+thoUfWke /hIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :reply-to:organization; bh=RWzvZFXlVd++NMVAT94nvMTrGns4Vy3+kdp44l9+v5w=; b=VKTKXRTMq0ClH5VzvMPvyeKiTU7CwLWQUWuOcTrFspWDgTvCo2RGGJYVhnMG1zSv9G 6HhEvLFSWXFGIUGt1rlaEWPF8fVq2Opdk8yFPbgF39i3H79u/p63OzcTbbGBw5CTwsCN zg7APF8K2itvLZfeZx9hZK84CCGJW14CYBrYPUZL5B3k4NbADyAAFKSnQscfsGdE0/q8 qK6/RTMOsfM6olQ7JoddpR3rY9CVmG+Pn3FgdcjmZJKHNea8kCchzbUBxwSwSl2GKL5l 3xLe/zMysLsAbPPMB5Xf/ovjczmylyy3e0Pxb7HlNNIhsNstOBkkCfKcLlozgOLMwrg6 StjA== X-Gm-Message-State: AKaTC005WxZ12CeRqzJWFPygUIWrB3TK/lZ81ky9yV6Klp/AkeWptwDoW7e82634Pe/f+A== X-Received: by 10.55.92.195 with SMTP id q186mr30054768qkb.170.1480564945165; Wed, 30 Nov 2016 20:02:25 -0800 (PST) Received: from z87.localdomain (pool-96-230-116-151.bstnma.fios.verizon.net. [96.230.116.151]) by smtp.gmail.com with ESMTPSA id y194sm21762757qkb.8.2016.11.30.20.02.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 30 Nov 2016 20:02:24 -0800 (PST) From: Len Brown To: linux-acpi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Len Brown , Lukas Wunner Subject: [PATCH v2] ACPI: Document _OSI and _REV for Linux BIOS writers Date: Wed, 30 Nov 2016 23:00:30 -0500 Message-Id: <619282eab16a5847ff71d601c43b7df48d306d9e.1480564794.git.len.brown@intel.com> X-Mailer: git-send-email 2.11.0.rc1 Reply-To: Len Brown Organization: Intel Open Source Technology Center Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Len Brown Based on a recent session at the Linux Plumber's Conference, we need to be more clear about how a BIOS should use _OSI to properly support Linux. Signed-off-by: Len Brown Cc: Lukas Wunner Reviewed-by: Lukas Wunner --- Documentation/acpi/osi.txt | 188 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 Documentation/acpi/osi.txt diff --git a/Documentation/acpi/osi.txt b/Documentation/acpi/osi.txt new file mode 100644 index 000000000000..c385024409a7 --- /dev/null +++ b/Documentation/acpi/osi.txt @@ -0,0 +1,188 @@ +ACPI _OSI and _REV methods +-------------------------- + +An ACPI BIOS can use the "Operating System Interfaces" method (_OSI) +to find out what the operating system supports. Eg. If BIOS +AML code includes _OSI("XYZ"), the kernel's AML interpreter +can evaluate that method, look to see if it supports 'XYZ' +and answer YES or NO to the BIOS. + +The ACPI _REV method returns the "Revision of the ACPI specification +that OSPM supports" + +This document explains how and why the BIOS and Linux should use these methods. +It also explains how and why they are widely misused. + +How to use _OSI +--------------- + +Linux runs on two groups of machines -- those that are tested by the OEM +to be compatible with Linux, and those that were never tested with Linux, +but where Linux was installed to replace the original OS (Windows or OSX). + +The larger group is the systems tested to run only Windows. Not only that, +but many were tested to run with just one specific version of Windows. +So even though the BIOS may use _OSI to query what version of Windows is running, +only a single path through the BIOS has actually been tested. +Experience shows that taking untested paths through the BIOS +exposes Linux to an entire category of BIOS bugs. +For this reason, Linux _OSI defaults must continue to claim compatibility +with all versions of Windows. + +But Linux isn't actually compatible with Windows, and the Linux community +has also been hurt with regressions when Linux adds the latest version of +Windows to its list of _OSI strings. So it is possible that additional strings +will be more thoroughly vetted before shipping upstream in the future. +But it is likely that they will all eventually be added. + +What should an OEM do if they want to support Linux and Windows +using the same BIOS image? Often they need to do something different +for Linux to deal with how Linux is different from Windows. +Here the BIOS should ask exactly what it wants to know: + +_OSI("Linux-OEM-my_interface_name") +where 'OEM' is needed if this is an OEM-specific hook, +and 'my_interface_name' describes the hook, which could be a +quirk, a bug, or a bug-fix. + +In addition, the OEM should send a patch to upstream Linux +via the linux-acpi@vger.kernel.org mailing list. When that patch +is checked into Linux, the OS will answer "YES" when the BIOS +on the OEM's system uses _OSI to ask if the interface is supported +by the OS. Linux distributors can back-port that patch for Linux +pre-installs, and it will be included by all distributions that +re-base to upstream. If the distribution can not update the kernel binary, +they can also add an acpi_osi=Linux-OEM-my_interface_name +cmdline parameter to the boot loader, as needed. + +If the string refers to a feature where the upstream kernel +eventually grows support, a patch should be sent to remove +the string when that support is added to the kernel. + +That was easy. Read on, to find out how to do it wrong. + +Before _OSI, there was _OS +-------------------------- + +ACPI 1.0 specified "_OS" as an +"object that evaluates to a string that identifies the operating system." + +The ACPI BIOS flow would include an evaluation of _OS, and the AML +interpreter in the kernel would return to it a string identifying the OS: + +Windows 98, SE: "Microsoft Windows" +Windows ME: "Microsoft WindowsME:Millenium Edition" +Windows NT: "Microsoft Windows NT" + +The idea was on a platform tasked with running multiple OS's, +the BIOS could use _OS to enable devices that an OS +might support, or enable quirks or bug workarounds +necessary to make the platform compatible with that pre-existing OS. + +But _OS had fundamental problems. First, the BIOS needed to know the name +of every possible version of the OS that would run on it, and needed to know +all the quirks of those OS's. Certainly it would make more sense +for the BIOS to ask *specific* things of the OS, such +"do you support a specific interface", and thus in ACPI 3.0, +_OSI was born to replace _OS. + +_OS was abandoned, though even today, many BIOS look for +_OS "Microsoft Windows NT", though it seems somewhat far-fetched +that anybody would install those old operating systems +over what came with the machine. + +Linux answers "Microsoft Windows NT" to please that BIOS idiom. +That is the *only* viable strategy, as that is what modern Windows does, +and so doing otherwise could steer the BIOS down an untested path. + +_OSI is born, and immediately misused +-------------------------------------- + +With _OSI, the *BIOS* provides the string describing an interface, +and asks the OS: "YES/NO, are you compatible with this interface?" + +eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how +to deal with the thermal extensions made to the ACPI 3.0 specification. +An old OS that doesn't know about those extensions would answer FALSE, +and a new OS may be able to return TRUE. + +For an OS-specific interface, the ACPI spec said that the BIOS and the OS +were to agree on a string of the form such as "Windows-interface_name". + +But two bad things happened. First, the Windows ecosystem used _OSI +not as designed, but as a direct replacement for _OS -- identifying +the OS version, rather than an OS supported interface. Indeed, right +from the start, the ACPI 3.0 spec itself codified this misuse +in example code using _OSI("Windows 2001"). + +This misuse was adopted and continues today. + +Linux had no choice but to also return TRUE to _OSI("Windows 2001") +and its successors. To do otherwise would virtually guarantee breaking +a BIOS that has been tested only with that _OSI returning TRUE. + +This strategy is problematic, as Linux is never completely compatible with +the latest version of Windows, and sometimes it takes more than a year +to iron out incompatibilities. + +Not to be out-done, the Linux community made things worse by returning TRUE +to _OSI("Linux"). Doing so is even worse than the Windows misuse +of _OSI, as "Linux" does not even contain any version information. +_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's +using it in untested BIOS flows. But some OEM's used _OSI("Linux") +in tested flows to support real Linux features. In 2009, Linux +removed _OSI("Linux"), and added a cmdline parameter to restore it +for legacy systems still needed it. Further a BIOS_BUG warning prints +for all BIOS's that invoke it. + +No BIOS should use _OSI("Linux"). + +The result is a strategy for Linux to maximize compatibility with +ACPI BIOS that are tested on Windows machines. There is a real risk +of over-stating that compatibility; but the alternative has often been +catastrophic failure resulting from the BIOS taking paths that +were never validated under *any* OS. + +Do not use _REV +--------------- + +Since _OSI("Linux") went away, some BIOS writers used _REV +to support Linux and Windows differences in the same BIOS. + +_REV was defined in ACPI 1.0 to return the version of ACPI +supported by the OS and the OS AML interpreter. + +Modern Windows returns _REV = 2. Linux used ACPI_CA_SUPPORT_LEVEL, +which would increment, based on the version of the spec supported. + +Unfortunately, _REV was also misused. eg. some BIOS would check +for _REV = 3, and do something for Linux, but when Linux returned +_REV = 4, that support broke. + +In response to this problem, Linux returns _REV = 2 always, +from mid-2015 onward. The ACPI specification will also be updated +to reflect that _REV is deprecated, and always returns 2. + +Apple Mac and _OSI("Darwin") +---------------------------- + +On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin") +to determine if the machine is running Apple OSX. + +Like Linux's _OSI("*Windows*") strategy, Linux defaults to +answering YES to _OSI("Darwin") to enable full access +to the hardware and validated BIOS paths seen by OSX. +Just like on Windows-tested platforms, this strategy has risks. + +Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin") +for the purpose of enabling Mac Thunderbolt support. Further, +if the kernel noticed _OSI("Darwin") being invoked, it additionally +disabled all _OSI("*Windows*") to keep poorly written Mac BIOS +from going down untested combinations of paths. + +The Linux-3.18 change in default caused power regressions on Mac +laptops, and the 3.18 implementation did not allow changing +the default via cmdline "acpi_osi=!Darwin". Linux-4.7 fixed +the ability to use acpi_osi=!Darwin as a workaround, and +we hope to see Mac Thunderbolt power management support in Linux-4.11. +