* [PATCH 0/4] add a helper function, is_buffer_dma_capable() @ 2008-09-09 16:06 FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 1/4] add is_buffer_dma_capable helper function FUJITA Tomonori 2008-09-09 16:27 ` [PATCH 0/4] add a helper function, is_buffer_dma_capable() Joerg Roedel 0 siblings, 2 replies; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:06 UTC (permalink / raw) To: mingo; +Cc: linux-kernel, fujita.tomonori, tony.luck, joerg.roedel This patchset adds a trivial helper function, is_buffer_dma_capable() and cleans up some IOMMU implementations. This function is to to see if a memory region is DMA-capable or not with the arguments, the dma_mask (or coherent_dma_mask) of a device and the address and size of a memory region. It's useful for IOMMUs that don't do virtual mappings at all times. The patch for swiotlb is a bug fix (the rest are just cleanups). Currently, swiotlb doesn't take account of the size of a memory region to see if if the memory region is DMA-capable. = arch/x86/kernel/pci-gart_64.c | 16 +++------------- arch/x86/kernel/pci-nommu.c | 10 ++++++---- include/linux/dma-mapping.h | 5 +++++ lib/swiotlb.c | 15 ++++++++------- 4 files changed, 22 insertions(+), 24 deletions(-) ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] add is_buffer_dma_capable helper function 2008-09-09 16:06 [PATCH 0/4] add a helper function, is_buffer_dma_capable() FUJITA Tomonori @ 2008-09-09 16:06 ` FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 2/4] x86: convert gart to use " FUJITA Tomonori 2008-09-09 16:17 ` [PATCH 1/4] add " Luck, Tony 2008-09-09 16:27 ` [PATCH 0/4] add a helper function, is_buffer_dma_capable() Joerg Roedel 1 sibling, 2 replies; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:06 UTC (permalink / raw) To: mingo; +Cc: linux-kernel, fujita.tomonori, Tony Luck, Joerg Roedel is_buffer_dma_capable helper function is to see if a memory region is DMA-capable or not. The arugments are the dma_mask (or coherent_dma_mask) of a device and the address and size of a memory region. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Tony Luck <tony.luck@intel.com> Cc: Joerg Roedel <joerg.roedel@amd.com> --- include/linux/dma-mapping.h | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 952e0f8..6ed50c1 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -48,6 +48,11 @@ static inline int is_device_dma_capable(struct device *dev) return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE; } +static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) +{ + return addr + size <= mask; +} + #ifdef CONFIG_HAS_DMA #include <asm/dma-mapping.h> #else -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] x86: convert gart to use is_buffer_dma_capable helper function 2008-09-09 16:06 ` [PATCH 1/4] add is_buffer_dma_capable helper function FUJITA Tomonori @ 2008-09-09 16:06 ` FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 3/4] x86: convert pci-nommu " FUJITA Tomonori 2008-09-09 16:17 ` [PATCH 1/4] add " Luck, Tony 1 sibling, 1 reply; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:06 UTC (permalink / raw) To: mingo; +Cc: linux-kernel, fujita.tomonori, Joerg Roedel Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Joerg Roedel <joerg.roedel@amd.com> --- arch/x86/kernel/pci-gart_64.c | 16 +++------------- 1 files changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 0b99d4a..1b0c412 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -214,24 +214,14 @@ static void iommu_full(struct device *dev, size_t size, int dir) static inline int need_iommu(struct device *dev, unsigned long addr, size_t size) { - u64 mask = *dev->dma_mask; - int high = addr + size > mask; - int mmu = high; - - if (force_iommu) - mmu = 1; - - return mmu; + return force_iommu || + !is_buffer_dma_capable(*dev->dma_mask, addr, size); } static inline int nonforced_iommu(struct device *dev, unsigned long addr, size_t size) { - u64 mask = *dev->dma_mask; - int high = addr + size > mask; - int mmu = high; - - return mmu; + return !is_buffer_dma_capable(*dev->dma_mask, addr, size); } /* Map a single continuous physical area into the IOMMU. -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] x86: convert pci-nommu to use is_buffer_dma_capable helper function 2008-09-09 16:06 ` [PATCH 2/4] x86: convert gart to use " FUJITA Tomonori @ 2008-09-09 16:06 ` FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 4/4] swiotlb: convert swiotlb " FUJITA Tomonori 0 siblings, 1 reply; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:06 UTC (permalink / raw) To: mingo; +Cc: linux-kernel, fujita.tomonori Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> --- arch/x86/kernel/pci-nommu.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 8e398b5..1c1c98a 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -14,7 +14,7 @@ static int check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) { - if (hwdev && bus + size > *hwdev->dma_mask) { + if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) { if (*hwdev->dma_mask >= DMA_32BIT_MASK) printk(KERN_ERR "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", @@ -79,6 +79,7 @@ nommu_alloc_coherent(struct device *hwdev, size_t size, unsigned long dma_mask; int node; struct page *page; + dma_addr_t addr; dma_mask = dma_alloc_coherent_mask(hwdev, gfp); @@ -90,14 +91,15 @@ again: if (!page) return NULL; - if ((page_to_phys(page) + size > dma_mask) && !(gfp & GFP_DMA)) { + addr = page_to_phys(page); + if (!is_buffer_dma_capable(dma_mask, addr, size) && !(gfp & GFP_DMA)) { free_pages((unsigned long)page_address(page), get_order(size)); gfp |= GFP_DMA; goto again; } - *dma_addr = page_to_phys(page); - if (check_addr("alloc_coherent", hwdev, *dma_addr, size)) { + if (check_addr("alloc_coherent", hwdev, addr, size)) { + *dma_addr = addr; flush_write_buffers(); return page_address(page); } -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] swiotlb: convert swiotlb to use is_buffer_dma_capable helper function 2008-09-09 16:06 ` [PATCH 3/4] x86: convert pci-nommu " FUJITA Tomonori @ 2008-09-09 16:06 ` FUJITA Tomonori 0 siblings, 0 replies; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:06 UTC (permalink / raw) To: mingo; +Cc: linux-kernel, fujita.tomonori, Tony Luck Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Tony Luck <tony.luck@intel.com> --- lib/swiotlb.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c index b5f5d11..240a67c 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -274,13 +274,13 @@ cleanup1: } static int -address_needs_mapping(struct device *hwdev, dma_addr_t addr) +address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) { dma_addr_t mask = 0xffffffff; /* If the device has a mask, use it, otherwise default to 32 bits */ if (hwdev && hwdev->dma_mask) mask = *hwdev->dma_mask; - return (addr & ~mask) != 0; + return !is_buffer_dma_capable(mask, addr, size); } static int is_swiotlb_buffer(char *addr) @@ -473,7 +473,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, int order = get_order(size); ret = (void *)__get_free_pages(flags, order); - if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { + if (ret && address_needs_mapping(hwdev, virt_to_bus(ret), size)) { /* * The allocated memory isn't reachable by the device. * Fall back on swiotlb_map_single(). @@ -497,7 +497,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, dev_addr = virt_to_bus(ret); /* Confirm address can be DMA'd by device */ - if (address_needs_mapping(hwdev, dev_addr)) { + if (address_needs_mapping(hwdev, dev_addr, size)) { printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", (unsigned long long)*hwdev->dma_mask, (unsigned long long)dev_addr); @@ -561,7 +561,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, * we can safely return the device addr and not worry about bounce * buffering it. */ - if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force) + if (!address_needs_mapping(hwdev, dev_addr, size) && !swiotlb_force) return dev_addr; /* @@ -578,7 +578,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, /* * Ensure that the address returned is DMA'ble */ - if (address_needs_mapping(hwdev, dev_addr)) + if (address_needs_mapping(hwdev, dev_addr, size)) panic("map_single: bounce buffer is not DMA'ble"); return dev_addr; @@ -721,7 +721,8 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, for_each_sg(sgl, sg, nelems, i) { addr = SG_ENT_VIRT_ADDRESS(sg); dev_addr = virt_to_bus(addr); - if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { + if (swiotlb_force || + address_needs_mapping(hwdev, dev_addr, sg->length)) { void *map = map_single(hwdev, addr, sg->length, dir); if (!map) { /* Don't panic here, we expect map_sg users -- 1.5.4.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* RE: [PATCH 1/4] add is_buffer_dma_capable helper function 2008-09-09 16:06 ` [PATCH 1/4] add is_buffer_dma_capable helper function FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 2/4] x86: convert gart to use " FUJITA Tomonori @ 2008-09-09 16:17 ` Luck, Tony 2008-09-09 16:21 ` Joerg Roedel 2008-09-09 16:49 ` FUJITA Tomonori 1 sibling, 2 replies; 10+ messages in thread From: Luck, Tony @ 2008-09-09 16:17 UTC (permalink / raw) To: FUJITA Tomonori, mingo@redhat.com Cc: linux-kernel@vger.kernel.org, Joerg Roedel +static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) +{ + return addr + size <= mask; +} Do we care about wrap-around (e.g. addr=0xffffffffffffffff size=2)? -Tony ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] add is_buffer_dma_capable helper function 2008-09-09 16:17 ` [PATCH 1/4] add " Luck, Tony @ 2008-09-09 16:21 ` Joerg Roedel 2008-09-09 16:49 ` FUJITA Tomonori 1 sibling, 0 replies; 10+ messages in thread From: Joerg Roedel @ 2008-09-09 16:21 UTC (permalink / raw) To: Luck, Tony Cc: FUJITA Tomonori, mingo@redhat.com, linux-kernel@vger.kernel.org On Tue, Sep 09, 2008 at 09:17:05AM -0700, Luck, Tony wrote: > +static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) > +{ > + return addr + size <= mask; > +} > > Do we care about wrap-around (e.g. addr=0xffffffffffffffff size=2)? I don't think so. The current code does not care about it and if it happens its a bug in the iommu implementation. Joerg -- | AMD Saxony Limited Liability Company & Co. KG Operating | Wilschdorfer Landstr. 101, 01109 Dresden, Germany System | Register Court Dresden: HRA 4896 Research | General Partner authorized to represent: Center | AMD Saxony LLC (Wilmington, Delaware, US) | General Manager of AMD Saxony LLC: Dr. Hans-R. Deppe, Thomas McCoy ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 1/4] add is_buffer_dma_capable helper function 2008-09-09 16:17 ` [PATCH 1/4] add " Luck, Tony 2008-09-09 16:21 ` Joerg Roedel @ 2008-09-09 16:49 ` FUJITA Tomonori 1 sibling, 0 replies; 10+ messages in thread From: FUJITA Tomonori @ 2008-09-09 16:49 UTC (permalink / raw) To: tony.luck; +Cc: fujita.tomonori, mingo, linux-kernel, joerg.roedel On Tue, 9 Sep 2008 09:17:05 -0700 "Luck, Tony" <tony.luck@intel.com> wrote: > +static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) > +{ > + return addr + size <= mask; > +} > > Do we care about wrap-around (e.g. addr=0xffffffffffffffff size=2)? We could do something like: return addr < mask && addr + size <= mask; But such wrap-around can happen only with a buggy IOMMU implementation. A driver will does DMA from 0xffffffffffffffff to 0x1. Even if this function does the right thing in such case, we will be dead? ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/4] add a helper function, is_buffer_dma_capable() 2008-09-09 16:06 [PATCH 0/4] add a helper function, is_buffer_dma_capable() FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 1/4] add is_buffer_dma_capable helper function FUJITA Tomonori @ 2008-09-09 16:27 ` Joerg Roedel 2008-09-10 9:34 ` Ingo Molnar 1 sibling, 1 reply; 10+ messages in thread From: Joerg Roedel @ 2008-09-09 16:27 UTC (permalink / raw) To: FUJITA Tomonori; +Cc: mingo, linux-kernel, tony.luck On Wed, Sep 10, 2008 at 01:06:45AM +0900, FUJITA Tomonori wrote: > This patchset adds a trivial helper function, is_buffer_dma_capable() > and cleans up some IOMMU implementations. This function is to to see > if a memory region is DMA-capable or not with the arguments, the > dma_mask (or coherent_dma_mask) of a device and the address and size > of a memory region. It's useful for IOMMUs that don't do virtual > mappings at all times. > > The patch for swiotlb is a bug fix (the rest are just > cleanups). Currently, swiotlb doesn't take account of the size of a > memory region to see if if the memory region is DMA-capable. Good idea. This patchset increases the readability of the software dma-api implementations. Acked-by: Joerg Roedel <joerg.roedel@amd.com> -- | AMD Saxony Limited Liability Company & Co. KG Operating | Wilschdorfer Landstr. 101, 01109 Dresden, Germany System | Register Court Dresden: HRA 4896 Research | General Partner authorized to represent: Center | AMD Saxony LLC (Wilmington, Delaware, US) | General Manager of AMD Saxony LLC: Dr. Hans-R. Deppe, Thomas McCoy ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/4] add a helper function, is_buffer_dma_capable() 2008-09-09 16:27 ` [PATCH 0/4] add a helper function, is_buffer_dma_capable() Joerg Roedel @ 2008-09-10 9:34 ` Ingo Molnar 0 siblings, 0 replies; 10+ messages in thread From: Ingo Molnar @ 2008-09-10 9:34 UTC (permalink / raw) To: Joerg Roedel; +Cc: FUJITA Tomonori, mingo, linux-kernel, tony.luck * Joerg Roedel <joerg.roedel@amd.com> wrote: > On Wed, Sep 10, 2008 at 01:06:45AM +0900, FUJITA Tomonori wrote: > > This patchset adds a trivial helper function, is_buffer_dma_capable() > > and cleans up some IOMMU implementations. This function is to to see > > if a memory region is DMA-capable or not with the arguments, the > > dma_mask (or coherent_dma_mask) of a device and the address and size > > of a memory region. It's useful for IOMMUs that don't do virtual > > mappings at all times. > > > > The patch for swiotlb is a bug fix (the rest are just > > cleanups). Currently, swiotlb doesn't take account of the size of a > > memory region to see if if the memory region is DMA-capable. > > Good idea. This patchset increases the readability of the software > dma-api implementations. > > Acked-by: Joerg Roedel <joerg.roedel@amd.com> applied to tip/x86/iommu: 2797982: swiotlb: convert swiotlb to use is_buffer_dma_capable helper function 49fbf4e: x86: convert pci-nommu to use is_buffer_dma_capable helper function ac4ff65: x86: convert gart to use is_buffer_dma_capable helper function 636dc67: add is_buffer_dma_capable helper function thanks! Ingo ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-10 9:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-09 16:06 [PATCH 0/4] add a helper function, is_buffer_dma_capable() FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 1/4] add is_buffer_dma_capable helper function FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 2/4] x86: convert gart to use " FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 3/4] x86: convert pci-nommu " FUJITA Tomonori 2008-09-09 16:06 ` [PATCH 4/4] swiotlb: convert swiotlb " FUJITA Tomonori 2008-09-09 16:17 ` [PATCH 1/4] add " Luck, Tony 2008-09-09 16:21 ` Joerg Roedel 2008-09-09 16:49 ` FUJITA Tomonori 2008-09-09 16:27 ` [PATCH 0/4] add a helper function, is_buffer_dma_capable() Joerg Roedel 2008-09-10 9:34 ` Ingo Molnar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox