From patchwork Tue May 8 18:16:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 910409 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ewe/5Tut"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40gST15379z9s2t for ; Wed, 9 May 2018 04:20:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755845AbeEHSTw (ORCPT ); Tue, 8 May 2018 14:19:52 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:41871 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933187AbeEHSRf (ORCPT ); Tue, 8 May 2018 14:17:35 -0400 Received: by mail-lf0-f67.google.com with SMTP id o123-v6so47224806lfe.8; Tue, 08 May 2018 11:17:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CXm8o+/9th4zdaMFtWmOrS/Euw3pyh/LZtMwDKlONX4=; b=Ewe/5TutVt3IQJG+CUOxXYvcgjVxfa650ilSGaVL3dO+Te9OUA5vUl/mSxW7cWuf4d kijmtWZbjpy5Hhnp38YjRlp4PUZT49g02WS/OPGrnpjo8W0baf/1ENxlC6PZivv1wtQw QlCJeF28f89GyyRQJ2sK95Kk3xjtim1BxZ9kjy7oynCGRds9htKW311PLiY7lD0x1DPp 13OZVC+KKp/1igIjXu4vEtyKNj1ii6mzteCWL3dKKgwtmI0mXR7snyhXtUQf+/SSp5LE sjGY/2/b7s2DNANukmfMxqGmhwvHv3FxVmIfcFIImNwuCqPkQFn+pPifDot8iXlP4UoJ qg0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CXm8o+/9th4zdaMFtWmOrS/Euw3pyh/LZtMwDKlONX4=; b=OINzsNeCJyQjxkI7fCAPJIRrVUU6adDCQjgbxcm30tN6uZs0IMt+0dxJGdBpUSCkgd 8gHiXx1XwyQTKFpxv/bhbIDWH4czTTXwl2nEd6Mxq4F1X0TPQMCmxU+q6CFlD7xzOyZs +dXMQs0Z+ZePGFnAJ/1HzyIZQu/mV5yM2Co5lQaXS2QcpRnRCAPcecs7MPDhh7Vm8XEo XevKhZnD8vhpO49oNsdsHyEi3XKBqUC63rN7GN2G3tFnuVyOTWkMD+S/Xs5v8eSJvgXX 3YlkiGszLrdVgO/Y6tQ6pZmNfeZGy1CK74CbOZrhFzT5em26Q6xvi5S/s/vWNdN+VV7d wHrw== X-Gm-Message-State: ALQs6tBbJ3u+nR9pvE/Id+gxCYr4ICnxFJA1FnKS+QeqaQugst3+9Huo p7TzsrQETo+IdFrCOg05qLQ= X-Google-Smtp-Source: AB8JxZrxFV1P9yz6p45rRphChV2+Tbzwx3Y1sVpbEHI/Zsn7zLN0SsP+Gb3ltM6G4jwXFyjB6EJ6Pw== X-Received: by 2002:a2e:9a06:: with SMTP id o6-v6mr19907164lji.17.1525803454019; Tue, 08 May 2018 11:17:34 -0700 (PDT) Received: from localhost.localdomain ([109.252.91.130]) by smtp.gmail.com with ESMTPSA id f64-v6sm2338699lfg.63.2018.05.08.11.17.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 May 2018 11:17:33 -0700 (PDT) From: Dmitry Osipenko To: Joerg Roedel , Thierry Reding , Jonathan Hunter Cc: linux-tegra@vger.kernel.org, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 7/9] iommu/tegra: gart: Provide single domain and group for all devices Date: Tue, 8 May 2018 21:16:58 +0300 Message-Id: <20180508181700.5169-8-digetx@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180508181700.5169-1-digetx@gmail.com> References: <20180508181700.5169-1-digetx@gmail.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org GART aperture is shared by all devices, hence there is a single IOMMU domain and group shared by these devices. Allocation of a group per device only wastes resources and allowance of having more than one domain is simply wrong because IOMMU mappings made by the users of "different" domains will stomp on each other. Signed-off-by: Dmitry Osipenko --- drivers/iommu/tegra-gart.c | 107 +++++++++---------------------------- 1 file changed, 24 insertions(+), 83 deletions(-) diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index 5b2d27620350..ebc105c201bd 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -44,22 +43,17 @@ #define GART_PAGE_MASK \ (~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID) -struct gart_client { - struct device *dev; - struct list_head list; -}; - struct gart_device { void __iomem *regs; u32 *savedata; u32 page_count; /* total remappable size */ dma_addr_t iovmm_base; /* offset to vmm_area */ spinlock_t pte_lock; /* for pagetable */ - struct list_head client; - spinlock_t client_lock; /* for client list */ struct device *dev; struct iommu_device iommu; /* IOMMU Core handle */ + struct iommu_group *group; /* Common IOMMU group */ + struct gart_domain *domain; /* Unique IOMMU domain */ struct tegra_mc_gart_handle mc_gart_handle; }; @@ -169,81 +163,31 @@ static inline bool gart_iova_range_valid(struct gart_device *gart, static int gart_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) { - struct gart_domain *gart_domain = to_gart_domain(domain); - struct gart_device *gart = gart_domain->gart; - struct gart_client *client, *c; - int err = 0; - - client = devm_kzalloc(gart->dev, sizeof(*c), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->dev = dev; - - spin_lock(&gart->client_lock); - list_for_each_entry(c, &gart->client, list) { - if (c->dev == dev) { - dev_err(gart->dev, - "%s is already attached\n", dev_name(dev)); - err = -EINVAL; - goto fail; - } - } - list_add(&client->list, &gart->client); - spin_unlock(&gart->client_lock); - dev_dbg(gart->dev, "Attached %s\n", dev_name(dev)); return 0; - -fail: - devm_kfree(gart->dev, client); - spin_unlock(&gart->client_lock); - return err; } static void gart_iommu_detach_dev(struct iommu_domain *domain, struct device *dev) { - struct gart_domain *gart_domain = to_gart_domain(domain); - struct gart_device *gart = gart_domain->gart; - struct gart_client *c; - - spin_lock(&gart->client_lock); - - list_for_each_entry(c, &gart->client, list) { - if (c->dev == dev) { - list_del(&c->list); - devm_kfree(gart->dev, c); - dev_dbg(gart->dev, "Detached %s\n", dev_name(dev)); - goto out; - } - } - dev_err(gart->dev, "Couldn't find\n"); -out: - spin_unlock(&gart->client_lock); } static struct iommu_domain *gart_iommu_domain_alloc(unsigned type) { - struct gart_domain *gart_domain; - struct gart_device *gart; - - if (type != IOMMU_DOMAIN_UNMANAGED) - return NULL; + struct gart_device *gart = gart_handle; - gart = gart_handle; - if (!gart) + if (type != IOMMU_DOMAIN_UNMANAGED || gart->domain) return NULL; - gart_domain = kzalloc(sizeof(*gart_domain), GFP_KERNEL); - if (!gart_domain) - return NULL; - - gart_domain->gart = gart; - gart_domain->domain.geometry.aperture_start = gart->iovmm_base; - gart_domain->domain.geometry.aperture_end = gart->iovmm_base + + gart->domain = kzalloc(sizeof(*gart->domain), GFP_KERNEL); + if (gart->domain) { + gart->domain->domain.geometry.aperture_start = gart->iovmm_base; + gart->domain->domain.geometry.aperture_end = gart->iovmm_base + gart->page_count * GART_PAGE_SIZE - 1; - gart_domain->domain.geometry.force_aperture = true; + gart->domain->domain.geometry.force_aperture = true; + gart->domain->gart = gart; + } - return &gart_domain->domain; + return &gart->domain->domain; } static void gart_iommu_domain_free(struct iommu_domain *domain) @@ -251,18 +195,7 @@ static void gart_iommu_domain_free(struct iommu_domain *domain) struct gart_domain *gart_domain = to_gart_domain(domain); struct gart_device *gart = gart_domain->gart; - if (gart) { - spin_lock(&gart->client_lock); - if (!list_empty(&gart->client)) { - struct gart_client *c; - - list_for_each_entry(c, &gart->client, list) - gart_iommu_detach_dev(domain, c->dev); - } - spin_unlock(&gart->client_lock); - } - - kfree(gart_domain); + kfree(gart->domain); } static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, @@ -377,7 +310,7 @@ struct iommu_group *gart_iommu_device_group(struct device *dev) if (err) return ERR_PTR(err); - return generic_device_group(dev); + return gart_handle->group; } static int gart_iommu_of_xlate(struct device *dev, @@ -502,8 +435,6 @@ static int tegra_gart_probe(struct platform_device *pdev) gart->dev = &pdev->dev; spin_lock_init(&gart->pte_lock); - spin_lock_init(&gart->client_lock); - INIT_LIST_HEAD(&gart->client); gart->regs = gart_regs; gart->iovmm_base = (dma_addr_t)res_remap->start; gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT); @@ -517,6 +448,14 @@ static int tegra_gart_probe(struct platform_device *pdev) goto iommu_unregister; } + gart->group = iommu_group_alloc(); + if (IS_ERR(gart->group)) { + ret = PTR_ERR(gart->group); + goto free_savedata; + } + + iommu_group_ref_get(gart->group); + platform_set_drvdata(pdev, gart); do_gart_setup(gart, NULL); @@ -525,6 +464,8 @@ static int tegra_gart_probe(struct platform_device *pdev) return 0; +free_savedata: + vfree(gart->savedata); iommu_unregister: iommu_device_unregister(&gart->iommu); remove_sysfs: