From patchwork Wed Apr 18 18:09:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Ramirez Luna X-Patchwork-Id: 7937 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 25A3623E1D for ; Wed, 18 Apr 2012 18:09:53 +0000 (UTC) Received: from mail-yw0-f52.google.com (mail-yw0-f52.google.com [209.85.213.52]) by fiordland.canonical.com (Postfix) with ESMTP id AEF40A18342 for ; Wed, 18 Apr 2012 18:09:52 +0000 (UTC) Received: by yhpp61 with SMTP id p61so4808074yhp.11 for ; Wed, 18 Apr 2012 11:09:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-gm-message-state; bh=Gto7kg9mjZqJ4ijksJ1mu7hpW34vs9Lck7Ky2uURc+g=; b=Zn4jNu6Ucl6yw/tTr7sld8yrCevRI4qEjUyaK8ecbUVdJDmtwOmZ/ykEbgMD8Q+AvS yiVqA7K3BgGLDeIkvPwht3ORWVPz+EaqOhecUHDlZlC88i5LMJcC3DrknVePaJ5Bcq0t CH1ogn+NiS5bNEZPW0NXLvFstbwnwH10Huq3wxxHAz4TAoRKIchp9shfUc7qqVS1VjZr jCtv6JAYaZazM9qRrsLgH/PFDuw/tt8v44WEhfIIcY6j95ACJ8QQsPTex2+NdVOxPtGx wbqgJ0K/tRmQifQdTro3874L60VPssr/M0MXGekr9cuduA6DOfcMFJrZOdBDo00656uh +bEA== Received: by 10.50.196.230 with SMTP id ip6mr2959311igc.49.1334772591978; Wed, 18 Apr 2012 11:09:51 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.137.198 with SMTP id x6csp236636ibt; Wed, 18 Apr 2012 11:09:51 -0700 (PDT) Received: by 10.236.174.35 with SMTP id w23mr3259662yhl.35.1334772590198; Wed, 18 Apr 2012 11:09:50 -0700 (PDT) Received: from mail-yw0-f50.google.com (mail-yw0-f50.google.com [209.85.213.50]) by mx.google.com with ESMTPS id f22si11499259yhe.142.2012.04.18.11.09.50 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Apr 2012 11:09:50 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.213.50 is neither permitted nor denied by best guess record for domain of omar.luna@linaro.org) client-ip=209.85.213.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.213.50 is neither permitted nor denied by best guess record for domain of omar.luna@linaro.org) smtp.mail=omar.luna@linaro.org Received: by yhjj63 with SMTP id j63so4510060yhj.37 for ; Wed, 18 Apr 2012 11:09:50 -0700 (PDT) Received: by 10.60.25.162 with SMTP id d2mr4620890oeg.30.1334772589818; Wed, 18 Apr 2012 11:09:49 -0700 (PDT) Received: from localhost.localdomain (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id tx2sm27658738obb.8.2012.04.18.11.09.47 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Apr 2012 11:09:48 -0700 (PDT) From: Omar Ramirez Luna To: Joerg Roedel Cc: Ohad Ben-Cohen , Tony Lindgren , Laurent Pinchart , iommu@lists.linux-foundation.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, patches@linaro.org, linaro-dev@lists.linaro.org, Omar Ramirez Luna Subject: [PATCH v2] iommu: OMAP: device detach on domain destroy Date: Wed, 18 Apr 2012 13:09:41 -0500 Message-Id: <1334772581-32015-1-git-send-email-omar.luna@linaro.org> X-Mailer: git-send-email 1.7.4.1 X-Gm-Message-State: ALoCoQkG79YOoyZDuEXRokIwsvCgFXzHYFTxi6V7VL4nzT/ldcJON+G6mrqZzxUeurXBEtQW0D6x 'domain_destroy with devices attached' case isn't yet handled, instead code assumes that the device was already detached. If the domain is destroyed the hardware still has access to invalid pointers to its page table and internal iommu object. In order to detach the users we need to track devices using the iommu, current use cases only have one user of iommu per instance. When required this can evolve to a list with the devices using the iommu_dev. Reported-by: Joerg Roedel Reviewed-by: Ohad Ben-Cohen Signed-off-by: Omar Ramirez Luna --- v2: rebased onto v3.4-rc2 drivers/iommu/omap-iommu.c | 32 +++++++++++++++++++++++--------- 1 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 6899dcd..e70ee2b 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -41,11 +41,13 @@ * @pgtable: the page table * @iommu_dev: an omap iommu device attached to this domain. only a single * iommu device can be attached for now. + * @dev: Device using this domain. * @lock: domain lock, should be taken when attaching/detaching */ struct omap_iommu_domain { u32 *pgtable; struct omap_iommu *iommu_dev; + struct device *dev; spinlock_t lock; }; @@ -1081,6 +1083,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) } omap_domain->iommu_dev = arch_data->iommu_dev = oiommu; + omap_domain->dev = dev; oiommu->domain = domain; out: @@ -1088,19 +1091,16 @@ out: return ret; } -static void omap_iommu_detach_dev(struct iommu_domain *domain, - struct device *dev) +static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain, + struct device *dev) { - struct omap_iommu_domain *omap_domain = domain->priv; - struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; struct omap_iommu *oiommu = dev_to_omap_iommu(dev); - - spin_lock(&omap_domain->lock); + struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; /* only a single device is supported per domain for now */ if (omap_domain->iommu_dev != oiommu) { dev_err(dev, "invalid iommu device\n"); - goto out; + return; } iopgtable_clear_entry_all(oiommu); @@ -1108,8 +1108,16 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain, omap_iommu_detach(oiommu); omap_domain->iommu_dev = arch_data->iommu_dev = NULL; + omap_domain->dev = NULL; +} -out: +static void omap_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct omap_iommu_domain *omap_domain = domain->priv; + + spin_lock(&omap_domain->lock); + _omap_iommu_detach_dev(omap_domain, dev); spin_unlock(&omap_domain->lock); } @@ -1148,13 +1156,19 @@ out: return -ENOMEM; } -/* assume device was already detached */ static void omap_iommu_domain_destroy(struct iommu_domain *domain) { struct omap_iommu_domain *omap_domain = domain->priv; domain->priv = NULL; + /* + * An iommu device is still attached + * (currently, only one device can be attached) ? + */ + if (omap_domain->iommu_dev) + _omap_iommu_detach_dev(omap_domain, omap_domain->dev); + kfree(omap_domain->pgtable); kfree(omap_domain); }