Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2956126imm; Fri, 24 Aug 2018 08:09:05 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZfstMES67X9l/cy5xFkUO6zIelzDPGhmfbGabWt4Ru7inUAcizVjr+MWL0a7g26reoN1uS X-Received: by 2002:a17:902:850c:: with SMTP id bj12-v6mr2139534plb.330.1535123345549; Fri, 24 Aug 2018 08:09:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535123345; cv=none; d=google.com; s=arc-20160816; b=QPua3Gu21JFFGTFQcMkTyrjpOhmL+Vkl1EIUhMsKzsQ0Gv1dJC48mseDqp0hky7FPb Gr0tckz3/Qpjcb4ZgxdqPLfa888jWKzdmkf5BoOHe7cwXV8qfVQ60db9mYmLVappDVPs 1SM1q2dhN5ynTi7o6kYKCnBXdz20VfQFPCpDVvkWUXcQ/zvVbdHNOYDjq6Tc4Cup6GNq frvVpv+TSucqTzIHLYXrys+pBdChV5VVc1KwLxhLuaDFtiDtbHmsHqXGJhJXtS/k0o6L GyNpHk8YH2aunCUeTiHKwfFKYjxEFO6wwwCg/hOlQVJw1xgv5u+ficj/payTD4ezVIfM cFvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=TCchN0Or/8U1Peei3BE8ObAiwF//GO8gqI5XQl4NbrQ=; b=KsTbdrVwaBbvV8jeh23v+tkejTObzbcselfeb+YbN7nz5QTC40/PzYTNOZAVoXxFzr LBVNC2SL0YGuIGcS9b6ZYDXdi4aVwqfwx4euRDzHbHk9H60yZYIPc2SO2yDj/gmiI5/r jNPY8YHBaxxDN1iBkNMndcK91Nzk4oYXbdy090zaxjcqBIc7LLQrBTjpJUAHHJm6TbpR ex0n8GacFvaAK1DszePPmA9DnajS0ZvtRboSdshHczPk3RcDnICn/rmhL9dkayiYB69B F2aPnRU18ION5SRza12+Kmj06/kFjmwhCl72QVqWcX8Pv1L4goYqG+O8q8ZjDLsMpkCt UfCQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f187-v6si5224212pfg.122.2018.08.24.08.08.50; Fri, 24 Aug 2018 08:09:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727968AbeHXSma (ORCPT + 99 others); Fri, 24 Aug 2018 14:42:30 -0400 Received: from foss.arm.com ([217.140.101.70]:60068 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726264AbeHXSm3 (ORCPT ); Fri, 24 Aug 2018 14:42:29 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 15E071682; Fri, 24 Aug 2018 08:07:26 -0700 (PDT) Received: from approximate.Emea.Arm.com (approximate.emea.arm.com [10.4.13.119]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 91CA03F5BC; Fri, 24 Aug 2018 08:07:24 -0700 (PDT) From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org Cc: Joerg Roedel , Heiko Stuebner , Jeffy Chen , arm@kernel.org Subject: [PATCH v2 3/4] iommu/rockchip: Handle errors returned from PM framework Date: Fri, 24 Aug 2018 16:06:36 +0100 Message-Id: <20180824150637.15316-4-marc.zyngier@arm.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180824150637.15316-1-marc.zyngier@arm.com> References: <20180824150637.15316-1-marc.zyngier@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Signed-off-by: Marc Zyngier --- drivers/iommu/rockchip-iommu.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 054cd2c8e9c8..4e0f9b61cd7f 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -521,10 +521,11 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id) 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_iommu_domain *rk_domain, 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(struct iommu_domain *domain, 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(struct iommu_domain *domain, 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 iommu_domain *domain, 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); -- 2.18.0