lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 7 Jan 2008 18:39:47 -0800 From: akepner@....com To: Tony Luck <tony.luck@...el.com>, Grant Grundler <grundler@...isc-linux.org>, Jesse Barnes <jbarnes@...tuousgeek.org>, Jes Sorensen <jes@....com>, Randy Dunlap <randy.dunlap@...cle.com>, Roland Dreier <rdreier@...co.com>, James Bottomley <James.Bottomley@...eleye.com>, David Miller <davem@...emloft.net>, Muli Ben-Yehuda <muli@...ibm.com> Cc: linux-kernel@...r.kernel.org Subject: [RFC/PARTIAL PATCH 3/3] dma: x86_64 allow "attributes" to be used by dma_map_* Allow dma "attributes" to be passed to dma_map_*/dma_unmap_* implementations on x86_64. Signed-off-by: Arthur Kepner <akepner@....com> -- arch/x86/kernel/pci-calgary_64.c | 13 ++++++++----- arch/x86/kernel/pci-gart_64.c | 27 +++++++++++++++++---------- arch/x86/kernel/pci-nommu_64.c | 8 ++++---- drivers/pci/intel-iommu.c | 10 ++++++---- include/asm-x86/dma-mapping_64.h | 27 ++++++++++++++++----------- include/asm-x86/swiotlb.h | 8 ++++---- 6 files changed, 55 insertions(+), 38 deletions(-) diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 6bf1f71..f742384 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -36,6 +36,7 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/scatterlist.h> +#include <linux/dma-direction.h> #include <asm/gart.h> #include <asm/calgary.h> #include <asm/tce.h> @@ -382,7 +383,7 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) } static void calgary_unmap_sg(struct device *dev, - struct scatterlist *sglist, int nelems, int direction) + struct scatterlist *sglist, int nelems, u32 flags) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -421,7 +422,7 @@ static int calgary_nontranslate_map_sg(struct device* dev, } static int calgary_map_sg(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, u32 flags) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -429,6 +430,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, unsigned int npages; unsigned long entry; int i; + enum dma_data_direction direction = dma_flags_get_dir(flags); if (!translation_enabled(tbl)) return calgary_nontranslate_map_sg(dev, sg, nelems, direction); @@ -457,7 +459,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, return nelems; error: - calgary_unmap_sg(dev, sg, nelems, direction); + calgary_unmap_sg(dev, sg, nelems, flags); for_each_sg(sg, s, nelems, i) { sg->dma_address = bad_dma_address; sg->dma_length = 0; @@ -466,12 +468,13 @@ error: } static dma_addr_t calgary_map_single(struct device *dev, void *vaddr, - size_t size, int direction) + size_t size, u32 flags) { dma_addr_t dma_handle = bad_dma_address; unsigned long uaddr; unsigned int npages; struct iommu_table *tbl = find_iommu_table(dev); + enum dma_data_direction direction = dma_flags_get_dir(flags); uaddr = (unsigned long)vaddr; npages = num_dma_pages(uaddr, size); @@ -485,7 +488,7 @@ static dma_addr_t calgary_map_single(struct device *dev, void *vaddr, } static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, u32 flags) { struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 06bcba5..da7336a 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -25,6 +25,7 @@ #include <linux/bitops.h> #include <linux/kdebug.h> #include <linux/scatterlist.h> +#include <linux/dma-direction.h> #include <asm/atomic.h> #include <asm/io.h> #include <asm/mtrr.h> @@ -230,15 +231,17 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, } static dma_addr_t gart_map_simple(struct device *dev, char *buf, - size_t size, int dir) + size_t size, u32 flags) { + enum dma_data_direction dir = dma_flags_get_dir(flags); dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir); flush_gart(); return map; } /* Map a single area into the IOMMU */ -static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) +static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, + u32 flags) { unsigned long phys_mem, bus; @@ -249,7 +252,7 @@ static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, i if (!need_iommu(dev, phys_mem, size)) return phys_mem; - bus = gart_map_simple(dev, addr, size, dir); + bus = gart_map_simple(dev, addr, size, flags); return bus; } @@ -257,7 +260,7 @@ static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, i * Free a DMA mapping. */ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction) + size_t size, u32 flags) { unsigned long iommu_page; int npages; @@ -278,10 +281,12 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, /* * Wrapper for pci_unmap_single working with scatterlists. */ -static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) +static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, u32 flags) { struct scatterlist *s; int i; + enum dma_data_direction dir = dma_flags_get_dir(flags); for_each_sg(sg, s, nents, i) { if (!s->dma_length || !s->length) @@ -292,10 +297,11 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, /* Fallback for dma_map_sg in case of overflow */ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, - int nents, int dir) + int nents, u32 flags) { struct scatterlist *s; int i; + enum dma_data_direction dir = dma_flags_get_dir(flags); #ifdef CONFIG_IOMMU_DEBUG printk(KERN_DEBUG "dma_map_sg overflow\n"); @@ -307,7 +313,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, addr = dma_map_area(dev, addr, s->length, dir); if (addr == bad_dma_address) { if (i > 0) - gart_unmap_sg(dev, sg, i, dir); + gart_unmap_sg(dev, sg, i, flags); nents = 0; sg[0].dma_length = 0; break; @@ -376,7 +382,7 @@ static inline int dma_map_cont(struct scatterlist *start, int nelems, * Merge chunks that have page aligned sizes into a continuous mapping. */ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, - int dir) + u32 flags) { int i; int out; @@ -384,6 +390,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, unsigned long pages = 0; int need = 0, nextneed; struct scatterlist *s, *ps, *start_sg, *sgmap; + enum dma_data_direction dir = dma_flags_get_dir(flags); if (nents == 0) return 0; @@ -435,10 +442,10 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, error: flush_gart(); - gart_unmap_sg(dev, sg, out, dir); + gart_unmap_sg(dev, sg, out, flags); /* When it was forced or merged try again in a dumb way */ if (force_iommu || iommu_merge) { - out = dma_map_sg_nonforce(dev, sg, nents, dir); + out = dma_map_sg_nonforce(dev, sg, nents, flags); if (out > 0) return out; } diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c index ab08e18..6c31163 100644 --- a/arch/x86/kernel/pci-nommu_64.c +++ b/arch/x86/kernel/pci-nommu_64.c @@ -27,7 +27,7 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) static dma_addr_t nommu_map_single(struct device *hwdev, void *ptr, size_t size, - int direction) + u32 flags) { dma_addr_t bus = virt_to_bus(ptr); if (!check_addr("map_single", hwdev, bus, size)) @@ -36,7 +36,7 @@ nommu_map_single(struct device *hwdev, void *ptr, size_t size, } static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size, - int direction) + u32 flags) { } @@ -56,7 +56,7 @@ static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size, * the same here. */ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) + int nents, u32 flags) { struct scatterlist *s; int i; @@ -76,7 +76,7 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, * pci_unmap_single() above. */ static void nommu_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, int dir) + int nents, u32 flags) { } diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e079a52..934e199 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1825,7 +1825,7 @@ get_valid_domain_for_dev(struct pci_dev *pdev) } static dma_addr_t intel_map_single(struct device *hwdev, void *addr, - size_t size, int dir) + size_t size, u32 flags) { struct pci_dev *pdev = to_pci_dev(hwdev); int ret; @@ -1833,6 +1833,7 @@ static dma_addr_t intel_map_single(struct device *hwdev, void *addr, unsigned long start_addr; struct iova *iova; int prot = 0; + enum dma_data_direction dir = dma_flags_get_dir(flags); BUG_ON(dir == DMA_NONE); if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) @@ -1892,7 +1893,7 @@ error: } static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, u32 flags) { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; @@ -1963,7 +1964,7 @@ static void intel_free_coherent(struct device *hwdev, size_t size, #define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, u32 flags) { int i; struct pci_dev *pdev = to_pci_dev(hwdev); @@ -2017,7 +2018,7 @@ static int intel_nontranslate_map_sg(struct device *hddev, } static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, u32 flags) { void *addr; int i; @@ -2030,6 +2031,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ret; struct scatterlist *sg; unsigned long start_addr; + enum dma_data_direction dir = dma_flags_get_dir(flags); BUG_ON(dir == DMA_NONE); if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) diff --git a/include/asm-x86/dma-mapping_64.h b/include/asm-x86/dma-mapping_64.h index ecd0f61..4bf1359 100644 --- a/include/asm-x86/dma-mapping_64.h +++ b/include/asm-x86/dma-mapping_64.h @@ -7,6 +7,7 @@ */ #include <linux/scatterlist.h> +#include <linux/dma-direction.h> #include <asm/io.h> #include <asm/swiotlb.h> @@ -17,12 +18,12 @@ struct dma_mapping_ops { void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *hwdev, void *ptr, - size_t size, int direction); + size_t size, u32 flags); /* like map_single, but doesn't check the device mask */ dma_addr_t (*map_simple)(struct device *hwdev, char *ptr, - size_t size, int direction); + size_t size, u32 flags); void (*unmap_single)(struct device *dev, dma_addr_t addr, - size_t size, int direction); + size_t size, u32 flags); void (*sync_single_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction); @@ -42,10 +43,10 @@ struct dma_mapping_ops { struct scatterlist *sg, int nelems, int direction); int (*map_sg)(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, u32 flags); void (*unmap_sg)(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + u32 flags); int (*dma_supported)(struct device *hwdev, u64 mask); int is_phys; }; @@ -75,22 +76,24 @@ extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr, static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, - int direction) + u32 flags) { + enum dma_data_direction direction = dma_flags_get_dir(flags); BUG_ON(!valid_dma_direction(direction)); return dma_ops->map_single(hwdev, ptr, size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size, - int direction) + u32 flags) { + enum dma_data_direction direction = dma_flags_get_dir(flags); BUG_ON(!valid_dma_direction(direction)); dma_ops->unmap_single(dev, addr, size, direction); } -#define dma_map_page(dev,page,offset,size,dir) \ - dma_map_single((dev), page_address(page)+(offset), (size), (dir)) +#define dma_map_page(dev,page,offset,size,flags) \ + dma_map_single((dev), page_address(page)+(offset), (size), (flags)) #define dma_unmap_page dma_unmap_single @@ -163,16 +166,18 @@ dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, } static inline int -dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) +dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, u32 flags) { + enum dma_data_direction direction = dma_flags_get_dir(flags); BUG_ON(!valid_dma_direction(direction)); return dma_ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction) + u32 flags) { + enum dma_data_direction direction = dma_flags_get_dir(flags); BUG_ON(!valid_dma_direction(direction)); dma_ops->unmap_sg(hwdev, sg, nents, direction); } diff --git a/include/asm-x86/swiotlb.h b/include/asm-x86/swiotlb.h index f9c5895..ad3ea99 100644 --- a/include/asm-x86/swiotlb.h +++ b/include/asm-x86/swiotlb.h @@ -6,11 +6,11 @@ /* SWIOTLB interface */ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, - size_t size, int dir); + size_t size, u32 flags); extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, u32 flags); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir); @@ -32,9 +32,9 @@ extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int dir); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, u32 flags); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, u32 flags); extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr); extern void swiotlb_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); -- Arthur -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists