Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp2988765pxb; Mon, 16 Nov 2020 02:47:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJz8oLUO7LpeVnAFReP2l0VGGArVGYp7UlelghpSn1cPYTOxwO4f8JAb3oaPZ02brrAeoDBI X-Received: by 2002:a05:6402:a51:: with SMTP id bt17mr14339140edb.328.1605523632904; Mon, 16 Nov 2020 02:47:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605523632; cv=none; d=google.com; s=arc-20160816; b=r/o3A8tbVFoBK1ywwYECywd5Y8+AEXP+szXefzNDQ4IuPdcuNsOHYOlqRy8vS/9LPj 6mr6MjTMjRPX160VoUNmAAqYj7ol9uUoM6z2C2dm+5UJn+dpTr6MHB7XWUE6h0qoKYj1 nmOre0akLXqGNEnfkZbr6LpipNyuBbO0fd2+MbG8HjydAHdplQK7FTZCjcSRfqYObQ0o 6H4tgzGf6E9+he65gJs2hOQ8/QYe22pUIlxLbLBni7Erp+l/2nBs+UZBosHSMHFjzTxM i2KVgXPIfQCHkzySX8HshGFhjOa7HFbt8w/gUCxvlwIg/LTZl/qeP0xQR86JpfpsyOqi SdnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Wd0/vnfcCrjDdoGcCQfh+pgN/wpeOYHsjnVMGzHzoxU=; b=iFooSFGi+pKsIN0DLKW8gVJHf1zsFR+73NJNghp7JNoBoRvn3K6+Uhza7i90yU/LB/ iDQjrYcazDSgGvYvuVCXNfjY2e8BsQbte5jJulV+V8dVh7YvMFms1mDlGPYGvs/PlBML 85M6yjwlho2pzhhLbXBaqUlSlT7tm0keVL15AA7YFvwWBtgOtYHiRGaxw8IMrS3fyxDn C6ULpA1Fnij6G8BMrc8UFv0q2dclDeCe/gS92zRlnO/BU0QOFooxzoSJH95rdA7zHiN+ bPwuQDaqce7NnG4YzBKRch2wvtya9gHAq6YmGZUZSyiFOGs30ZqJReNbNzuG0CuZKMu7 vcow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=bueII90b; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id sb10si11631873ejb.541.2020.11.16.02.46.49; Mon, 16 Nov 2020 02:47:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=bueII90b; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729361AbgKPKoQ (ORCPT + 99 others); Mon, 16 Nov 2020 05:44:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:32778 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726281AbgKPKoQ (ORCPT ); Mon, 16 Nov 2020 05:44:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1605523454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wd0/vnfcCrjDdoGcCQfh+pgN/wpeOYHsjnVMGzHzoxU=; b=bueII90b6Lg4SA6DzYt3+St84/irV41q6hTckqW56aGTbz/I0AbGv1doBhEn6Pf8Mb7nHS X0+bNledIN1LeqdW4A6JoU8O47jrgcdGIhn+6caAOb+rS2WsOEpWnv8AlHXxeBdD3ShtmD QRVfwTudNHX9PeMooedG0vPd7Ig0RBI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-216-kEfNBnrrOpWMFnCF64Shhg-1; Mon, 16 Nov 2020 05:44:12 -0500 X-MC-Unique: kEfNBnrrOpWMFnCF64Shhg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 51FDA8015FA; Mon, 16 Nov 2020 10:44:10 +0000 (UTC) Received: from laptop.redhat.com (ovpn-113-230.ams2.redhat.com [10.36.113.230]) by smtp.corp.redhat.com (Postfix) with ESMTP id 453C05C5AF; Mon, 16 Nov 2020 10:44:00 +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, will@kernel.org, joro@8bytes.org, maz@kernel.org, robin.murphy@arm.com Cc: jean-philippe@linaro.org, zhangfei.gao@linaro.org, zhangfei.gao@gmail.com, vivek.gautam@arm.com, shameerali.kolothum.thodi@huawei.com, alex.williamson@redhat.com, jacob.jun.pan@linux.intel.com, yi.l.liu@intel.com, tn@semihalf.com, nicoleotsuka@gmail.com Subject: [PATCH v12 06/15] iommu/smmuv3: Implement attach/detach_pasid_table Date: Mon, 16 Nov 2020 11:43:07 +0100 Message-Id: <20201116104316.31816-7-eric.auger@redhat.com> In-Reply-To: <20201116104316.31816-1-eric.auger@redhat.com> References: <20201116104316.31816-1-eric.auger@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 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 --- v7 -> v8: - remove smmu->features check, now done on domain finalize v6 -> v7: - check versions and comment the fact we don't need to take into account s1dss and s1fmt 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/arm-smmu-v3/arm-smmu-v3.c | 98 +++++++++++++++++++++ 1 file changed, 98 insertions(+) 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 9580090bd0c9..08ab0dd81049 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2655,6 +2655,102 @@ static void arm_smmu_get_resv_regions(struct device *dev, iommu_dma_get_resv_regions(dev, head); } +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 *master; + struct arm_smmu_device *smmu; + unsigned long flags; + int ret = -EINVAL; + + if (cfg->format != IOMMU_PASID_FORMAT_SMMUV3) + return -EINVAL; + + if (cfg->version != PASID_TABLE_CFG_VERSION_1 || + cfg->vendor_data.smmuv3.version != PASID_TABLE_SMMUV3_CFG_VERSION_1) + return -EINVAL; + + mutex_lock(&smmu_domain->init_mutex); + + smmu = smmu_domain->smmu; + + if (!smmu) + goto out; + + if (smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + goto out; + + switch (cfg->config) { + case IOMMU_PASID_CONFIG_ABORT: + kfree(smmu_domain->s1_cfg); + smmu_domain->s1_cfg = NULL; + smmu_domain->abort = true; + break; + case IOMMU_PASID_CONFIG_BYPASS: + kfree(smmu_domain->s1_cfg); + smmu_domain->s1_cfg = NULL; + smmu_domain->abort = false; + break; + case IOMMU_PASID_CONFIG_TRANSLATE: + /* we do not support S1 <-> S1 transitions */ + if (smmu_domain->s1_cfg) + goto out; + + /* + * we currently support a single CD so s1fmt and s1dss + * fields are also ignored + */ + if (cfg->pasid_bits) + goto out; + + smmu_domain->s1_cfg = kzalloc(sizeof(*smmu_domain->s1_cfg), + GFP_KERNEL); + if (!smmu_domain->s1_cfg) { + ret = -ENOMEM; + goto out; + } + + smmu_domain->s1_cfg->cdcfg.cdtab_dma = cfg->base_ptr; + smmu_domain->abort = false; + break; + default: + goto out; + } + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(master, &smmu_domain->devices, domain_head) + arm_smmu_install_ste_for_dev(master); + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + ret = 0; +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 *master; + unsigned long flags; + + mutex_lock(&smmu_domain->init_mutex); + + if (smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + goto unlock; + + kfree(smmu_domain->s1_cfg); + smmu_domain->s1_cfg = NULL; + smmu_domain->abort = true; + + spin_lock_irqsave(&smmu_domain->devices_lock, flags); + list_for_each_entry(master, &smmu_domain->devices, domain_head) + arm_smmu_install_ste_for_dev(master); + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); + +unlock: + mutex_unlock(&smmu_domain->init_mutex); +} + static bool arm_smmu_dev_has_feature(struct device *dev, enum iommu_dev_features feat) { @@ -2736,6 +2832,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 = generic_iommu_put_resv_regions, + .attach_pasid_table = arm_smmu_attach_pasid_table, + .detach_pasid_table = arm_smmu_detach_pasid_table, .dev_has_feat = arm_smmu_dev_has_feature, .dev_feat_enabled = arm_smmu_dev_feature_enabled, .dev_enable_feat = arm_smmu_dev_enable_feature, -- 2.21.3