From patchwork Fri Mar 30 15:52:38 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: 7550 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 0745523E29 for ; Fri, 30 Mar 2012 15:52:50 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 9E328A180D0 for ; Fri, 30 Mar 2012 15:52:49 +0000 (UTC) Received: by iage36 with SMTP id e36so1586612iag.11 for ; Fri, 30 Mar 2012 08:52:49 -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 :mime-version:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=fNGdB5kG8RhetniOfoovIxBsN7Gph1tUC2BDqamtc/Q=; b=d8LR6GZBzVNcURbQw1tgBxyW/tYyel48LYyPigGx4/iT856xtCmjLDhTJxWqWERhv+ sACrNUtkjdiAx+G8uF431IoBRVQH78f3RnhmsegP07zIz8BlbLVk3GPna4H2CV/WIJ/z se/uoOe1/3LLxWqOIrTm8YVOXY3NUZ0BzTrjuZo9lW1rri9QR7z0tiSBl720361xX//l zJTtNA5cc18XsI8jBVAIoIx0Sy74cEdhc0hqrQjmWXYFpRrVB90zQq6jGrHPrnRnr1BE AvhH90iDskmrY85/MnFxwtPMeETQRy0552IUX+AOUpr1t+AnTNnoI6vtr5A30c1GYXyr jAHw== Received: by 10.50.46.195 with SMTP id x3mr1778921igm.54.1333122768916; Fri, 30 Mar 2012 08:52:48 -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.5.205 with SMTP id 13csp2566ibw; Fri, 30 Mar 2012 08:52:48 -0700 (PDT) Received: by 10.60.13.37 with SMTP id e5mr3611939oec.70.1333122768411; Fri, 30 Mar 2012 08:52:48 -0700 (PDT) Received: from mail-ob0-f178.google.com (mail-ob0-f178.google.com [209.85.214.178]) by mx.google.com with ESMTPS id v6si6221334obc.28.2012.03.30.08.52.48 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 30 Mar 2012 08:52:48 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.214.178 is neither permitted nor denied by best guess record for domain of omar.luna@linaro.org) client-ip=209.85.214.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.214.178 is neither permitted nor denied by best guess record for domain of omar.luna@linaro.org) smtp.mail=omar.luna@linaro.org Received: by obbtb18 with SMTP id tb18so1489503obb.37 for ; Fri, 30 Mar 2012 08:52:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.15.102 with SMTP id w6mr3618153obc.6.1333122768140; Fri, 30 Mar 2012 08:52:48 -0700 (PDT) Received: from localhost.localdomain (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id o9sm9543050obd.21.2012.03.30.08.52.46 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 30 Mar 2012 08:52:47 -0700 (PDT) From: Omar Ramirez Luna To: Omar Ramirez Luna Cc: patches@linaro.org, linaro-dev@lists.linaro.org Subject: [PATCH] iommu: OMAP: device detach on domain destroy Date: Fri, 30 Mar 2012 10:52:38 -0500 Message-Id: <1333122758-3594-1-git-send-email-omar.luna@linaro.org> X-Mailer: git-send-email 1.7.4.1 X-Gm-Message-State: ALoCoQm8QxhKNZcjiSLxOzc1fOvOOAkSGnxpRss6j87ZElr4AuiZrSRqqG8Pz/gC0oG7Wrz6+G8Q '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 --- 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 821062a..e32bd15 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; }; @@ -1074,6 +1076,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; /* temporary workaround */ @@ -1084,19 +1087,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); @@ -1104,11 +1104,19 @@ 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; /* temporary workaround */ clk_disable(oiommu->clk); +} -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); } @@ -1147,13 +1155,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); }