Received: by 2002:ab2:644:0:b0:1ec:cbc4:63fb with SMTP id 4csp1141142lqn; Mon, 26 Feb 2024 08:48:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCULunr/m727ud0H/MUxl6jgKhFMtAgs8u026KC3Yn4jaxh/lQQauQdm/tzUUd0bHIivckQaicdpYaLLBpb4Bt4F4IFbhgNa39P1/JuMQA== X-Google-Smtp-Source: AGHT+IGIfDg9JgFNPy6IIoeV5qG5LmB5LshexglcTWZ9oK869ICut+BRgEKh8xwO4cV+d7xjU88j X-Received: by 2002:a05:6402:7c5:b0:564:5604:d0e1 with SMTP id u5-20020a05640207c500b005645604d0e1mr5237402edy.38.1708966098081; Mon, 26 Feb 2024 08:48:18 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708966098; cv=pass; d=google.com; s=arc-20160816; b=i49UWciADrEB5AAiDAaIt21QWgE5G3wgQdQoBEf/IADMcsLgW46YtZS8U4J0ZaG2gE UdRf/5zMlunAvvKZzUbSiq5iDifLHztih9f5i2hSBSGcLk7/OiCAeQQ33RrSlF7AvKtE 0s1x68BkSS2bVy9YfS8bPiosHdytEuq0zW4gw8Wh87w31TRdMpWXLDwWDrliOsKzRlZx I0YcuPmsP7+p1tLtu8ZQU7YapLgnmvyG02A22V0n1i7JF5XID604fESbhDsK7wXPxxqa 8IIoD8zScCteU71RJ5StZAEakmjgrd6Jt/Du0oTCjZPSkz4TZuLu2q6h50Q3h6cyVe6l xbNA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=QIXBImLK/l5R4/Pb9pL6SlbkpBTSUcYe51WpoYJ0U5s=; fh=s5Fc0MEg8Xcp85xwyejK4S4zs7msQB7g1OY0X3YpOJg=; b=UQIye2BzWGVx9d6hQOgc0fCMzFLBg7RIDbvQje9AH/wUH5g4GuOWuhRituQsYw3eZk eSQs/+/keqWdH2SXxtFlZZAgIdHkM+GaKn7TzBTtApDQMT6oNj5VkRL2rA/xpuzarEl+ nvooPwtHljKAR0tcmV/ns9b3JcU4BBaB3LC2Uf2zU3YlTQ35bHvzzsygj9Xx3JhRJn46 iAds4o9SpShQMI6s7/g528SO6JrKk3KH+VeuNKE6pUXdfMRXL7J6fNfnI3WRZuOvClUz pn27iadTYFYHnJX1SEsi1NL7K8zCIMjNOAqe+QUldAc2OC0oJ3IEBvi7ze22ixxZT27F NeUA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=rjwysocki.net); spf=pass (google.com: domain of linux-kernel+bounces-81930-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81930-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id bf11-20020a0564021a4b00b00565d73c3fd9si1326324edb.93.2024.02.26.08.48.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Feb 2024 08:48:18 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-81930-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=rjwysocki.net); spf=pass (google.com: domain of linux-kernel+bounces-81930-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-81930-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 2BCD21F2BA2E for ; Mon, 26 Feb 2024 16:47:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 303C712CD9E; Mon, 26 Feb 2024 16:47:09 +0000 (UTC) Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2088B12C522; Mon, 26 Feb 2024 16:47:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.96.170.134 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708966026; cv=none; b=UIdR4UDPDFZisBF4Xpnt6SDohDq3YJX5gC2yaxRVTTOU+BJanuXmWPVe+ixCHh3w5gBokziKBfX3NZQcWM1W8rFR6BslHSk9vt77s6EkOFK0hbzvg+T2I+RQkd0VS9xMySmbEynrXDPCk7DNl7AFg3Kbne8sosMh7OyrJkSHAng= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708966026; c=relaxed/simple; bh=80eMbshAOaGrGFUKm7chy0SE9XzQNdY5bar8g8qo9s0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oSOWjCnAxuzn8sZpGi9JWEOgJZ7OMx87+GdbdssUPzHaKmcvhoh2iGUVCgt2LC1MPJVwYTAETbe+gfLVvRKoDGdyIHckJLyOBv94NEqJV//ClRAqcR2UYT4wukVUjGPvPotE0kzFpEejERJ4mbAvNabO2MNILNjlP+zZXWxiDi4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net; spf=pass smtp.mailfrom=rjwysocki.net; arc=none smtp.client-ip=79.96.170.134 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rjwysocki.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rjwysocki.net Received: from localhost (127.0.0.1) (HELO v370.home.net.pl) by /usr/run/smtp (/usr/run/postfix/private/idea_relay_lmtp) via UNIX with SMTP (IdeaSmtpServer 5.4.0) id fcde5ceec8ac2b3d; Mon, 26 Feb 2024 17:46:55 +0100 Received: from kreacher.localnet (unknown [195.136.19.94]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by cloudserver094114.home.pl (Postfix) with ESMTPSA id 884C166A4D4; Mon, 26 Feb 2024 17:46:54 +0100 (CET) From: "Rafael J. Wysocki" To: Linux ACPI , Jonathan Cameron Cc: LKML , Mika Westerberg , "Rafael J. Wysocki" , "Russell King (Oracle)" Subject: [PATCH v2 4/5] ACPI: scan: Rework Device Check and Bus Check notification handling Date: Mon, 26 Feb 2024 17:45:11 +0100 Message-ID: <1958983.PYKUYFuaPT@kreacher> In-Reply-To: <6021126.lOV4Wx5bFT@kreacher> References: <6021126.lOV4Wx5bFT@kreacher> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="UTF-8" X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvledrgedvgdeltdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfjqffogffrnfdpggftiffpkfenuceurghilhhouhhtmecuudehtdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkjghfggfgtgesthfuredttddtjeenucfhrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqeenucggtffrrghtthgvrhhnpeektddvveeijeekveekvdffieffheeitdehkeekfeeiheffkefgledtheelhedvudenucffohhmrghinhepuhgvfhhirdhorhhgnecukfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqedpnhgspghrtghpthhtohepiedprhgtphhtthhopehlihhnuhigqdgrtghpihesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehjohhnrghthhgrnhdrtggrmhgvrhhonheshhhurgifvghirdgtohhmpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepmhhikhgrrdifvghsthgv rhgsvghrgheslhhinhhugidrihhnthgvlhdrtghomhdprhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugiesrghrmhhlihhnuhigrdhorhhgrdhukh X-DCC--Metrics: v370.home.net.pl 1024; Body=6 Fuz1=6 Fuz2=6 From: Rafael J. Wysocki The underlying problem is the handling of the enabled bit in device status (bit 1 of _STA return value) which is required by the ACPI specification to be observed in addition to the present bit (bit 0 of _STA return value) [1], but Linux does not observe it. Since Linux has not looked at that bit for a long time, it is generally risky to start obseving it in all device enumeration cases, especially at the system initialization time, but it can be observed when the kernel receives a Bus Check or Device Check notification indicating a change in device configuration. In those cases, seeing the enabled bit clear may be regarded as an indication that the device at hand should not be used any more. For this reason, rework the handling of Device Check and Bus Check notifications in the ACPI core device enumeration code in the following way: 1. Rename acpi_bus_trim_one() to acpi_scan_check_and_detach() and make it check device status if its second argument is not NULL, in which case it will detach scan handlers or ACPI drivers from devices whose _STA returns the enabled bit clear. 2. Make acpi_scan_device_check() and acpi_scan_bus_check() invoke acpi_scan_check_and_detach() with a non-NULL second argument unconditionally, so scan handlers and ACPI drivers are detached from the target device and its ancestors if their _STA returns the enabled bit clear. Link: https://uefi.org/specs/ACPI/6.5/06_Device_Configuration.html#sta-device-status # [1] Signed-off-by: Rafael J. Wysocki --- v1 -> v2: * Split patch [3/4] from v1 and put changes related to the "enabled" _STA bit into this patch. * Leave the acpi_device_is_present() check in acpi_scan_device_check(), so as to continue walking the bus below the device when it is not enabled (for backwards compatibility). --- drivers/acpi/scan.c | 84 +++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 39 deletions(-) Index: linux-pm/drivers/acpi/scan.c =================================================================== --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -244,11 +244,27 @@ static int acpi_scan_try_to_offline(stru return 0; } -static int acpi_bus_trim_one(struct acpi_device *adev, void *not_used) +static int acpi_scan_check_and_detach(struct acpi_device *adev, void *check) { struct acpi_scan_handler *handler = adev->handler; - acpi_dev_for_each_child_reverse(adev, acpi_bus_trim_one, NULL); + acpi_dev_for_each_child_reverse(adev, acpi_scan_check_and_detach, check); + + if (check) { + acpi_bus_get_status(adev); + /* + * Skip devices that are still there and take the enabled + * flag into account. + */ + if (acpi_device_is_enabled(adev)) + return 0; + + /* Skip device that have not been enumerated. */ + if (!acpi_device_enumerated(adev)) { + dev_dbg(&adev->dev, "Still not enumerated\n"); + return 0; + } + } adev->flags.match_driver = false; if (handler) { @@ -270,6 +286,11 @@ static int acpi_bus_trim_one(struct acpi return 0; } +static void acpi_scan_check_subtree(struct acpi_device *adev) +{ + acpi_scan_check_and_detach(adev, (void *)true); +} + static int acpi_scan_hot_remove(struct acpi_device *device) { acpi_handle handle = device->handle; @@ -315,42 +336,30 @@ static int acpi_scan_hot_remove(struct a return 0; } -static int acpi_scan_device_not_enumerated(struct acpi_device *adev) -{ - if (!acpi_device_enumerated(adev)) { - dev_warn(&adev->dev, "Still not enumerated\n"); - return -EALREADY; - } - acpi_bus_trim(adev); - return 0; -} - static int acpi_scan_device_check(struct acpi_device *adev) { int error; - acpi_bus_get_status(adev); - if (acpi_device_is_present(adev)) { - /* - * This function is only called for device objects for which - * matching scan handlers exist. The only situation in which - * the scan handler is not attached to this device object yet - * is when the device has just appeared (either it wasn't - * present at all before or it was removed and then added - * again). - */ - if (adev->handler) { - dev_dbg(&adev->dev, "Already enumerated\n"); - return 0; - } - error = acpi_bus_scan(adev->handle); - if (error) { - dev_warn(&adev->dev, "Namespace scan failure\n"); - return error; - } - } else { - error = acpi_scan_device_not_enumerated(adev); + acpi_scan_check_subtree(adev); + + if (!acpi_device_is_present(adev)) + return 0; + + /* + * This function is only called for device objects for which matching + * scan handlers exist. The only situation in which the scan handler + * is not attached to this device object yet is when the device has + * just appeared (either it wasn't present at all before or it was + * removed and then added again). + */ + if (adev->handler) { + dev_dbg(&adev->dev, "Already enumerated\n"); + return 0; } + error = acpi_bus_scan(adev->handle); + if (error) + dev_warn(&adev->dev, "Namespace scan failure\n"); + return error; } @@ -359,11 +368,8 @@ static int acpi_scan_bus_check(struct ac struct acpi_scan_handler *handler = adev->handler; int error; - acpi_bus_get_status(adev); - if (!acpi_device_is_present(adev)) { - acpi_scan_device_not_enumerated(adev); - return 0; - } + acpi_scan_check_subtree(adev); + if (handler && handler->hotplug.scan_dependent) return handler->hotplug.scan_dependent(adev); @@ -2586,7 +2592,7 @@ EXPORT_SYMBOL(acpi_bus_scan); */ void acpi_bus_trim(struct acpi_device *adev) { - acpi_bus_trim_one(adev, NULL); + acpi_scan_check_and_detach(adev, NULL); } EXPORT_SYMBOL_GPL(acpi_bus_trim);