]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.6.1/acpi-osi-fix-an-issue-that-acpi_osi-cannot-disable-acpica-internal-strings.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.6.1 / acpi-osi-fix-an-issue-that-acpi_osi-cannot-disable-acpica-internal-strings.patch
1 From 30c9bb0d7603e7b3f4d6a0ea231e1cddae020c32 Mon Sep 17 00:00:00 2001
2 From: Lv Zheng <lv.zheng@intel.com>
3 Date: Tue, 3 May 2016 16:48:20 +0800
4 Subject: ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA internal strings
5
6 From: Lv Zheng <lv.zheng@intel.com>
7
8 commit 30c9bb0d7603e7b3f4d6a0ea231e1cddae020c32 upstream.
9
10 The order of the _OSI related functionalities is as follows:
11
12 acpi_blacklisted()
13 acpi_dmi_osi_linux()
14 acpi_osi_setup()
15 acpi_osi_setup()
16 acpi_update_interfaces() if "!*"
17 <<<<<<<<<<<<<<<<<<<<<<<<
18 parse_args()
19 __setup("acpi_osi=")
20 acpi_osi_setup_linux()
21 acpi_update_interfaces() if "!*"
22 <<<<<<<<<<<<<<<<<<<<<<<<
23 acpi_early_init()
24 acpi_initialize_subsystem()
25 acpi_ut_initialize_interfaces()
26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27 acpi_bus_init()
28 acpi_os_initialize1()
29 acpi_install_interface_handler(acpi_osi_handler)
30 acpi_osi_setup_late()
31 acpi_update_interfaces() for "!"
32 >>>>>>>>>>>>>>>>>>>>>>>>
33 acpi_osi_handler()
34
35 Since acpi_osi_setup_linux() can override acpi_dmi_osi_linux(), the command
36 line setting can override the DMI detection. That's why acpi_blacklisted()
37 is put before __setup("acpi_osi=").
38
39 Then we can notice the following wrong invocation order. There are
40 acpi_update_interfaces() (marked by <<<<) calls invoked before
41 acpi_ut_initialize_interfaces() (marked by ^^^^). This makes it impossible
42 to use acpi_osi=!* correctly from OSI DMI table or from the command line.
43 The use of acpi_osi=!* is meant to disable both ACPICA
44 (acpi_gbl_supported_interfaces) and Linux specific strings
45 (osi_setup_entries) while the ACPICA part should have stopped working
46 because of the order issue.
47
48 This patch fixes this issue by moving acpi_update_interfaces() to where
49 it is invoked for acpi_osi=! (marked by >>>>) as this is ensured to be
50 invoked after acpi_ut_initialize_interfaces() (marked by ^^^^). Linux
51 specific strings are still handled in the original place in order to make
52 the following command line working: acpi_osi=!* acpi_osi="Module Device".
53
54 Note that since acpi_osi=!* is meant to further disable linux specific
55 string comparing to the acpi_osi=!, there is no such use case in our bug
56 fixing work and hence there is no one using acpi_osi=!* either from the
57 command line or from the DMI quirks, this issue is just a theoretical
58 issue.
59
60 Fixes: 741d81280ad2 (ACPI: Add facility to remove all _OSI strings)
61 Tested-by: Lukas Wunner <lukas@wunner.de>
62 Tested-by: Chen Yu <yu.c.chen@intel.com>
63 Signed-off-by: Lv Zheng <lv.zheng@intel.com>
64 Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
65 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
66
67 ---
68 drivers/acpi/osl.c | 16 +++++++++++-----
69 1 file changed, 11 insertions(+), 5 deletions(-)
70
71 --- a/drivers/acpi/osl.c
72 +++ b/drivers/acpi/osl.c
73 @@ -135,7 +135,7 @@ static struct osi_linux {
74 unsigned int enable:1;
75 unsigned int dmi:1;
76 unsigned int cmdline:1;
77 - unsigned int default_disabling:1;
78 + u8 default_disabling;
79 } osi_linux = {0, 0, 0, 0};
80
81 static u32 acpi_osi_handler(acpi_string interface, u32 supported)
82 @@ -1751,10 +1751,13 @@ void __init acpi_osi_setup(char *str)
83 if (*str == '!') {
84 str++;
85 if (*str == '\0') {
86 - osi_linux.default_disabling = 1;
87 + /* Do not override acpi_osi=!* */
88 + if (!osi_linux.default_disabling)
89 + osi_linux.default_disabling =
90 + ACPI_DISABLE_ALL_VENDOR_STRINGS;
91 return;
92 } else if (*str == '*') {
93 - acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
94 + osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
95 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
96 osi = &osi_setup_entries[i];
97 osi->enable = false;
98 @@ -1827,10 +1830,13 @@ static void __init acpi_osi_setup_late(v
99 acpi_status status;
100
101 if (osi_linux.default_disabling) {
102 - status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
103 + status = acpi_update_interfaces(osi_linux.default_disabling);
104
105 if (ACPI_SUCCESS(status))
106 - printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
107 + printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
108 + osi_linux.default_disabling ==
109 + ACPI_DISABLE_ALL_STRINGS ?
110 + " and feature groups" : "");
111 }
112
113 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {