From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24FFAC43464 for ; Fri, 18 Sep 2020 10:20:24 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id A6F5B208C3 for ; Fri, 18 Sep 2020 10:20:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="NN3YKWo7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A6F5B208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 256416B0074; Fri, 18 Sep 2020 06:20:10 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 191546B0075; Fri, 18 Sep 2020 06:20:10 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 010B26B0078; Fri, 18 Sep 2020 06:20:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0043.hostedemail.com [216.40.44.43]) by kanga.kvack.org (Postfix) with ESMTP id E05106B0074 for ; Fri, 18 Sep 2020 06:20:09 -0400 (EDT) Received: from smtpin29.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 9FCEE1EE6 for ; Fri, 18 Sep 2020 10:20:09 +0000 (UTC) X-FDA: 77275786938.29.cave92_1a17a092712a Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin29.hostedemail.com (Postfix) with ESMTP id 7ED7A180868F8 for ; Fri, 18 Sep 2020 10:20:09 +0000 (UTC) X-HE-Tag: cave92_1a17a092712a X-Filterd-Recvd-Size: 10606 Received: from mail-ed1-f67.google.com (mail-ed1-f67.google.com [209.85.208.67]) by imf20.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Sep 2020 10:20:08 +0000 (UTC) Received: by mail-ed1-f67.google.com with SMTP id i1so5605651edv.2 for ; Fri, 18 Sep 2020 03:20:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eg7wj6YFIcJZXJ6e8hlFJkbAy4XI85542+kUktisWC0=; b=NN3YKWo7KlOKOcYqp3gJxVVXaBCg4b72hUoRkFq4dnIy3mAoVCOCb8Nflc6zCOSg5T 3lLn2ufJQO3MB4NzCcPFz/OPZ692CdWsLH8qUnnyllurF2migm3fyfbrgCyGd1wHL5ow AX5BKeXz5t4JavRKUAmXblHvBQb+f0CYMikoDSA7LJpI7EJR3JZYD/rxJnVMspwcOJ3i twWq+eX1lLpAogO2KGWT/a1q8Rtsc5xwcmJlgcu9tYu/P2xI9VwWYp1Se1zHqAFd7ItA 36oqWDulumEumvD4QBWIA/0IqvJlzPcvwK3uwgRRE7E4ywEjxP8CUdLPyJ1KtZecrCj0 eCcA== 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:mime-version:content-transfer-encoding; bh=eg7wj6YFIcJZXJ6e8hlFJkbAy4XI85542+kUktisWC0=; b=mvDtctxSGpcZFlcNAZwmnRTa8eNdGdQ+/TWUfBkQ4MSXrkdDSiTBGcVfaD7x6vNSV4 V97Ro/JFHoVjbDy6yvYR8rw+v4BI8WRx/FiKMh+GAsmxg6+uXc2OfjrQFzaxNaJxu4rE XLKI3Plh6m6kJrYPUDT7MMF095Rz8ZFfEu0HFrd09hX5WgqMrZZh1PHH6CiggasXRI5g DY5xZMWyhZUVg+0StIonx2HONeoUIAVqdYSzEOt0DMLINZx+50fjaPcfq3p1MXhyDfGS vjWLcAO8N4CEF4iJl0POnF6dC3hXKcEirX/N/h7DGN52NWtNTg6Z/hZLoVArPGlJrQWu njLA== X-Gm-Message-State: AOAM533kZnuKLUJy7Ttgi0yB/7q2rfkkjyZ7cc9QDgOvy7OqTSTe2l3x 1r3owq7uATHHcRV+WcP2xzu09g== X-Google-Smtp-Source: ABdhPJyTheVNNu7Zbtw9eQMNbAXnHGefwLCRmhLHQeUXn955I5Vb84eT0KaNKYBPqLiFEvCa50xi7w== X-Received: by 2002:aa7:d593:: with SMTP id r19mr19218496edq.331.1600424407714; Fri, 18 Sep 2020 03:20:07 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id r16sm1940674edc.57.2020.09.18.03.20.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2020 03:20:07 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org Cc: joro@8bytes.org, catalin.marinas@arm.com, will@kernel.org, robin.murphy@arm.com, baolu.lu@linux.intel.com, Jonathan.Cameron@huawei.com, jacob.jun.pan@linux.intel.com, zhangfei.gao@linaro.org, xuzaibo@huawei.com, fenghua.yu@intel.com, eric.auger@redhat.com, Jean-Philippe Brucker Subject: [PATCH v10 11/13] iommu/arm-smmu-v3: Add SVA device feature Date: Fri, 18 Sep 2020 12:18:51 +0200 Message-Id: <20200918101852.582559-12-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200918101852.582559-1-jean-philippe@linaro.org> References: <20200918101852.582559-1-jean-philippe@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Implement the IOMMU device feature callbacks to support the SVA feature. At the moment dev_has_feat() returns false since I/O Page Faults and BTM aren't yet implemented. Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 26 ++++++ .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 49 ++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 79 +++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/= arm/arm-smmu-v3/arm-smmu-v3.h index 7b14b48a26c7..ba34914813ff 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -646,6 +646,8 @@ struct arm_smmu_master { u32 *sids; unsigned int num_sids; bool ats_enabled; + bool sva_enabled; + struct list_head bonds; unsigned int ssid_bits; }; =20 @@ -687,10 +689,34 @@ bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *c= d); =20 #ifdef CONFIG_ARM_SMMU_V3_SVA bool arm_smmu_sva_supported(struct arm_smmu_device *smmu); +bool arm_smmu_master_sva_supported(struct arm_smmu_master *master); +bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master); +int arm_smmu_master_enable_sva(struct arm_smmu_master *master); +int arm_smmu_master_disable_sva(struct arm_smmu_master *master); #else /* CONFIG_ARM_SMMU_V3_SVA */ static inline bool arm_smmu_sva_supported(struct arm_smmu_device *smmu) { return false; } + +static inline bool arm_smmu_master_sva_supported(struct arm_smmu_master = *master) +{ + return false; +} + +static inline bool arm_smmu_master_sva_enabled(struct arm_smmu_master *m= aster) +{ + return false; +} + +static inline int arm_smmu_master_enable_sva(struct arm_smmu_master *mas= ter) +{ + return -ENODEV; +} + +static inline int arm_smmu_master_disable_sva(struct arm_smmu_master *ma= ster) +{ + return -ENODEV; +} #endif /* CONFIG_ARM_SMMU_V3_SVA */ #endif /* _ARM_SMMU_V3_H */ diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/io= mmu/arm/arm-smmu-v3/arm-smmu-v3-sva.c index cb94c0924196..9255c9600fb8 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c @@ -10,6 +10,8 @@ #include "arm-smmu-v3.h" #include "../../io-pgtable-arm.h" =20 +static DEFINE_MUTEX(sva_lock); + /* * Check if the CPU ASID is available on the SMMU side. If a private con= text * descriptor is using it, try to replace it. @@ -197,3 +199,50 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *= smmu) =20 return true; } + +static bool arm_smmu_iopf_supported(struct arm_smmu_master *master) +{ + return false; +} + +bool arm_smmu_master_sva_supported(struct arm_smmu_master *master) +{ + if (!(master->smmu->features & ARM_SMMU_FEAT_SVA)) + return false; + + /* SSID and IOPF support are mandatory for the moment */ + return master->ssid_bits && arm_smmu_iopf_supported(master); +} + +bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master) +{ + bool enabled; + + mutex_lock(&sva_lock); + enabled =3D master->sva_enabled; + mutex_unlock(&sva_lock); + return enabled; +} + +int arm_smmu_master_enable_sva(struct arm_smmu_master *master) +{ + mutex_lock(&sva_lock); + master->sva_enabled =3D true; + mutex_unlock(&sva_lock); + + return 0; +} + +int arm_smmu_master_disable_sva(struct arm_smmu_master *master) +{ + mutex_lock(&sva_lock); + if (!list_empty(&master->bonds)) { + dev_err(master->dev, "cannot disable SVA, device is bound\n"); + mutex_unlock(&sva_lock); + return -EBUSY; + } + master->sva_enabled =3D false; + mutex_unlock(&sva_lock); + + return 0; +} diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/= arm/arm-smmu-v3/arm-smmu-v3.c index 44c57bcfe112..95f2e36a4f15 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2162,6 +2162,16 @@ static int arm_smmu_attach_dev(struct iommu_domain= *domain, struct device *dev) master =3D dev_iommu_priv_get(dev); smmu =3D master->smmu; =20 + /* + * Checking that SVA is disabled ensures that this device isn't bound t= o + * any mm, and can be safely detached from its old domain. Bonds cannot + * be removed concurrently since we're holding the group mutex. + */ + if (arm_smmu_master_sva_enabled(master)) { + dev_err(dev, "cannot attach - SVA enabled\n"); + return -EBUSY; + } + arm_smmu_detach_dev(master); =20 mutex_lock(&smmu_domain->init_mutex); @@ -2309,6 +2319,7 @@ static struct iommu_device *arm_smmu_probe_device(s= truct device *dev) master->smmu =3D smmu; master->sids =3D fwspec->ids; master->num_sids =3D fwspec->num_ids; + INIT_LIST_HEAD(&master->bonds); dev_iommu_priv_set(dev, master); =20 /* Check the SIDs are in range of the SMMU and our stream table */ @@ -2361,6 +2372,7 @@ static void arm_smmu_release_device(struct device *= dev) return; =20 master =3D dev_iommu_priv_get(dev); + WARN_ON(arm_smmu_master_sva_enabled(master)); arm_smmu_detach_dev(master); arm_smmu_disable_pasid(master); kfree(master); @@ -2478,6 +2490,69 @@ static void arm_smmu_get_resv_regions(struct devic= e *dev, iommu_dma_get_resv_regions(dev, head); } =20 +static bool arm_smmu_dev_has_feature(struct device *dev, + enum iommu_dev_features feat) +{ + struct arm_smmu_master *master =3D dev_iommu_priv_get(dev); + + if (!master) + return false; + + switch (feat) { + case IOMMU_DEV_FEAT_SVA: + return arm_smmu_master_sva_supported(master); + default: + return false; + } +} + +static bool arm_smmu_dev_feature_enabled(struct device *dev, + enum iommu_dev_features feat) +{ + struct arm_smmu_master *master =3D dev_iommu_priv_get(dev); + + if (!master) + return false; + + switch (feat) { + case IOMMU_DEV_FEAT_SVA: + return arm_smmu_master_sva_enabled(master); + default: + return false; + } +} + +static int arm_smmu_dev_enable_feature(struct device *dev, + enum iommu_dev_features feat) +{ + if (!arm_smmu_dev_has_feature(dev, feat)) + return -ENODEV; + + if (arm_smmu_dev_feature_enabled(dev, feat)) + return -EBUSY; + + switch (feat) { + case IOMMU_DEV_FEAT_SVA: + return arm_smmu_master_enable_sva(dev_iommu_priv_get(dev)); + default: + return -EINVAL; + } +} + +static int arm_smmu_dev_disable_feature(struct device *dev, + enum iommu_dev_features feat) +{ + if (!arm_smmu_dev_feature_enabled(dev, feat)) + return -EINVAL; + + switch (feat) { + case IOMMU_DEV_FEAT_SVA: + return arm_smmu_master_disable_sva(dev_iommu_priv_get(dev)); + default: + return -EINVAL; + } +} + static struct iommu_ops arm_smmu_ops =3D { .capable =3D arm_smmu_capable, .domain_alloc =3D arm_smmu_domain_alloc, @@ -2496,6 +2571,10 @@ static struct iommu_ops arm_smmu_ops =3D { .of_xlate =3D arm_smmu_of_xlate, .get_resv_regions =3D arm_smmu_get_resv_regions, .put_resv_regions =3D generic_iommu_put_resv_regions, + .dev_has_feat =3D arm_smmu_dev_has_feature, + .dev_feat_enabled =3D arm_smmu_dev_feature_enabled, + .dev_enable_feat =3D arm_smmu_dev_enable_feature, + .dev_disable_feat =3D arm_smmu_dev_disable_feature, .pgsize_bitmap =3D -1UL, /* Restricted during device attach */ }; =20 --=20 2.28.0