{"id":2175746,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2175746/?format=json","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.0/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<3933560.kQq0lBPeGt@rafael.j.wysocki>","date":"2025-12-18T20:39:43","name":"[v1,6/8] ACPI: bus: Rework the handling of \\_SB._OSC platform features","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"cacf8ffee59a60f4cfcb4cc9c20d62dfb881af47","submitter":{"id":64267,"url":"http://patchwork.ozlabs.org/api/1.0/people/64267/?format=json","name":"Rafael J. Wysocki","email":"rafael@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/3933560.kQq0lBPeGt@rafael.j.wysocki/mbox/","series":[{"id":485914,"url":"http://patchwork.ozlabs.org/api/1.0/series/485914/?format=json","date":"2025-12-18T20:37:36","name":"ACPI: bus: Rework of the \\_SB._OSC handling","version":1,"mbox":"http://patchwork.ozlabs.org/series/485914/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2175746/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-43329-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=KHq0Wnqq;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.105.105.114; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-43329-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"KHq0Wnqq\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dXNGr6k7vz1y2r\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 19 Dec 2025 07:55:32 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 5D8B130210FB\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 20:55:25 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 30EAB346AC9;\n\tThu, 18 Dec 2025 20:43:17 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 063B8346A1B;\n\tThu, 18 Dec 2025 20:43:17 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 96C34C4CEFB;\n\tThu, 18 Dec 2025 20:43:15 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1766090597; cv=none;\n b=slbHrRlgNrcR2ZYdD+nNbiWfyBFNKg8dIGthQ7/AL+q/e00Hbq4hI+hBXG3lD5a++RZruY3pplQSCJlke3RJtm2k1349w5mc5ZBRbr1+pjGQ1TPhtcIwEbWnsPoW7EAWtattN8hmUeGyv9Of1i56djsv+BUhTnoRJo870YsmqSM=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1766090597; c=relaxed/simple;\n\tbh=TRz4UmjZYVBoGvjkGjAaJ4KVllyNLIuvUaPbwbc4FEU=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=k+QJrud+Udtz5NKwHmkS0DBe5xAmPAd4JsPNXelzDb0SHHMlAgdzFR3NVqSjmgRWo/J8qsrw6+jFc8EDmNe1J4OpduOesvayf2MVEyNV5b81H+P6KJpD8CBE5mBhBoJrTHlDk7NvAX8UbCmKPccdJzYXjShf5oJN7PDiuqiFdBc=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=KHq0Wnqq; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1766090596;\n\tbh=TRz4UmjZYVBoGvjkGjAaJ4KVllyNLIuvUaPbwbc4FEU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=KHq0Wnqq95x70BfeTJhu4mfDSe00Wue3Y39FLc/16tXKWDqwsHm5dBJKCfVS+t4GH\n\t PXZw9angCHzVTkCby5L7+SpiBDnnF61rcemPvbVCISDCeQxl6xZO0Y8nCcJ76XRJ/F\n\t AtB0fhoLXZ7DZkmqEDUws3EPYOzuBe7Kph0cHZnB85FsSFWqBgHZmD7kq6saaPkn6d\n\t jl3Y8J1fTCqkEbYnprLf3jn0YqQBs8LgC9FKli1cUV9rtDkdDdN8qzimM2g87/FpEu\n\t fbBy1c6MQjqEkmSDn/pw3UngRM+JmVS5Mrh+yEl/oQ685FYGdt7vNdT/AAogyWIrZ9\n\t bI0koq40wkmtw==","From":"\"Rafael J. Wysocki\" <rafael@kernel.org>","To":"Linux ACPI <linux-acpi@vger.kernel.org>","Cc":"LKML <linux-kernel@vger.kernel.org>,\n Linux PCI <linux-pci@vger.kernel.org>, Bjorn Helgaas <helgaas@kernel.org>,\n Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,\n Hans de Goede <hansg@kernel.org>,\n Mario Limonciello <mario.limonciello@amd.com>","Subject":"\n [PATCH v1 6/8] ACPI: bus: Rework the handling of \\_SB._OSC platform features","Date":"Thu, 18 Dec 2025 21:39:43 +0100","Message-ID":"<3933560.kQq0lBPeGt@rafael.j.wysocki>","Organization":"Linux Kernel Development","In-Reply-To":"<5049211.GXAFRqVoOG@rafael.j.wysocki>","References":"<5049211.GXAFRqVoOG@rafael.j.wysocki>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"UTF-8\""},"content":"From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>\n\nThe current handling of \\_SB._OSC is susceptible to problems with\nsetting error bits in the output buffer by mistake if the platform\nfirmware is supplied with a feature mask previously acknowledged\nby the analogous _OSC call with OSC_QUERY_ENABLE set.  If that\nhappens, acpi_run_osc() will return an error and the kernel will\nassume that it cannot control any of the features it has asked\nfor.  If an error bit has been set by mistake, however, the platform\nfirmware may expect the kernel to actually take over the control of\nthose features and nobody will take care of them going forward.\n\nIf the given feature mask has been already acknowledged once though,\nthe kernel may reasonably expect the _OSC evaluation to succeed and\nacknowledge all of the features in the current mask again, but that\nis not generally guaranteed to happen, so it is actually good to\nverify the return buffer.  Still, it is sufficient to check the\nfeature bits in the return buffer for this purpose.\n\nNamely, the OSC_INVALID_UUID_ERROR and OSC_INVALID_REVISION_ERROR bits\nshould not be set then because they were not set during the previous\n_OSC evaluation that has acknowledged the feature mask.  Moreover,\nif all of the feature bits that are set in the capabilities buffer\nare also set in the return buffer, the OSC_CAPABILITIES_MASK_ERROR\nshould not be set either and the OSC_REQUEST_ERROR bit doesn't matter\neven if set.  Thus if that is the case, the kernel may regard the\nentire feature mask as acknowledged and take over the control of the\ngiven features as per Section 6.2.12 of ACPI 6.6 [1].\n\nIf the feature masks in the capabilities buffer and in the return\nbuffer are different, the bits that are set in both masks may still\nbe regarded as acknowledged and the corresponding features may be\ncontrolled by the kernel.\n\nIntroduce a new function carrying out an _OSC handshake along the\nlines of the above description and make the \\_SB._OSC handling code\nuse it to avoid failing in some cases in which it may succeed\nregardless of platform firmware deficiencies.\n\nLink: https://uefi.org/specs/ACPI/6.6/06_Device_Configuration.html#osc-operating-system-capabilities\nSigned-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>\n---\n drivers/acpi/bus.c |  128 ++++++++++++++++++++++++++++++++++++-----------------\n 1 file changed, 88 insertions(+), 40 deletions(-)","diff":"--- a/drivers/acpi/bus.c\n+++ b/drivers/acpi/bus.c\n@@ -311,6 +311,79 @@ out:\n }\n EXPORT_SYMBOL(acpi_run_osc);\n \n+static int acpi_osc_handshake(acpi_handle handle, const char *uuid_str,\n+\t\t\t      int rev, struct acpi_buffer *cap)\n+{\n+\tunion acpi_object in_params[4], *out_obj;\n+\tsize_t bufsize = cap->length / sizeof(u32);\n+\tstruct acpi_object_list input;\n+\tstruct acpi_buffer output;\n+\tu32 *capbuf, *retbuf, test;\n+\tguid_t guid;\n+\tint ret, i;\n+\n+\tif (!cap || cap->length < 2 * sizeof(32) || guid_parse(uuid_str, &guid))\n+\t\treturn -EINVAL;\n+\n+\t/* First evaluate _OSC with OSC_QUERY_ENABLE set. */\n+\tcapbuf = cap->pointer;\n+\tcapbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;\n+\n+\tret = acpi_eval_osc(handle, &guid, rev, cap, in_params, &output);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tout_obj = output.pointer;\n+\tretbuf = (u32 *)out_obj->buffer.pointer;\n+\n+\tif (acpi_osc_error_check(handle, &guid, rev, cap, retbuf)) {\n+\t\tret = -ENODATA;\n+\t\tgoto out;\n+\t}\n+\n+\t/*\n+\t * Clear the feature bits in the capabilities buffer that have not been\n+\t * acknowledged and clear the return buffer.\n+\t */\n+\tfor (i = OSC_QUERY_DWORD + 1, test = 0; i < bufsize; i++) {\n+\t\tcapbuf[i] &= retbuf[i];\n+\t\ttest |= capbuf[i];\n+\t\tretbuf[i] = 0;\n+\t}\n+\t/*\n+\t * If none of the feature bits have been acknowledged, there's nothing\n+\t * more to do.\n+\t */\n+\tif (!test)\n+\t\tgoto out;\n+\n+\tretbuf[OSC_QUERY_DWORD] = 0;\n+\t/*\n+\t * Now evaluate _OSC again (directly) with OSC_QUERY_ENABLE clear and\n+\t * the updated input and output buffers used before.\n+\t */\n+\tcapbuf[OSC_QUERY_DWORD] = 0;\n+\t/* Reuse in_params[] populated by acpi_eval_osc(). */\n+\tinput.pointer = in_params;\n+\tinput.count = 4;\n+\n+\tif (ACPI_FAILURE(acpi_evaluate_object(handle, \"_OSC\", &input, &output))) {\n+\t\tret = -ENODATA;\n+\t\tgoto out;\n+\t}\n+\n+\t/* Clear the feature bits that have not been acknowledged in capbuf[]. */\n+\tfor (i = OSC_QUERY_DWORD + 1; i < bufsize; i++)\n+\t\tcapbuf[i] &= retbuf[i];\n+\n+\t/* Check _OSC errors to print debug messages if any. */\n+\tacpi_osc_error_check(handle, &guid, rev, cap, retbuf);\n+\n+out:\n+\tACPI_FREE(out_obj);\n+\treturn ret;\n+}\n+\n bool osc_sb_apei_support_acked;\n \n /*\n@@ -342,19 +415,16 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_sup\n \n bool osc_sb_cppc2_support_acked;\n \n-static u8 sb_uuid_str[] = \"0811B06E-4A27-44F9-8D60-3CBBC22E7B48\";\n static void acpi_bus_osc_negotiate_platform_control(void)\n {\n-\tu32 capbuf[2], *capbuf_ret;\n-\tstruct acpi_osc_context context = {\n-\t\t.uuid_str = sb_uuid_str,\n-\t\t.rev = 1,\n-\t\t.cap.length = 8,\n-\t\t.cap.pointer = capbuf,\n+\tstatic const u8 sb_uuid_str[] = \"0811B06E-4A27-44F9-8D60-3CBBC22E7B48\";\n+\tu32 capbuf[2];\n+\tstruct acpi_buffer cap = {\n+\t\t.pointer = capbuf,\n+\t\t.length = sizeof(capbuf),\n \t};\n \tacpi_handle handle;\n \n-\tcapbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;\n \tcapbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */\n \tif (IS_ENABLED(CONFIG_ACPI_PROCESSOR_AGGREGATOR))\n \t\tcapbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT;\n@@ -400,43 +470,21 @@ static void acpi_bus_osc_negotiate_platf\n \tif (ACPI_FAILURE(acpi_get_handle(NULL, \"\\\\_SB\", &handle)))\n \t\treturn;\n \n-\tif (ACPI_FAILURE(acpi_run_osc(handle, &context)))\n-\t\treturn;\n-\n-\tcapbuf_ret = context.ret.pointer;\n-\tif (context.ret.length <= OSC_SUPPORT_DWORD) {\n-\t\tkfree(context.ret.pointer);\n-\t\treturn;\n-\t}\n-\n-\t/*\n-\t * Now run _OSC again with query flag clear and with the caps\n-\t * supported by both the OS and the platform.\n-\t */\n-\tcapbuf[OSC_QUERY_DWORD] = 0;\n-\tcapbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD];\n-\tkfree(context.ret.pointer);\n-\n-\tif (ACPI_FAILURE(acpi_run_osc(handle, &context)))\n+\tif (acpi_osc_handshake(handle, sb_uuid_str, 1, &cap))\n \t\treturn;\n \n-\tcapbuf_ret = context.ret.pointer;\n-\tif (context.ret.length > OSC_SUPPORT_DWORD) {\n #ifdef CONFIG_ACPI_CPPC_LIB\n-\t\tosc_sb_cppc2_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;\n+\tosc_sb_cppc2_support_acked = capbuf[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;\n #endif\n \n-\t\tosc_sb_apei_support_acked =\n-\t\t\tcapbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;\n-\t\tosc_pc_lpi_support_confirmed =\n-\t\t\tcapbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;\n-\t\tosc_sb_native_usb4_support_confirmed =\n-\t\t\tcapbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;\n-\t\tosc_cpc_flexible_adr_space_confirmed =\n-\t\t\tcapbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;\n-\t}\n-\n-\tkfree(context.ret.pointer);\n+\tosc_sb_apei_support_acked =\n+\t\t\tcapbuf[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;\n+\tosc_pc_lpi_support_confirmed =\n+\t\t\tcapbuf[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;\n+\tosc_sb_native_usb4_support_confirmed =\n+\t\t\tcapbuf[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;\n+\tosc_cpc_flexible_adr_space_confirmed =\n+\t\t\tcapbuf[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;\n }\n \n /*\n","prefixes":["v1","6/8"]}