Received: by 10.192.165.148 with SMTP id m20csp768910imm; Fri, 20 Apr 2018 15:37:50 -0700 (PDT) X-Google-Smtp-Source: AIpwx48HfAAJoyId1YEF/i789YfM/tRC2lkyTy5Y8Axion3+2t+u2PYdRFxBU0g5ycAzpcUc/9wk X-Received: by 10.98.88.194 with SMTP id m185mr10960300pfb.167.1524263870087; Fri, 20 Apr 2018 15:37:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524263870; cv=none; d=google.com; s=arc-20160816; b=O7dLII0nqjXkqJBxZuO5X3Eav7dheDH9udJ/kxDj+OmMB9lMNO3gT5tA435RM3W7dC /UZuQZdIZGp3snZJ3lF1tweiwz20upddYzmX2niurh3EUGc+9BRirKLt5hLf7hEU/7N8 rxXTAp5qFtC4OysukO6w+pvYr0wU0y8DCQdBOHODQArhiKe/ggn1YPEy/ZJEQwwVwnYW my30IiZC9wM7ggi8U8tbz0g0CH52GTP0qH6J1kaEhEf1NhCbgz8Yljns8sn+mUg1Xya8 PB4ypyUj4RVu7dxhrlbA7MXBHT8Xkmwg4d1y1DnsdJOZvmsWYKscKB6fIUok7Rm5j51o 4sTg== 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 :organization:references:in-reply-to:message-id:subject:cc:to:from :date:arc-authentication-results; bh=+42fwGhmiUp4aUCGeLoYKOE9eGi5+DnvG7qfA4j7/W0=; b=ZjdeTr3Lw9mMgPPV6kV/WVey/OBna2vd03zSdHSLrCu99ubfhlaqF2m+SkhQpiXj/p 06P8oTjGJ2zxU04XuJRxeXQ70601dyrh32uWVetyBqPxQzQ0QjAav8IiP3wYqweEY6Su evxIbfQmxLY5gw8Ngf0RtFG7Teoc9qOIeJxDJFMwSuJhQBKuUzoa4dcuLkZNGND5HW2/ 3FHbKurFxIKabmAeU2zb/SQ0+AVfipnCFbyovISpKCVCcSGirx240caZB3s0hS+6/jNh exQ4NNwEwJPPZICnRb09Mu+6Gn0UCLXcQmCXVI2b9Q1sMonNcClNaQnkT3PHGJj4GXlA RGgw== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 59-v6si6590700plc.103.2018.04.20.15.37.10; Fri, 20 Apr 2018 15:37:50 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752209AbeDTWe2 (ORCPT + 99 others); Fri, 20 Apr 2018 18:34:28 -0400 Received: from mga12.intel.com ([192.55.52.136]:54402 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751325AbeDTWe1 (ORCPT ); Fri, 20 Apr 2018 18:34:27 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Apr 2018 15:34:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,303,1520924400"; d="scan'208";a="49574982" Received: from jacob-builder.jf.intel.com (HELO jacob-builder) ([10.7.199.155]) by orsmga001.jf.intel.com with ESMTP; 20 Apr 2018 15:34:26 -0700 Date: Fri, 20 Apr 2018 15:36:59 -0700 From: Jacob Pan To: Alex Williamson Cc: iommu@lists.linux-foundation.org, LKML , Joerg Roedel , David Woodhouse , Greg Kroah-Hartman , Jean-Philippe Brucker , Rafael Wysocki , "Liu, Yi L" , "Tian, Kevin" , Raj Ashok , Jean Delvare , "Christoph Hellwig" , "Lu Baolu" , Yi L , jacob.jun.pan@linux.intel.com Subject: Re: [PATCH v4 09/22] iommu/vt-d: add svm/sva invalidate function Message-ID: <20180420153659.3052139d@jacob-builder> In-Reply-To: <20180417131045.7635a63d@w520.home> References: <1523915351-54415-1-git-send-email-jacob.jun.pan@linux.intel.com> <1523915351-54415-10-git-send-email-jacob.jun.pan@linux.intel.com> <20180417131045.7635a63d@w520.home> Organization: OTC X-Mailer: Claws Mail 3.13.2 (GTK+ 2.24.30; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 17 Apr 2018 13:10:45 -0600 Alex Williamson wrote: > On Mon, 16 Apr 2018 14:48:58 -0700 > Jacob Pan wrote: > > > When Shared Virtual Address (SVA) is enabled for a guest OS via > > vIOMMU, we need to provide invalidation support at IOMMU API and > > driver level. This patch adds Intel VT-d specific function to > > implement iommu passdown invalidate API for shared virtual address. > > > > The use case is for supporting caching structure invalidation > > of assigned SVM capable devices. Emulated IOMMU exposes queue > > invalidation capability and passes down all descriptors from the > > guest to the physical IOMMU. > > > > The assumption is that guest to host device ID mapping should be > > resolved prior to calling IOMMU driver. Based on the device handle, > > host IOMMU driver can replace certain fields before submit to the > > invalidation queue. > > > > Signed-off-by: Liu, Yi L > > Signed-off-by: Ashok Raj > > Signed-off-by: Jacob Pan > > --- > > drivers/iommu/intel-iommu.c | 170 > > ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 > > insertions(+) > > > > diff --git a/drivers/iommu/intel-iommu.c > > b/drivers/iommu/intel-iommu.c index cae4042..c765448 100644 > > --- a/drivers/iommu/intel-iommu.c > > +++ b/drivers/iommu/intel-iommu.c > > @@ -4973,6 +4973,175 @@ static void > > intel_iommu_detach_device(struct iommu_domain *domain, > > dmar_remove_one_dev_info(to_dmar_domain(domain), dev); } > > > > +/* > > + * 3D array for converting IOMMU generic type-granularity to VT-d > > granularity > > + * X indexed by enum iommu_inv_type > > + * Y indicates request without and with PASID > > + * Z indexed by enum iommu_inv_granularity > > + * > > + * For an example, if we want to find the VT-d granularity > > encoding for IOTLB > > + * type, DMA request with PASID, and page selective. The look up > > indices are: > > + * [1][1][8], where > > + * 1: IOMMU_INV_TYPE_TLB > > + * 1: with PASID > > + * 8: IOMMU_INV_GRANU_PAGE_PASID > > + * > > + * Granu_map array indicates validity of the table. 1: valid, 0: > > invalid > > + * > > + */ > > +const static int > > inv_type_granu_map[IOMMU_INV_NR_TYPE][2][IOMMU_INV_NR_GRANU] = { > > + /* extended dev IOTLBs, for dev-IOTLB, only global is > > valid, > > + for dev-EXIOTLB, two valid granu */ > > + { > > + {1}, > > + {0, 0, 0, 0, 1, 1, 0, 0, 0} > > + }, > > + /* IOTLB and EIOTLB */ > > + { > > + {1, 1, 0, 1, 0, 0, 0, 0, 0}, > > + {0, 0, 0, 0, 1, 0, 1, 1, 1} > > + }, > > + /* PASID cache */ > > + { > > + {0}, > > + {0, 0, 0, 0, 1, 1, 0, 0, 0} > > + }, > > + /* context cache */ > > + { > > + {1, 1, 1} > > + } > > +}; > > + > > +const static u64 > > inv_type_granu_table[IOMMU_INV_NR_TYPE][2][IOMMU_INV_NR_GRANU] = { > > + /* extended dev IOTLBs, only global is valid */ > > + { > > + {QI_DEV_IOTLB_GRAN_ALL}, > > + {0, 0, 0, 0, QI_DEV_IOTLB_GRAN_ALL, > > QI_DEV_IOTLB_GRAN_PASID_SEL, 0, 0, 0} > > + }, > > + /* IOTLB and EIOTLB */ > > + { > > + {DMA_TLB_GLOBAL_FLUSH, DMA_TLB_DSI_FLUSH, 0, > > DMA_TLB_PSI_FLUSH}, > > + {0, 0, 0, 0, QI_GRAN_ALL_ALL, 0, QI_GRAN_NONG_ALL, > > QI_GRAN_NONG_PASID, QI_GRAN_PSI_PASID} > > + }, > > + /* PASID cache */ > > + { > > + {0}, > > + {0, 0, 0, 0, QI_PC_ALL_PASIDS, QI_PC_PASID_SEL} > > + }, > > + /* context cache */ > > + { > > + {DMA_CCMD_GLOBAL_INVL, DMA_CCMD_DOMAIN_INVL, > > DMA_CCMD_DEVICE_INVL} > > + } > > +}; > > + > > +static inline int to_vtd_granularity(int type, int granu, int > > with_pasid, u64 *vtd_granu) +{ > > + if (type >= IOMMU_INV_NR_TYPE || granu >= > > IOMMU_INV_NR_GRANU || with_pasid > 1) > > + return -EINVAL; > > + > > + if (inv_type_granu_map[type][with_pasid][granu] == 0) > > + return -EINVAL; > > + > > + *vtd_granu = inv_type_granu_table[type][with_pasid][granu]; > > + > > + return 0; > > +} > > + > > +static int intel_iommu_sva_invalidate(struct iommu_domain *domain, > > + struct device *dev, struct tlb_invalidate_info > > *inv_info) > > inv_info->hdr.version is never checked, why do we have these if > they're not used? > the version was added to leave room for future extension. you are right, it should be checked. > > +{ > > + struct intel_iommu *iommu; > > + struct dmar_domain *dmar_domain = to_dmar_domain(domain); > > + struct device_domain_info *info; > > + u16 did, sid; > > + u8 bus, devfn; > > + int ret = 0; > > + u64 granu; > > + unsigned long flags; > > + > > + if (!inv_info || !dmar_domain) > > + return -EINVAL; > > + > > + iommu = device_to_iommu(dev, &bus, &devfn); > > + if (!iommu) > > + return -ENODEV; > > + > > + if (!dev || !dev_is_pci(dev)) > > + return -ENODEV; > > + > > + did = dmar_domain->iommu_did[iommu->seq_id]; > > + sid = PCI_DEVID(bus, devfn); > > + ret = to_vtd_granularity(inv_info->hdr.type, > > inv_info->granularity, > > + !!(inv_info->flags & > > IOMMU_INVALIDATE_PASID_TAGGED), &granu); > > + if (ret) { > > + pr_err("Invalid range type %d, granu %d\n", > > inv_info->hdr.type, > > + inv_info->granularity); > > + return ret; > > + } > > + > > + spin_lock(&iommu->lock); > > + spin_lock_irqsave(&device_domain_lock, flags); > > + > > + switch (inv_info->hdr.type) { > > + case IOMMU_INV_TYPE_CONTEXT: > > + iommu->flush.flush_context(iommu, did, sid, > > + DMA_CCMD_MASK_NOBIT, > > granu); > > + break; > > + case IOMMU_INV_TYPE_TLB: > > + /* We need to deal with two scenarios: > > + * - IOTLB for request w/o PASID > > + * - extended IOTLB for request with PASID. > > + */ > > + if (inv_info->size && > > + (inv_info->addr & ((1 << (VTD_PAGE_SHIFT + > > inv_info->size)) - 1))) { > > + pr_err("Addr out of range, addr 0x%llx, > > size order %d\n", > > + inv_info->addr, inv_info->size); > > + ret = -ERANGE; > > + goto out_unlock; > > + } > > + > > + if (inv_info->flags & > > IOMMU_INVALIDATE_PASID_TAGGED) > > + qi_flush_eiotlb(iommu, did, > > mm_to_dma_pfn(inv_info->addr), > > + inv_info->pasid, > > + inv_info->size, granu, > > + inv_info->flags & > > IOMMU_INVALIDATE_GLOBAL_PAGE); > > + else > > + qi_flush_iotlb(iommu, did, > > mm_to_dma_pfn(inv_info->addr), > > + inv_info->size, granu); > > + /** > > + * Always flush device IOTLB if ATS is enabled > > since guest > > + * vIOMMU exposes CM = 1, no device IOTLB flush > > will be passed > > + * down. > > + */ > > + info = iommu_support_dev_iotlb(dmar_domain, iommu, > > bus, devfn); > > + if (info && info->ats_enabled) { > > + if (inv_info->flags & > > IOMMU_INVALIDATE_PASID_TAGGED) > > + qi_flush_dev_eiotlb(iommu, sid, > > + inv_info->pasid, > > info->ats_qdep, > > + inv_info->addr, > > inv_info->size, > > + granu); > > + else > > + qi_flush_dev_iotlb(iommu, sid, > > info->pfsid, > > + info->ats_qdep, > > inv_info->addr, > > + inv_info->size); > > + } > > + break; > > + case IOMMU_INV_TYPE_PASID: > > + qi_flush_pasid(iommu, did, granu, inv_info->pasid); > > + > > + break; > > + default: > > + dev_err(dev, "Unknown IOMMU invalidation type > > %d\n", > > + inv_info->hdr.type); > > + ret = -EINVAL; > > + } > > > More verbose logging, you mean dev_err is unnecessary? I will remove that. > is vfio just passing these through allowing them > to be user reachable? Thanks, yes, the invalidation types are in uapi, expect qemu traps invalidation from vIOMMU and passdown to physical IOMMU. > > Alex > > [...] > [Jacob Pan]