From: Greg Kroah-Hartman Date: Mon, 3 Jul 2023 06:06:46 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v5.15.120~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=822be437671ba9cf81747c555b8ff6ffc4a28a20;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: pci-acpi-call-_reg-when-transitioning-d-states.patch pci-acpi-validate-acpi_pci_set_power_state-parameter.patch --- diff --git a/queue-6.1/pci-acpi-call-_reg-when-transitioning-d-states.patch b/queue-6.1/pci-acpi-call-_reg-when-transitioning-d-states.patch new file mode 100644 index 00000000000..ffc61b499d8 --- /dev/null +++ b/queue-6.1/pci-acpi-call-_reg-when-transitioning-d-states.patch @@ -0,0 +1,108 @@ +From 112a7f9c8edbf76f7cb83856a6cb6b60a210b659 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Tue, 20 Jun 2023 09:04:51 -0500 +Subject: PCI/ACPI: Call _REG when transitioning D-states +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Limonciello + +commit 112a7f9c8edbf76f7cb83856a6cb6b60a210b659 upstream. + +ACPI r6.5, sec 6.5.4, describes how AML is unable to access an +OperationRegion unless _REG has been called to connect a handler: + + The OS runs _REG control methods to inform AML code of a change in the + availability of an operation region. When an operation region handler is + unavailable, AML cannot access data fields in that region. (Operation + region writes will be ignored and reads will return indeterminate data.) + +The PCI core does not call _REG at any time, leading to the undefined +behavior mentioned in the spec. + +The spec explains that _REG should be executed to indicate whether a +given region can be accessed: + + Once _REG has been executed for a particular operation region, indicating + that the operation region handler is ready, a control method can access + fields in the operation region. Conversely, control methods must not + access fields in operation regions when _REG method execution has not + indicated that the operation region handler is ready. + +An example included in the spec demonstrates calling _REG when devices are +turned off: "when the host controller or bridge controller is turned off +or disabled, PCI Config Space Operation Regions for child devices are +no longer available. As such, ETH0’s _REG method will be run when it +is turned off and will again be run when PCI1 is turned off." + +It is reported that ASMedia PCIe GPIO controllers fail functional tests +after the system has returning from suspend (S3 or s2idle). This is because +the BIOS checks whether the OSPM has called the _REG method to determine +whether it can interact with the OperationRegion assigned to the device as +part of the other AML called for the device. + +To fix this issue, call acpi_evaluate_reg() when devices are transitioning +to D3cold or D0. + +[bhelgaas: split pci_power_t checking to preliminary patch] +Link: https://uefi.org/specs/ACPI/6.5/06_Device_Configuration.html#reg-region +Link: https://lore.kernel.org/r/20230620140451.21007-1-mario.limonciello@amd.com +Signed-off-by: Mario Limonciello +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci-acpi.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c +index bf545f719182..a05350a4e49c 100644 +--- a/drivers/pci/pci-acpi.c ++++ b/drivers/pci/pci-acpi.c +@@ -1043,6 +1043,16 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev) + return false; + } + ++static void acpi_pci_config_space_access(struct pci_dev *dev, bool enable) ++{ ++ int val = enable ? ACPI_REG_CONNECT : ACPI_REG_DISCONNECT; ++ int ret = acpi_evaluate_reg(ACPI_HANDLE(&dev->dev), ++ ACPI_ADR_SPACE_PCI_CONFIG, val); ++ if (ret) ++ pci_dbg(dev, "ACPI _REG %s evaluation failed (%d)\n", ++ enable ? "connect" : "disconnect", ret); ++} ++ + int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) + { + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); +@@ -1074,6 +1084,9 @@ int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) + if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == + PM_QOS_FLAGS_ALL) + return -EBUSY; ++ ++ /* Notify AML lack of PCI config space availability */ ++ acpi_pci_config_space_access(dev, false); + } + + error = acpi_device_set_power(adev, state_conv[state]); +@@ -1083,6 +1096,15 @@ int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) + pci_dbg(dev, "power state changed by ACPI to %s\n", + acpi_power_state_string(adev->power.state)); + ++ /* ++ * Notify AML of PCI config space availability. Config space is ++ * accessible in all states except D3cold; the only transitions ++ * that change availability are transitions to D3cold and from ++ * D3cold to D0. ++ */ ++ if (state == PCI_D0) ++ acpi_pci_config_space_access(dev, true); ++ + return 0; + } + +-- +2.41.0 + diff --git a/queue-6.1/pci-acpi-validate-acpi_pci_set_power_state-parameter.patch b/queue-6.1/pci-acpi-validate-acpi_pci_set_power_state-parameter.patch new file mode 100644 index 00000000000..bb8f5be5035 --- /dev/null +++ b/queue-6.1/pci-acpi-validate-acpi_pci_set_power_state-parameter.patch @@ -0,0 +1,82 @@ +From 5557b62634abbd55bab7b154ce4bca348ad7f96f Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Wed, 21 Jun 2023 16:36:12 -0500 +Subject: PCI/ACPI: Validate acpi_pci_set_power_state() parameter + +From: Bjorn Helgaas + +commit 5557b62634abbd55bab7b154ce4bca348ad7f96f upstream. + +Previously acpi_pci_set_power_state() assumed the requested power state was +valid (PCI_D0 ... PCI_D3cold). If a caller supplied something else, we +could index outside the state_conv[] array and pass junk to +acpi_device_set_power(). + +Validate the pci_power_t parameter and return -EINVAL if it's invalid. + +Link: https://lore.kernel.org/r/20230621222857.GA122930@bhelgaas +Signed-off-by: Bjorn Helgaas +Reviewed-by: Mario Limonciello +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci-acpi.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c +index 052a611081ec..bf545f719182 100644 +--- a/drivers/pci/pci-acpi.c ++++ b/drivers/pci/pci-acpi.c +@@ -1053,32 +1053,37 @@ int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) + [PCI_D3hot] = ACPI_STATE_D3_HOT, + [PCI_D3cold] = ACPI_STATE_D3_COLD, + }; +- int error = -EINVAL; ++ int error; + + /* If the ACPI device has _EJ0, ignore the device */ + if (!adev || acpi_has_method(adev->handle, "_EJ0")) + return -ENODEV; + + switch (state) { +- case PCI_D3cold: +- if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == +- PM_QOS_FLAGS_ALL) { +- error = -EBUSY; +- break; +- } +- fallthrough; + case PCI_D0: + case PCI_D1: + case PCI_D2: + case PCI_D3hot: +- error = acpi_device_set_power(adev, state_conv[state]); ++ case PCI_D3cold: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (state == PCI_D3cold) { ++ if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == ++ PM_QOS_FLAGS_ALL) ++ return -EBUSY; + } + +- if (!error) +- pci_dbg(dev, "power state changed by ACPI to %s\n", +- acpi_power_state_string(adev->power.state)); ++ error = acpi_device_set_power(adev, state_conv[state]); ++ if (error) ++ return error; ++ ++ pci_dbg(dev, "power state changed by ACPI to %s\n", ++ acpi_power_state_string(adev->power.state)); + +- return error; ++ return 0; + } + + pci_power_t acpi_pci_get_power_state(struct pci_dev *dev) +-- +2.41.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 023b4ce4175..d92964c17b7 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -1,3 +1,5 @@ xtensa-fix-lock_mm_and_find_vma-in-case-vma-not-found.patch drm-amd-display-remove-optimization-for-vrr-updates.patch drm-amd-display-do-not-update-drr-while-bw-optimizations-pending.patch +pci-acpi-validate-acpi_pci_set_power_state-parameter.patch +pci-acpi-call-_reg-when-transitioning-d-states.patch