From nobody Mon Feb 9 14:17:12 2026 Received: from mail-dl1-f50.google.com (mail-dl1-f50.google.com [74.125.82.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 06C333314CD for ; Thu, 22 Jan 2026 17:49:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769104163; cv=none; b=UBEFFg+4fT93IVDSlH3BymsuJDCRqZYdWByGRKJDdwcayFsM2tqO+c4sA+mKBDFQhvlJuiUPW9sV1Bjx9D/NuznoHlec/X54HbhdxsuPVvuTZL8OHPfMbwQsG3GJUrQGdMi+d4S7h3Zdnwms38qbly7FjRT/06J4ek4OME49JKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769104163; c=relaxed/simple; bh=PPSbiTfVEGExWa8EuuY6a6EN8vMNdxghuY659RvCiCI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=XQ6hxCG1ywGMcwXOrHSIPMpnGjA1bWFLIg+VWBpq5/AqJbhLXld7cfOCCrGgj5St/8IweUUCV5f0G3QMvhA8N9k5vLWshvvXcz1HGSIEJw3A1HA45Yn4I8r+2kay/v8BCuKu8B3/KWifBqRJCskQ8QwHRu05gSrg3bisUuujydQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=OQXnEp90; arc=none smtp.client-ip=74.125.82.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="OQXnEp90" Received: by mail-dl1-f50.google.com with SMTP id a92af1059eb24-121bf277922so2268285c88.0 for ; Thu, 22 Jan 2026 09:49:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1769104145; x=1769708945; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=E3WbKmVrq7sm/5pwwqVvAut+xxxGLtgFYQpauTPoz70=; b=OQXnEp90kPXwTCa2gO7xkl/5bNSZs9gW56JSbAhBCXgNyrTa8fEUdjmcwGvXh5yrgl CpJrbsh94R0REe5TcF1qA/S7dc8DicsXjOVUCGQiUlIzsW5Gga0fZxjmeoG3yBUteyYN WL+JdjWSDsUgn4Viqg0ISIm+ihWz+B9i+9I0A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769104145; x=1769708945; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=E3WbKmVrq7sm/5pwwqVvAut+xxxGLtgFYQpauTPoz70=; b=IY358gHAjLvgyqCTu3PPhpy4hyQ5I7zvEP6pp8xXP0AjQ0apfSusZoOwIpHEASRwmS azYcQOZTuq7Rfv3Iaf/agyQ1YQXyvVNtpA9Tv4p8RQZbI4Rgp3nVaC/2kWE0KdVvZRMR XqdB/jMMhLn9aworVUMhMY2yTy+IqbOrYsdY4IB8KfbRt9F9j9yxMPYeUF2kV1wNAVJx 8A0tbHbfL6BKoWY/lQV6uW7aeztO1kBkbOhz4hOm8Y/89L+Xgix5SWjdkzN/VGig0wSK 2LplrUp40b3BO1Guxlni/6unZHjmcYKFY90OBCuMNkYojRrB/zbM7aNJZ0XO6gXsjcEG Jqwg== X-Gm-Message-State: AOJu0Yw96lZqpcLQ2Q5Fltujbza2voqxxdb8h5Zk6nI28hGqPHSIjlar nAFIEhA+GgRBkpLR7VJa6NmHQXev0+A9cXkYoF7CchnznVk4ADiFcjCz2A2a3fiYwA== X-Gm-Gg: AZuq6aJDCJQBAGAaaqpW0F+qMY9OcyiQNvJhVDK8nXQ+WHfa9um9UNiv9a7yhOCbzkY ceSOtOpfEMyK0q4SbsoHERncFoRE2y/T+PMW6saxZNjgSPFNisMQjZLixAPpMYejHDO/VHSGc3x yW3wJ6O9DasZnGY8hTc2qxFRn1KZhSrlWselTtuubwOiIVOdcf3BpttyafJtkhlgI8cOPbl/n63 ou6N2VVxP2y7HIsUfF9vXGxaIZFs/iT7FXPRrbLEP5tMnxjPh3rszc8idZWyMiKl9pkp73+dhTB bM7fDjm3K1SQdGO1/ZZkUp4DAb2x601zqQKtoUFG+a5VZ5tlHy5JI0OJ2/HJ+Cd+U1Sr+4qxpkq tXZZSF/19eBRZxlhg/tQFF3lqtmkE2CiByATH2B81kUfngv/0r8WPX+s9sO+rs8W01Cea74u/2b 9eaJBpbf1bvqSkChoAwOBsTb00HTx5s01EF/ukhYr4LIvGP2rg9Q== X-Received: by 2002:a05:7022:126:b0:123:2d38:928e with SMTP id a92af1059eb24-1247dc082b1mr61654c88.35.1769104144779; Thu, 22 Jan 2026 09:49:04 -0800 (PST) Received: from localhost ([2a00:79e0:2e7c:8:f995:553f:5ab5:f684]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-1247d9981a4sm164342c88.9.2026.01.22.09.49.03 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 22 Jan 2026 09:49:04 -0800 (PST) From: Brian Norris To: Bjorn Helgaas Cc: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Lukas Wunner , linux-pm@vger.kernel.org, "Rafael J . Wysocki" , Marek Szyprowski , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Brian Norris Subject: [PATCH v5] PCI/PM: Prevent runtime suspend until devices are fully initialized Date: Thu, 22 Jan 2026 09:48:15 -0800 Message-ID: <20260122094815.v5.1.I60a53c170a8596661883bd2b4ef475155c7aa72b@changeid> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previously, it was possible for a PCI device to be runtime-suspended before it was fully initialized. When that happened, the suspend process could save invalid device state, for example, before BAR assignment. Restoring the invalid state during resume may leave the device non-functional. Prevent runtime suspend for PCI devices until they are fully initialized by deferring pm_runtime_enable(). More details on how exactly this may occur: 1. PCI device is created by pci_scan_slot() or similar 2. As part of pci_scan_slot(), pci_pm_init() puts the device in D0 and prevents runtime suspend prevented via pm_runtime_forbid() 3. pci_device_add() adds the underlying 'struct device' via device_add(), which means user space can allow runtime suspend, e.g., echo auto > /sys/bus/pci/devices/.../power/control 4. PCI device receives BAR configuration (pci_assign_unassigned_bus_resources(), etc.) 5. pci_bus_add_device() applies final fixups, saves device state, and tries to attach a driver The device may potentially be suspended between #3 and #5, so this is racy with user space (udev or similar). Many PCI devices are enumerated at subsys_initcall time and so will not race with user space, but devices created later by hotplug or modular pwrctrl or host controller drivers are susceptible to this race. More runtime PM details at the first Link: below. Signed-off-by: Brian Norris Tested-by: Marek Szyprowski Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20251016155335.1.I60a53c170a8596661883bd2= b4ef475155c7aa72b@changeid/ Link: https://lore.kernel.org/all/0e35a4e1-894a-47c1-9528-fc5ffbafd9e2@sams= ung.com/ Link: https://lore.kernel.org/all/20251016155335.1.I60a53c170a8596661883bd2= b4ef475155c7aa72b@changeid/ Cc: --- Changes in v5: * Put pm_runtime_set_active() back where it was, to ensure our parent can't suspend before we're really ready. (See bug report in 2nd "Link:") * Add comments * Update commit description with Bjorn's rewrite * Add Marek's Tested-by Changes in v4: * Move pm_runtime_set_active() too Changes in v3: * Add Link to initial discussion * Add Rafael's Reviewed-by * Add lengthier footnotes about forbid vs allow vs sysfs Changes in v2: * Update CC list * Rework problem description * Update solution: defer pm_runtime_enable(), instead of trying to get()/put() drivers/pci/bus.c | 7 +++++++ drivers/pci/pci.c | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 4383a36fd6ca..90954f81962b 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include =20 @@ -379,6 +380,12 @@ void pci_bus_add_device(struct pci_dev *dev) put_device(&pdev->dev); } =20 + /* + * Enable runtime PM (and potentially suspend) only after we've fully + * configured the PCI state. + */ + pm_runtime_enable(&dev->dev); + if (!dn || of_device_is_available(dn)) pci_dev_allow_binding(dev); =20 diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 13dbb405dc31..07b0d029aa51 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3196,8 +3196,11 @@ void pci_pm_init(struct pci_dev *dev) poweron: pci_pm_power_up_and_verify_state(dev); pm_runtime_forbid(&dev->dev); + /* + * Mark ourselves active now, to prevent our parent from suspending + * while we finish configuring the PCI device. + */ pm_runtime_set_active(&dev->dev); - pm_runtime_enable(&dev->dev); } =20 static unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop) --=20 2.52.0.457.g6b5491de43-goog