Received: by 2002:ac0:950e:0:0:0:0:0 with SMTP id f14csp1321214imc; Sun, 17 Mar 2019 10:26:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqxSVbpmaGtN3l0Q0oHHduKFBNx+4v4uKChEkxgoDGMnZGVPT8VFHLcJN4LGbdH+WoL5U/WK X-Received: by 2002:a17:902:9341:: with SMTP id g1mr15717646plp.80.1552843560225; Sun, 17 Mar 2019 10:26:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552843560; cv=none; d=google.com; s=arc-20160816; b=mMNkap1EG/UeK0RJayjmgvItZMNxQXb/uafWbIh16nC2x86bh++4e1SytOjORpLks8 y//ZyyGLOkbbWOgkpOYody5Fuf1w96nJPL/jbWRNfFgZA8HO1yYeKAy8ckL2GuzKqNMx P8jTA+BdyyFtYFoLW3GtAeiLeS7UiMh0sZ8FIT5HldUnqoFfVUB8LG+bleh9iYq6ZH6f pZdKAzo+XKv1xl+s7qV6T3nkzvAZfQwuEf/w/l4sElY+OeLPIF2gzUiNaKdr8sm49ihD mVJLOFguIWuFmCziqBYTiee3UO0loQhsKgciWpnGdO7jC1S00EjwT5NJ+XJVcbdLun7X Qzig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=tj4DrzX/2SbHS8gqfedcWUrYQaIBnlPgcrXi9BBUiCM=; b=PGgaj2aoQNkzGJFGWf9hqM406mUTKWjIkWIoyUcWphqWIgyyzuWqnEyXPXl6geDkTr XkC9I3bCgngM2gBrsuc6TpaXEO1q8HlYtK8IAeWjHp3/ADm/xp40bQJ8LQWMcZfwIHLO lFjr/7/ppRZjPff5mzm+FYIljgXVI2+rPGkTsctOzRukSwZ4fSSzTIuZQP0zW0Nziht8 jUUHz1NYVCqNtHtxYLSRKRfuFG/lVEoJJdFtGTV6qE5tZcbpiuZPXYABl9vUGs2st4F9 05s6kiyUZ8brTscgSC3bLOwUl/+iToWVyRfiN7YBDJbVkaQalRcJ5RZGAveSMooXWHyb ODUA== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t24si6661259pgv.141.2019.03.17.10.25.45; Sun, 17 Mar 2019 10:26:00 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727598AbfCQRYE (ORCPT + 99 others); Sun, 17 Mar 2019 13:24:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52544 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727551AbfCQRYD (ORCPT ); Sun, 17 Mar 2019 13:24:03 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id ADF55308219C; Sun, 17 Mar 2019 17:24:02 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-102.ams2.redhat.com [10.36.116.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id A98A5282D9; Sun, 17 Mar 2019 17:23:54 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, joro@8bytes.org, alex.williamson@redhat.com, jacob.jun.pan@linux.intel.com, yi.l.liu@linux.intel.com, jean-philippe.brucker@arm.com, will.deacon@arm.com, robin.murphy@arm.com Cc: kevin.tian@intel.com, ashok.raj@intel.com, marc.zyngier@arm.com, christoffer.dall@arm.com, peter.maydell@linaro.org, vincent.stehle@arm.com Subject: [PATCH v6 13/22] iommu/smmuv3: Implement attach/detach_pasid_table Date: Sun, 17 Mar 2019 18:22:23 +0100 Message-Id: <20190317172232.1068-14-eric.auger@redhat.com> In-Reply-To: <20190317172232.1068-1-eric.auger@redhat.com> References: <20190317172232.1068-1-eric.auger@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Sun, 17 Mar 2019 17:24:02 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On attach_pasid_table() we program STE S1 related info set by the guest into the actual physical STEs. At minimum we need to program the context descriptor GPA and compute whether the stage1 is translated/bypassed or aborted. Signed-off-by: Eric Auger --- v3 -> v4: - adapt to changes in iommu_pasid_table_config - different programming convention at s1_cfg/s2_cfg/ste.abort v2 -> v3: - callback now is named set_pasid_table and struct fields are laid out differently. v1 -> v2: - invalidate the STE before changing them - hold init_mutex - handle new fields --- drivers/iommu/arm-smmu-v3.c | 114 ++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index e22e944ffc05..e41f61844d78 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2207,6 +2207,118 @@ static void arm_smmu_put_resv_regions(struct device *dev, kfree(entry); } +static int arm_smmu_attach_pasid_table(struct iommu_domain *domain, + struct iommu_pasid_table_config *cfg) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_master_data *entry; + struct arm_smmu_s1_cfg *s1_cfg; + struct arm_smmu_device *smmu; + unsigned long flags; + int ret = -EINVAL; + + if (cfg->format != IOMMU_PASID_FORMAT_SMMUV3) + return -EINVAL; + + mutex_lock(&smmu_domain->init_mutex); + + smmu = smmu_domain->smmu; + + if (!smmu) + goto out; + + if (!((smmu->features & ARM_SMMU_FEAT_TRANS_S1) && + (smmu->features & ARM_SMMU_FEAT_TRANS_S2))) { + dev_info(smmu_domain->smmu->dev, + "does not implement two stages\n"); + goto out; + } + + if (smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + goto out; + + switch (cfg->config) { + case IOMMU_PASID_CONFIG_ABORT: + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(entry, &smmu_domain->devices, list) { + entry->ste.s1_cfg = NULL; + entry->ste.abort = true; + arm_smmu_install_ste_for_dev(entry->dev->iommu_fwspec); + } + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + ret = 0; + break; + case IOMMU_PASID_CONFIG_BYPASS: + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(entry, &smmu_domain->devices, list) { + entry->ste.s1_cfg = NULL; + entry->ste.abort = false; + arm_smmu_install_ste_for_dev(entry->dev->iommu_fwspec); + } + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + ret = 0; + break; + case IOMMU_PASID_CONFIG_TRANSLATE: + /* we currently support a single CD */ + if (cfg->pasid_bits) + goto out; + + s1_cfg = &smmu_domain->s1_cfg; + s1_cfg->cdptr_dma = cfg->base_ptr; + + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(entry, &smmu_domain->devices, list) { + entry->ste.s1_cfg = s1_cfg; + entry->ste.abort = false; + arm_smmu_install_ste_for_dev(entry->dev->iommu_fwspec); + } + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + ret = 0; + break; + default: + break; + } +out: + mutex_unlock(&smmu_domain->init_mutex); + return ret; +} + +static void arm_smmu_detach_pasid_table(struct iommu_domain *domain) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_master_data *entry; + struct arm_smmu_device *smmu; + unsigned long flags; + + mutex_lock(&smmu_domain->init_mutex); + + smmu = smmu_domain->smmu; + + if (!smmu) + return; + + if (!((smmu->features & ARM_SMMU_FEAT_TRANS_S1) && + (smmu->features & ARM_SMMU_FEAT_TRANS_S2))) { + dev_info(smmu_domain->smmu->dev, + "does not implement two stages\n"); + return; + } + + if (smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + return; + + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(entry, &smmu_domain->devices, list) { + entry->ste.s1_cfg = NULL; + entry->ste.abort = true; + arm_smmu_install_ste_for_dev(entry->dev->iommu_fwspec); + } + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + + memset(&smmu_domain->s1_cfg, 0, sizeof(struct arm_smmu_s1_cfg)); + mutex_unlock(&smmu_domain->init_mutex); +} + static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, @@ -2225,6 +2337,8 @@ static struct iommu_ops arm_smmu_ops = { .of_xlate = arm_smmu_of_xlate, .get_resv_regions = arm_smmu_get_resv_regions, .put_resv_regions = arm_smmu_put_resv_regions, + .attach_pasid_table = arm_smmu_attach_pasid_table, + .detach_pasid_table = arm_smmu_detach_pasid_table, .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; -- 2.20.1