Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp5107603rwb; Mon, 21 Nov 2022 16:58:37 -0800 (PST) X-Google-Smtp-Source: AA0mqf6IgjQuTG1SbrwswWCDfUGH/DifX8skv0uE9JqZa2/IUv0g8Whx7DpaVWFE+feWwlldVVMu X-Received: by 2002:a17:90a:ab84:b0:213:343:9873 with SMTP id n4-20020a17090aab8400b0021303439873mr29011366pjq.102.1669078717251; Mon, 21 Nov 2022 16:58:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669078717; cv=none; d=google.com; s=arc-20160816; b=GnyPNz3dTTeP1Hx/KzXjKqOL20wynhBBLCyFhA0TyQOCJV2iTgKlWcyFd//7QZT14+ sqWPhVyVFadJUVEbAdrL5IruGyp8rCME2arM9rQeb7KLX1ZK3avypjg+ZptZAVQmTwqc LrI7uPvuuDAE7E5EfRRM6x8pgib1KPyjQXQYHjfnLHrD2hpzTDgvYOh51C0Z2Nre6iyi 5ji9a9EiDA+hGgKEe3WFm54tPI33/XcoiycfzTq1LHZSpxT4A/IhqQeLvyEjKmoeb70E bbBfXPOXZFbDUEtocXkh/yEX/AijHpg0EKAXBGP9Yz2UFs1jgv0UUPXD3Ojm9U9xO/+F 6/Tw== 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=xvjuCZllxvg0nYsjGFc5a7Qw/0O6Hs77PiucHRpVcgU=; b=G2H4CuA/TIjbj9zuo8x+4dKOTspN0+zEeOqVcOe7F8PB7jeNPUP0x3EVpAC0K/xXX4 9UQPtioZFlf6h5l1v5j69IxZwRytkZVJMNpudsCTck6MX2J1zAS8qUtuqKkPCFEJfDD3 6s7BOFidS6/+NlL+HGBlPaF/inc4vDMk/wKuk1QJRP6zaiK1IPdfwIicuTWoczH1q9Fk tvBBcjn7ibmzRlQG7O878jiwBsu2SSgcry2H+W8H+f0l57taCION3VFXIRET2P5N/SJH oLdyZ1MlNn5zJ1OV5bD+YwFjNT5Yxey4uIg6cf8c8cqTe0UU5QLrwsItwptm0PmC5Mwp qgVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=QXg0cvrk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f10-20020a63de0a000000b0046ec7b397e1si11975835pgg.759.2022.11.21.16.58.25; Mon, 21 Nov 2022 16:58:37 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=QXg0cvrk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231749AbiKVAhH (ORCPT + 92 others); Mon, 21 Nov 2022 19:37:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231788AbiKVAg5 (ORCPT ); Mon, 21 Nov 2022 19:36:57 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6765C6972 for ; Mon, 21 Nov 2022 16:36:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669077416; x=1700613416; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dGFRCSd1fhvN2Zriryw2U6ONKPu+goRSJXbnvvR3SvQ=; b=QXg0cvrk84Wndwf0EBycEA987uJfwAvbGcH/FbrLzDUptpPe2mJbwoNr mfATEiSAfeA8T+Y/ClE8Rbr0SkZI7z/tH10EzEaCisC5qA8gjNh8J+Ae3 NIJ8s1jfYrY1mcysv45Ff23sRVMIGBSBdltQMhyUPrOh794mds67SmNMK DeF70q64pn2r7ZU4z1zXaLzYJkdZ2snGB5G4Wl+N8VVIHo6HP4UGfyXDP ci8QkArxVUjtZkg2eDlIo0O4n4TwdYi03zEfR3NDs8reofKv/Ts8kmNg7 PIZTNd6zMOZzaW5aka4kgyle+MYXNg8IBQokGts6t55awt/9DOwB5euXI w==; X-IronPort-AV: E=McAfee;i="6500,9779,10538"; a="315516472" X-IronPort-AV: E=Sophos;i="5.96,182,1665471600"; d="scan'208";a="315516472" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Nov 2022 16:36:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10538"; a="619018421" X-IronPort-AV: E=Sophos;i="5.96,182,1665471600"; d="scan'208";a="619018421" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Nov 2022 16:36:55 -0800 From: Lu Baolu To: Joerg Roedel Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 2/7] iommu/vt-d: Add device_block_translation() helper Date: Tue, 22 Nov 2022 08:29:44 +0800 Message-Id: <20221122002949.148140-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221122002949.148140-1-baolu.lu@linux.intel.com> References: <20221122002949.148140-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If domain attaching to device fails, the IOMMU driver should bring the device to blocking DMA state. The upper layer is expected to recover it by attaching a new domain. Use device_block_translation() in the error path of dev_attach to make the behavior specific. The difference between device_block_translation() and the previous dmar_remove_one_dev_info() is that, in the scalable mode, it is the RID2PASID entry instead of context entry being cleared. As a result, enabling PCI capabilities is moved up. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian Link: https://lore.kernel.org/r/20221118132451.114406-3-baolu.lu@linux.intel.com --- drivers/iommu/intel/iommu.c | 44 ++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index dea0190acc86..1c1a52d1a818 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -277,7 +277,7 @@ static LIST_HEAD(dmar_satc_units); #define for_each_rmrr_units(rmrr) \ list_for_each_entry(rmrr, &dmar_rmrr_units, list) -static void dmar_remove_one_dev_info(struct device *dev); +static void device_block_translation(struct device *dev); int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON); int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON); @@ -1400,7 +1400,7 @@ static void iommu_enable_pci_caps(struct device_domain_info *info) { struct pci_dev *pdev; - if (!info || !dev_is_pci(info->dev)) + if (!dev_is_pci(info->dev)) return; pdev = to_pci_dev(info->dev); @@ -2045,7 +2045,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain, } else { iommu_flush_write_buffer(iommu); } - iommu_enable_pci_caps(info); ret = 0; @@ -2487,7 +2486,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) dev, PASID_RID2PASID); if (ret) { dev_err(dev, "Setup RID2PASID failed\n"); - dmar_remove_one_dev_info(dev); + device_block_translation(dev); return ret; } } @@ -2495,10 +2494,12 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) ret = domain_context_mapping(domain, dev); if (ret) { dev_err(dev, "Domain context map failed\n"); - dmar_remove_one_dev_info(dev); + device_block_translation(dev); return ret; } + iommu_enable_pci_caps(info); + return 0; } @@ -4109,6 +4110,37 @@ static void dmar_remove_one_dev_info(struct device *dev) info->domain = NULL; } +/* + * Clear the page table pointer in context or pasid table entries so that + * all DMA requests without PASID from the device are blocked. If the page + * table has been set, clean up the data structures. + */ +static void device_block_translation(struct device *dev) +{ + struct device_domain_info *info = dev_iommu_priv_get(dev); + struct intel_iommu *iommu = info->iommu; + unsigned long flags; + + iommu_disable_dev_iotlb(info); + if (!dev_is_real_dma_subdevice(dev)) { + if (sm_supported(iommu)) + intel_pasid_tear_down_entry(iommu, dev, + PASID_RID2PASID, false); + else + domain_context_clear(info); + } + + if (!info->domain) + return; + + spin_lock_irqsave(&info->domain->lock, flags); + list_del(&info->link); + spin_unlock_irqrestore(&info->domain->lock, flags); + + domain_detach_iommu(info->domain, iommu); + info->domain = NULL; +} + static int md_domain_init(struct dmar_domain *domain, int guest_width) { int adjust_width; @@ -4230,7 +4262,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, struct device_domain_info *info = dev_iommu_priv_get(dev); if (info->domain) - dmar_remove_one_dev_info(dev); + device_block_translation(dev); } ret = prepare_domain_attach_device(domain, dev); -- 2.34.1