Re: [Xen-devel] [RFC v2 7/7] xen/iommu: smmu-v3: Add Xen specific code to enable the ported driver
On 20/11/17 14:25, Julien Grall wrote: [...] + else { cpu_relax(); Hmmm I now see why you added cpu_relax() at the top. Well, on Xen cpu_relax is just a barrier. On Linux it is used to yield. And that bit is worrying me. The Linux code will allow context switching to another tasks if the code is taking too much time. Xen is not preemptible, so is it fine? This is used when consuming the command queue and could be a potential performance issue if the queue is large. (This is never the case). I am wondering if we should define a yeild in long run? As I said before, Xen is not preemptible. In this particular case, there are spinlock taken by the callers (e.g any function assigning device). So yield would just make it worst. The arguments here don't make much sense - the "yield" instruction has nothing to do with software-level concepts of preemption. It is a hint to SMT *hardware* that this logical processor is doing nothing useful in the short term, so it might be a good idea to let other logical processor(s) have priority over shared execution resources if applicable. Until SMT CPUs become commonly available, though, it's somewhat of a moot point and mostly just a future-proofing consideration. Robin. ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [RFC 6/6] acpi:arm64: Add support for parsing IORT table
On 12/06/17 14:44, Jan Beulich wrote: >>>> On 12.06.17 at 15:36, <julien.gr...@arm.com> wrote: >> On 09/06/17 12:15, Robin Murphy wrote: >>> On 08/06/17 20:30, Sameer Goel wrote: >>> [...] >>>> /** >>>> - * iort_iommu_configure - Set-up IOMMU configuration for a device. >>>> + * iort_iommu_configure - Set-up IOMMU configuration for a device. This >>>> + * function sets up the fwspec as needed for a given device. Only PCI >>>> + * devices are supported for now. >>>> * >>>> * @dev: device to configure >>>> * >>>> - * Returns: iommu_ops pointer on configuration success >>>> - * NULL on configuration failure >>>> + * Returns: Appropriate acpi_status >>>> */ >>>> -const struct iommu_ops *iort_iommu_configure(struct device *dev) >>>> +acpi_status iort_iommu_configure(struct device *dev) >>>> { >>>>struct acpi_iort_node *node, *parent; >>>> - const struct iommu_ops *ops = NULL; >>>>u32 streamid = 0; >>>> + acpi_status status = AE_OK; >>>> >>>>if (dev_is_pci(dev)) { >>>> - struct pci_bus *bus = to_pci_dev(dev)->bus; >>>> + struct pci_dev *pci_device = to_pci_dev(dev); >>>>u32 rid; >>>> >>>> - pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid, >>>> - ); >>>> + rid = PCI_BDF2(pci_device->bus,pci_device->devfn); >>> >>> Beware that the Linux code isn't actually correct to begin with[1]. I >>> don't know how much Xen deals with PCI bridges and quirks, but as it >>> stands you should be able to trivially expose the flaw here by plugging >>> in a Marvell 88SE912x-based SATA card and watching either DMA or MSIs >>> (or even both) kick up stream table faults. >>> >>> Robin. >>> >>> [1]:http://www.spinics.net/lists/linux-acpi/msg74844.html >> >> I am not sure how x86 is handling that. The closest I can find would be >> domain_context_mapping. I have CCed x86 folks to get more feedback here. > > I'm lacking enough context to know whether this is the issue > with what we call phantom devices, or something else. Phantom functions, PCIe-PCI bridges, basically anything that can result in traffic from a single endpoint appearing on multiple RIDs, or a RID other than the device's BDF, at the root complex (and IOMMUs/MSI doorbells beyond). Robin. ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] new dma-mapping tree, was Re: clean up and modularize arch dma_mapping interface V2
Hi Christoph, On 20/06/17 13:41, Christoph Hellwig wrote: > On Fri, Jun 16, 2017 at 08:10:15PM +0200, Christoph Hellwig wrote: >> I plan to create a new dma-mapping tree to collect all this work. >> Any volunteers for co-maintainers, especially from the iommu gang? > > Ok, I've created the new tree: > >git://git.infradead.org/users/hch/dma-mapping.git for-next > > Gitweb: > > > http://git.infradead.org/users/hch/dma-mapping.git/shortlog/refs/heads/for-next > > And below is the patch to add the MAINTAINERS entry, additions welcome. I'm happy to be a reviewer, since I've been working in this area for some time, particularly with the dma-iommu code and arm64 DMA ops. Robin. > Stephen, can you add this to linux-next? > > --- > From 335979c41912e6c101a20b719862b2d837370df1 Mon Sep 17 00:00:00 2001 > From: Christoph Hellwig> Date: Tue, 20 Jun 2017 11:17:30 +0200 > Subject: MAINTAINERS: add entry for dma mapping helpers > > This code has been spread between getting in through arch trees, the iommu > tree, -mm and the drivers tree. There will be a lot of work in this area, > including consolidating various arch implementations into more common > code, so ensure we have a proper git tree that facilitates cooperation with > the architecture maintainers. > > Signed-off-by: Christoph Hellwig > --- > MAINTAINERS | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 09b5ab6a8a5c..56859d53a424 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2595,6 +2595,19 @@ S: Maintained > F: net/bluetooth/ > F: include/net/bluetooth/ > > +DMA MAPPING HELPERS > +M: Christoph Hellwig > +L: linux-ker...@vger.kernel.org > +T: git git://git.infradead.org/users/hch/dma-mapping.git > +W: http://git.infradead.org/users/hch/dma-mapping.git > +S: Supported > +F: lib/dma-debug.c > +F: lib/dma-noop.c > +F: lib/dma-virt.c > +F: drivers/base/dma-mapping.c > +F: drivers/base/dma-coherent.c > +F: include/linux/dma-mapping.h > + > BONDING DRIVER > M: Jay Vosburgh > M: Veaceslav Falico > ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 06/44] iommu/dma: don't rely on DMA_ERROR_CODE
On 16/06/17 19:10, Christoph Hellwig wrote: > DMA_ERROR_CODE is not a public API and will go away soon. dma dma-iommu > driver already implements a proper ->mapping_error method, so it's only > using the value internally. Add a new local define using the value > that arm64 which is the only current user of dma-iommu. I was angling at just open-coding 0/!dma_addr/etc. for simplicity rather than having anything #defined at all - nothing except the 4th and final hunks actually have any relevance to dma_mapping_error(), and I reckon it's plenty clear enough in context. The rest is just proactively blatting address arguments with "arbitrary definitely-invalid value", which is more paranoia than anything else (and arguably unnecessary). It's not the biggest deal, though, so either way: Reviewed-by: Robin Murphy <robin.mur...@arm.com> > Signed-off-by: Christoph Hellwig <h...@lst.de> > --- > drivers/iommu/dma-iommu.c | 18 ++ > 1 file changed, 10 insertions(+), 8 deletions(-) > > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c > index 62618e77bedc..9403336f1fa6 100644 > --- a/drivers/iommu/dma-iommu.c > +++ b/drivers/iommu/dma-iommu.c > @@ -31,6 +31,8 @@ > #include > #include > > +#define IOMMU_MAPPING_ERROR 0 > + > struct iommu_dma_msi_page { > struct list_headlist; > dma_addr_t iova; > @@ -500,7 +502,7 @@ void iommu_dma_free(struct device *dev, struct page > **pages, size_t size, > { > __iommu_dma_unmap(iommu_get_domain_for_dev(dev), *handle, size); > __iommu_dma_free_pages(pages, PAGE_ALIGN(size) >> PAGE_SHIFT); > - *handle = DMA_ERROR_CODE; > + *handle = IOMMU_MAPPING_ERROR; > } > > /** > @@ -533,7 +535,7 @@ struct page **iommu_dma_alloc(struct device *dev, size_t > size, gfp_t gfp, > dma_addr_t iova; > unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; > > - *handle = DMA_ERROR_CODE; > + *handle = IOMMU_MAPPING_ERROR; > > min_size = alloc_sizes & -alloc_sizes; > if (min_size < PAGE_SIZE) { > @@ -627,11 +629,11 @@ static dma_addr_t __iommu_dma_map(struct device *dev, > phys_addr_t phys, > > iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); > if (!iova) > - return DMA_ERROR_CODE; > + return IOMMU_MAPPING_ERROR; > > if (iommu_map(domain, iova, phys - iova_off, size, prot)) { > iommu_dma_free_iova(cookie, iova, size); > - return DMA_ERROR_CODE; > + return IOMMU_MAPPING_ERROR; > } > return iova + iova_off; > } > @@ -671,7 +673,7 @@ static int __finalise_sg(struct device *dev, struct > scatterlist *sg, int nents, > > s->offset += s_iova_off; > s->length = s_length; > - sg_dma_address(s) = DMA_ERROR_CODE; > + sg_dma_address(s) = IOMMU_MAPPING_ERROR; > sg_dma_len(s) = 0; > > /* > @@ -714,11 +716,11 @@ static void __invalidate_sg(struct scatterlist *sg, int > nents) > int i; > > for_each_sg(sg, s, nents, i) { > - if (sg_dma_address(s) != DMA_ERROR_CODE) > + if (sg_dma_address(s) != IOMMU_MAPPING_ERROR) > s->offset += sg_dma_address(s); > if (sg_dma_len(s)) > s->length = sg_dma_len(s); > - sg_dma_address(s) = DMA_ERROR_CODE; > + sg_dma_address(s) = IOMMU_MAPPING_ERROR; > sg_dma_len(s) = 0; > } > } > @@ -836,7 +838,7 @@ void iommu_dma_unmap_resource(struct device *dev, > dma_addr_t handle, > > int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) > { > - return dma_addr == DMA_ERROR_CODE; > + return dma_addr == IOMMU_MAPPING_ERROR; > } > > static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, > ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [RFC 6/6] acpi:arm64: Add support for parsing IORT table
On 08/06/17 20:30, Sameer Goel wrote: [...] > /** > - * iort_iommu_configure - Set-up IOMMU configuration for a device. > + * iort_iommu_configure - Set-up IOMMU configuration for a device. This > + * function sets up the fwspec as needed for a given device. Only PCI > + * devices are supported for now. > * > * @dev: device to configure > * > - * Returns: iommu_ops pointer on configuration success > - * NULL on configuration failure > + * Returns: Appropriate acpi_status > */ > -const struct iommu_ops *iort_iommu_configure(struct device *dev) > +acpi_status iort_iommu_configure(struct device *dev) > { > struct acpi_iort_node *node, *parent; > - const struct iommu_ops *ops = NULL; > u32 streamid = 0; > + acpi_status status = AE_OK; > > if (dev_is_pci(dev)) { > - struct pci_bus *bus = to_pci_dev(dev)->bus; > + struct pci_dev *pci_device = to_pci_dev(dev); > u32 rid; > > - pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid, > -); > + rid = PCI_BDF2(pci_device->bus,pci_device->devfn); Beware that the Linux code isn't actually correct to begin with[1]. I don't know how much Xen deals with PCI bridges and quirks, but as it stands you should be able to trivially expose the flaw here by plugging in a Marvell 88SE912x-based SATA card and watching either DMA or MSIs (or even both) kick up stream table faults. Robin. [1]:http://www.spinics.net/lists/linux-acpi/msg74844.html > > node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, > - iort_match_node_callback, >dev); > + iort_match_node_callback, dev); > if (!node) > - return NULL; > + return AE_NOT_FOUND; > > parent = iort_node_map_rid(node, rid, , > IORT_IOMMU_TYPE); > > - ops = iort_iommu_xlate(dev, parent, streamid); > + status = iort_iommu_xlate(dev, parent, streamid); > + > + status = status ? AE_ERROR : AE_OK; > > } else { > + status = AE_NOT_IMPLEMENTED; > +#if 0 > int i = 0; > > node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, > @@ -616,11 +655,17 @@ const struct iommu_ops *iort_iommu_configure(struct > device *dev) > parent = iort_node_get_id(node, , > IORT_IOMMU_TYPE, i++); > } > +#endif > } > > - return ops; > + return status; > } ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 16/44] arm64: remove DMA_ERROR_CODE
On 08/06/17 14:25, Christoph Hellwig wrote: > The dma alloc interface returns an error by return NULL, and the > mapping interfaces rely on the mapping_error method, which the dummy > ops already implement correctly. > > Thus remove the DMA_ERROR_CODE define. Reviewed-by: Robin Murphy <robin.mur...@arm.com> > Signed-off-by: Christoph Hellwig <h...@lst.de> > --- > arch/arm64/include/asm/dma-mapping.h | 1 - > arch/arm64/mm/dma-mapping.c | 3 +-- > 2 files changed, 1 insertion(+), 3 deletions(-) > > diff --git a/arch/arm64/include/asm/dma-mapping.h > b/arch/arm64/include/asm/dma-mapping.h > index 5392dbeffa45..cf8fc8f05580 100644 > --- a/arch/arm64/include/asm/dma-mapping.h > +++ b/arch/arm64/include/asm/dma-mapping.h > @@ -24,7 +24,6 @@ > #include > #include > > -#define DMA_ERROR_CODE (~(dma_addr_t)0) > extern const struct dma_map_ops dummy_dma_ops; > > static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type > *bus) > diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c > index 3216e098c058..147fbb907a2f 100644 > --- a/arch/arm64/mm/dma-mapping.c > +++ b/arch/arm64/mm/dma-mapping.c > @@ -184,7 +184,6 @@ static void *__dma_alloc(struct device *dev, size_t size, > no_map: > __dma_free_coherent(dev, size, ptr, *dma_handle, attrs); > no_mem: > - *dma_handle = DMA_ERROR_CODE; > return NULL; > } > > @@ -487,7 +486,7 @@ static dma_addr_t __dummy_map_page(struct device *dev, > struct page *page, > enum dma_data_direction dir, > unsigned long attrs) > { > - return DMA_ERROR_CODE; > + return 0; > } > > static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr, > ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 06/44] iommu/dma: don't rely on DMA_ERROR_CODE
Hi Christoph, On 08/06/17 14:25, Christoph Hellwig wrote: > DMA_ERROR_CODE is not a public API and will go away soon. dma dma-iommu > driver already implements a proper ->mapping_error method, so it's only > using the value internally. Add a new local define using the value > that arm64 which is the only current user of dma-iommu. It would be fine to just use 0, since dma-iommu already makes sure that that will never be allocated for a valid DMA address. Otherwise, looks good! Robin. > Signed-off-by: Christoph Hellwig> --- > drivers/iommu/dma-iommu.c | 18 ++ > 1 file changed, 10 insertions(+), 8 deletions(-) > > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c > index 62618e77bedc..638aea814b94 100644 > --- a/drivers/iommu/dma-iommu.c > +++ b/drivers/iommu/dma-iommu.c > @@ -31,6 +31,8 @@ > #include > #include > > +#define IOMMU_MAPPING_ERROR (~(dma_addr_t)0) > + > struct iommu_dma_msi_page { > struct list_headlist; > dma_addr_t iova; > @@ -500,7 +502,7 @@ void iommu_dma_free(struct device *dev, struct page > **pages, size_t size, > { > __iommu_dma_unmap(iommu_get_domain_for_dev(dev), *handle, size); > __iommu_dma_free_pages(pages, PAGE_ALIGN(size) >> PAGE_SHIFT); > - *handle = DMA_ERROR_CODE; > + *handle = IOMMU_MAPPING_ERROR; > } > > /** > @@ -533,7 +535,7 @@ struct page **iommu_dma_alloc(struct device *dev, size_t > size, gfp_t gfp, > dma_addr_t iova; > unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; > > - *handle = DMA_ERROR_CODE; > + *handle = IOMMU_MAPPING_ERROR; > > min_size = alloc_sizes & -alloc_sizes; > if (min_size < PAGE_SIZE) { > @@ -627,11 +629,11 @@ static dma_addr_t __iommu_dma_map(struct device *dev, > phys_addr_t phys, > > iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); > if (!iova) > - return DMA_ERROR_CODE; > + return IOMMU_MAPPING_ERROR; > > if (iommu_map(domain, iova, phys - iova_off, size, prot)) { > iommu_dma_free_iova(cookie, iova, size); > - return DMA_ERROR_CODE; > + return IOMMU_MAPPING_ERROR; > } > return iova + iova_off; > } > @@ -671,7 +673,7 @@ static int __finalise_sg(struct device *dev, struct > scatterlist *sg, int nents, > > s->offset += s_iova_off; > s->length = s_length; > - sg_dma_address(s) = DMA_ERROR_CODE; > + sg_dma_address(s) = IOMMU_MAPPING_ERROR; > sg_dma_len(s) = 0; > > /* > @@ -714,11 +716,11 @@ static void __invalidate_sg(struct scatterlist *sg, int > nents) > int i; > > for_each_sg(sg, s, nents, i) { > - if (sg_dma_address(s) != DMA_ERROR_CODE) > + if (sg_dma_address(s) != IOMMU_MAPPING_ERROR) > s->offset += sg_dma_address(s); > if (sg_dma_len(s)) > s->length = sg_dma_len(s); > - sg_dma_address(s) = DMA_ERROR_CODE; > + sg_dma_address(s) = IOMMU_MAPPING_ERROR; > sg_dma_len(s) = 0; > } > } > @@ -836,7 +838,7 @@ void iommu_dma_unmap_resource(struct device *dev, > dma_addr_t handle, > > int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) > { > - return dma_addr == DMA_ERROR_CODE; > + return dma_addr == IOMMU_MAPPING_ERROR; > } > > static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, > ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v4 43/44] dma-mapping: Remove dma_get_attr
On 10/06/16 11:12, Krzysztof Kozlowski wrote: After switching DMA attributes to unsigned long it is easier to just compare the bits. Signed-off-by: Krzysztof Kozlowski <k.kozlow...@samsung.com> [for avr32] Acked-by: Hans-Christian Noren Egtvedt <egtv...@samfundet.no> --- [...] arch/arm64/mm/dma-mapping.c| 10 +++ [...] drivers/iommu/dma-iommu.c | 2 +- [...] diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index a7686028dfeb..06c068ca3541 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -32,7 +32,7 @@ static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, bool coherent) { - if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) + if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE)) return pgprot_writecombine(prot); return prot; } @@ -702,7 +702,7 @@ static dma_addr_t __iommu_map_page(struct device *dev, struct page *page, dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot); if (!iommu_dma_mapping_error(dev, dev_addr) && - !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) + (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) __iommu_sync_single_for_device(dev, dev_addr, size, dir); return dev_addr; @@ -712,7 +712,7 @@ static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { - if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) __iommu_sync_single_for_cpu(dev, dev_addr, size, dir); iommu_dma_unmap_page(dev, dev_addr, size, dir, attrs); @@ -752,7 +752,7 @@ static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl, { bool coherent = is_device_dma_coherent(dev); - if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) __iommu_sync_sg_for_device(dev, sgl, nelems, dir); return iommu_dma_map_sg(dev, sgl, nelems, @@ -764,7 +764,7 @@ static void __iommu_unmap_sg_attrs(struct device *dev, enum dma_data_direction dir, unsigned long attrs) { - if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) + if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) __iommu_sync_sg_for_cpu(dev, sgl, nelems, dir); iommu_dma_unmap_sg(dev, sgl, nelems, dir, attrs); [...] diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 6c1bda504fb1..08a1e2f3690f 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -306,7 +306,7 @@ struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp, } else { size = ALIGN(size, min_size); } - if (dma_get_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, attrs)) + if (attrs & DMA_ATTR_ALLOC_SINGLE_PAGES) alloc_sizes = min_size; count = PAGE_ALIGN(size) >> PAGE_SHIFT; [...] These all look appropriate to me; thanks! For arm64 and dma-iommu: Acked-by: Robin Murphy <robin.mur...@arm.com> ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel