[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180913131843.308288149@linuxfoundation.org>
Date: Thu, 13 Sep 2018 15:29:53 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Heiko Stuebner <heiko@...ech.de>,
Marc Zyngier <marc.zyngier@....com>,
Olof Johansson <olof@...om.net>,
Sasha Levin <alexander.levin@...rosoft.com>
Subject: [PATCH 4.18 044/197] iommu/rockchip: Handle errors returned from PM framework
4.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <marc.zyngier@....com>
[ Upstream commit 3fc7c5c0cff3150e471f5fd12f59971c6d2c6513 ]
pm_runtime_get_if_in_use can fail: either PM has been disabled
altogether (-EINVAL), or the device hasn't been enabled yet (0).
Sadly, the Rockchip IOMMU driver tends to conflate the two things
by considering a non-zero return value as successful.
This has the consequence of hiding other bugs, so let's handle this
case throughout the driver, with a WARN_ON_ONCE so that we can try
and work out what happened.
Fixes: 0f181d3cf7d98 ("iommu/rockchip: Add runtime PM support")
Reviewed-by: Heiko Stuebner <heiko@...ech.de>
Signed-off-by: Marc Zyngier <marc.zyngier@....com>
Signed-off-by: Olof Johansson <olof@...om.net>
Signed-off-by: Sasha Levin <alexander.levin@...rosoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/iommu/rockchip-iommu.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -521,10 +521,11 @@ static irqreturn_t rk_iommu_irq(int irq,
u32 int_status;
dma_addr_t iova;
irqreturn_t ret = IRQ_NONE;
- int i;
+ int i, err;
- if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
- return 0;
+ err = pm_runtime_get_if_in_use(iommu->dev);
+ if (WARN_ON_ONCE(err <= 0))
+ return ret;
if (WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks)))
goto out;
@@ -620,11 +621,15 @@ static void rk_iommu_zap_iova(struct rk_
spin_lock_irqsave(&rk_domain->iommus_lock, flags);
list_for_each(pos, &rk_domain->iommus) {
struct rk_iommu *iommu;
+ int ret;
iommu = list_entry(pos, struct rk_iommu, node);
/* Only zap TLBs of IOMMUs that are powered on. */
- if (pm_runtime_get_if_in_use(iommu->dev)) {
+ ret = pm_runtime_get_if_in_use(iommu->dev);
+ if (WARN_ON_ONCE(ret < 0))
+ continue;
+ if (ret) {
WARN_ON(clk_bulk_enable(iommu->num_clocks,
iommu->clocks));
rk_iommu_zap_lines(iommu, iova, size);
@@ -891,6 +896,7 @@ static void rk_iommu_detach_device(struc
struct rk_iommu *iommu;
struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
+ int ret;
/* Allow 'virtual devices' (eg drm) to detach from domain */
iommu = rk_iommu_from_dev(dev);
@@ -909,7 +915,9 @@ static void rk_iommu_detach_device(struc
list_del_init(&iommu->node);
spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
- if (pm_runtime_get_if_in_use(iommu->dev)) {
+ ret = pm_runtime_get_if_in_use(iommu->dev);
+ WARN_ON_ONCE(ret < 0);
+ if (ret > 0) {
rk_iommu_disable(iommu);
pm_runtime_put(iommu->dev);
}
@@ -946,7 +954,8 @@ static int rk_iommu_attach_device(struct
list_add_tail(&iommu->node, &rk_domain->iommus);
spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
- if (!pm_runtime_get_if_in_use(iommu->dev))
+ ret = pm_runtime_get_if_in_use(iommu->dev);
+ if (!ret || WARN_ON_ONCE(ret < 0))
return 0;
ret = rk_iommu_enable(iommu);
Powered by blists - more mailing lists