merge swiotlb support into dma_direct_ops
Hi Konrad and others,
can you review this series? It merges the swiotlb support into the DMA direct ops so that we don't have to duplicate the dma mapping logic in multiple places.
Note that this is based on the dma_mapping_error series for which I'd still like to collect a few more reviews, so pulling the git tree might be easiest for testing.
The git tree is available here:
git://git.infradead.org/users/hch/misc.git swiotlb-merge
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/swiotlb-merge
PATCH 1/5 swiotlb: remove SWIOTLB_MAP_ERROR
We can use DMA_MAPPING_ERROR instead, which already maps to the same value.
--- drivers/xen/swiotlb-xen.c | 4 ++-- include/linux/swiotlb.h | 3 --- kernel/dma/swiotlb.c | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-)
drivers/xen/swiotlb-xen.c +2 -2
@@ -403,7 +403,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, map =swiotlb_tbl_map_single (dev, start_dma_addr, phys, size, dir, attrs); -if (map =SWIOTLB_MAP_ERROR ) +if (map =DMA_MAPPING_ERROR )return DMA_MAPPING_ERROR ; dev_addr =xen_phys_to_bus (map);
@@ -572,7 +572,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,sg_phys (sg), sg->length, dir, attrs); -if (map =SWIOTLB_MAP_ERROR ) { +if (map =DMA_MAPPING_ERROR ) {dev_warn (hwdev,"swiotlb buffer is full\n" );/* Don't panic here, we expect map_sg users to do proper error handling. */
include/linux/swiotlb.h +0 -3
@@ -46,9 +46,6 @@ enum dma_sync_target { SYNC_FOR_DEVICE = 1, }; -/* define the last possible byte of physical address space as a mapping error */ -#define SWIOTLB_MAP_ERROR (~(phys_addr_t)0x0) - extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, dma_addr_t tbl_dma_addr, phys_addr_t phys, size_t size,
kernel/dma/swiotlb.c +2 -2
@@ -526,7 +526,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,spin_unlock_irqrestore (&io_tlb_lock, flags);if (!(attrs &DMA_ATTR_NO_WARN ) &&printk_ratelimit ())dev_warn (hwdev,"swiotlb buffer is full (sz: %zd bytes)\n" , size); -return SWIOTLB_MAP_ERROR ; +return DMA_MAPPING_ERROR ; found:spin_unlock_irqrestore (&io_tlb_lock, flags);
@@ -637,7 +637,7 @@ static dma_addr_t swiotlb_bounce_page(struct device *dev, phys_addr_t *phys,/* Oh well, have to allocate and map a bounce buffer. */ *phys =swiotlb_tbl_map_single (dev,__phys_to_dma (dev, io_tlb_start), *phys, size, dir, attrs); -if (*phys =SWIOTLB_MAP_ERROR ) +if (*phys =DMA_MAPPING_ERROR )return DMA_MAPPING_ERROR ;/* Ensure that the address returned is DMA'ble */
Signature · 1 line
2.19.1
PATCH 2/5 swiotlb: remove dma_mark_clean
In reply to Christoph HellwigInstead of providing a special dma_mark_clean hook just for ia64, switch ia64 to use the normal arch_sync_dma_for_cpu hooks instead.
This means that we now also set the PG_arch_1 bit for pages in the swiotlb buffer, which isn't stricly needed as we will never execute code out of the swiotlb buffer, but otherwise harmless.
--- arch/ia64/Kconfig | 3 ++- arch/ia64/kernel/dma-mapping.c | 20 +++++++++++++++++++- arch/ia64/mm/init.c | 18 +++++++----------- drivers/xen/swiotlb-xen.c | 20 +------------------- include/linux/dma-direct.h | 8 -------- kernel/dma/swiotlb.c | 18 +----------------- 6 files changed, 30 insertions(+), 57 deletions(-)
arch/ia64/Kconfig +2 -1
@@ -28,8 +28,9 @@ config IA64 select HAVE_ARCH_TRACEHOOK select HAVE_MEMBLOCK_NODE_MAP select HAVE_VIRT_CPU_ACCOUNTING - select ARCH_HAS_DMA_MARK_CLEAN + select ARCH_HAS_DMA_COHERENT_TO_PFN select ARCH_HAS_SG_CHAIN + select ARCH_HAS_SYNC_DMA_FOR_CPU select VIRT_TO_BUS select ARCH_DISCARD_MEMBLOCK select GENERIC_IRQ_PROBE
arch/ia64/kernel/dma-mapping.c +19 -1
@@ -1,5 +1,5 @@// SPDX-License-Identifier: GPL-2.0 -#include <linux/dma-mapping.h> +#include <linux/dma-direct.h> #include <linux/swiotlb.h> #include <linux/export.h>
@@ -16,6 +16,24 @@ const struct dma_map_ops *dma_get_ops(struct device *dev)EXPORT_SYMBOL (dma_get_ops);#ifdef CONFIG_SWIOTLB +void *arch_dma_alloc (struct device *dev,size_t size, +dma_addr_t *dma_handle,gfp_t gfp,unsigned long attrs) +{ +return dma_direct_alloc_pages (dev, size, dma_handle, gfp, attrs); +} + +void arch_dma_free (struct device *dev,size_t size,void *cpu_addr, +dma_addr_t dma_addr,unsigned long attrs) +{ +dma_direct_free_pages (dev, size, cpu_addr, dma_addr, attrs); +} + +long arch_dma_coherent_to_pfn (struct device *dev,void *cpu_addr, +dma_addr_t dma_addr) +{ +return page_to_pfn (virt_to_page (cpu_addr)); +} +void __init swiotlb_dma_init (void ) { dma_ops = &swiotlb_dma_ops;
arch/ia64/mm/init.c +7 -11
@@ -71,18 +71,14 @@ __ia64_sync_icache_dcache (pte_t pte)* DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to * flush them when they get mapped into an executable vm-area. */ -void -dma_mark_clean (void *addr,size_t size) +void arch_sync_dma_for_cpu (struct device *dev,phys_addr_t paddr, +size_t size,enum dma_data_direction dir) { -unsigned long pg_addr, end; - - pg_addr =PAGE_ALIGN ((unsigned long ) addr); - end = (unsigned long ) addr + size; -while (pg_addr +PAGE_SIZE <= end) { -struct page *page =virt_to_page (pg_addr); -set_bit (PG_arch_1, &page->flags); - pg_addr +=PAGE_SIZE ; - } +unsigned long pfn =__phys_to_pfn (paddr); + +do { +set_bit (PG_arch_1, &pfn_to_page (pfn)->flags); + }while (++pfn <=__phys_to_pfn (paddr + size -1 )); } inline void
drivers/xen/swiotlb-xen.c +1 -19
@@ -441,21 +441,8 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,xen_dma_unmap_page (hwdev, dev_addr, size, dir, attrs);/* NOTE: We use dev_addr here, not paddr! */ -if (is_xen_swiotlb_buffer (dev_addr)) { +if (is_xen_swiotlb_buffer (dev_addr))swiotlb_tbl_unmap_single (hwdev, paddr, size, dir, attrs); -return ; - } - -if (dir !=DMA_FROM_DEVICE ) -return ; - -/* -* phys_to_virt doesn't work with hihgmem page but we could -* call dma_mark_clean() with hihgmem page here. However, we -* are fine since dma_mark_clean() is null on POWERPC. We can -* make dma_mark_clean() take a physical address if necessary. -*/ -dma_mark_clean (phys_to_virt (paddr), size); } static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
@@ -493,11 +480,6 @@ xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,if (target =SYNC_FOR_DEVICE )xen_dma_sync_single_for_device (hwdev, dev_addr, size, dir); - -if (dir !=DMA_FROM_DEVICE ) -return ; - -dma_mark_clean (phys_to_virt (paddr), size); }void
include/linux/dma-direct.h +0 -8
@@ -48,14 +48,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)return __sme_clr (__dma_to_phys (dev, daddr)); } -#ifdef CONFIG_ARCH_HAS_DMA_MARK_CLEAN -void dma_mark_clean (void *addr,size_t size); -#else -static inline void dma_mark_clean (void *addr,size_t size) -{ -} -#endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */ -u64 dma_direct_get_required_mask (struct device *dev);void *dma_direct_alloc (struct device *dev,size_t size,dma_addr_t *dma_handle,gfp_t gfp,unsigned long attrs);
kernel/dma/swiotlb.c +1 -17
@@ -706,21 +706,8 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, (attrs & DMA_ATTR_SKIP_CPU_SYNC) = 0)arch_sync_dma_for_cpu (hwdev, paddr, size, dir); -if (is_swiotlb_buffer (paddr)) { +if (is_swiotlb_buffer (paddr))swiotlb_tbl_unmap_single (hwdev, paddr, size, dir, attrs); -return ; - } - -if (dir !=DMA_FROM_DEVICE ) -return ; - -/* -* phys_to_virt doesn't work with hihgmem page but we could -* call dma_mark_clean() with hihgmem page here. However, we -* are fine since dma_mark_clean() is null on POWERPC. We can -* make dma_mark_clean() take a physical address if necessary. -*/ -dma_mark_clean (phys_to_virt (paddr), size); }/*
@@ -750,9 +737,6 @@ swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,if (!dev_is_dma_coherent (hwdev) && target =SYNC_FOR_DEVICE )arch_sync_dma_for_device (hwdev, paddr, size, dir); - -if (!is_swiotlb_buffer (paddr) && dir =DMA_FROM_DEVICE ) -dma_mark_clean (phys_to_virt (paddr), size); }void
Signature · 1 line
2.19.1
PATCH 3/5 dma-direct: improve addressability error reporting
In reply to Christoph HellwigOnly report report a DMA addressability report once to avoid spewing the kernel log with repeated message. Also provide a stack trace to make it easy to find the actual caller that caused the problem.
Last but not least move the actual check into the fast path and only leave the error reporting in a helper.
--- kernel/dma/direct.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-)
kernel/dma/direct.c +15 -21
@@ -30,27 +30,16 @@ static inline bool force_dma_unencrypted(void)return sev_active (); } -static bool -check_addr (struct device *dev,dma_addr_t dma_addr,size_t size, -const char *caller) +static void report_addr (struct device *dev,dma_addr_t dma_addr,size_t size) { -if (unlikely (dev && !dma_capable (dev, dma_addr, size))) { -if (!dev->dma_mask) { -dev_err (dev, -"%s: call on device without dma_mask\n" , - caller); -return false; - } - -if (*dev->dma_mask >=DMA_BIT_MASK (32 ) || dev->bus_dma_mask) { -dev_err (dev, -"%s: overflow %pad+%zu of device mask %llx bus mask %llx\n" , - caller, &dma_addr, size, - *dev->dma_mask, dev->bus_dma_mask); - } -return false; +if (!dev->dma_mask) { +dev_err_once (dev,"DMA map on device without dma_mask\n" ); + }else if (*dev->dma_mask >=DMA_BIT_MASK (32 ) || dev->bus_dma_mask) { +dev_err_once (dev, +"overflow %pad+%zu of DMA mask %llx bus mask %llx\n" , + &dma_addr, size, *dev->dma_mask, dev->bus_dma_mask); } -return true; +WARN_ON_ONCE (1 ); } static inline dma_addr_t phys_to_dma_direct(struct device *dev,
@@ -288,8 +277,10 @@ dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,phys_addr_t phys =page_to_phys (page) + offset;dma_addr_t dma_addr =phys_to_dma (dev, phys); -if (!check_addr (dev, dma_addr, size, __func__)) +if (unlikely (dev && !dma_capable (dev, dma_addr, size))) { +report_addr (dev, dma_addr, size);return DMA_MAPPING_ERROR ; + }if (!(attrs &DMA_ATTR_SKIP_CPU_SYNC ))dma_direct_sync_single_for_device (dev, dma_addr, size, dir);
@@ -306,8 +297,11 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,BUG_ON (!sg_page (sg));sg_dma_address (sg) =phys_to_dma (dev,sg_phys (sg)); -if (!check_addr (dev,sg_dma_address (sg), sg->length, __func__)) +if (unlikely (dev && !dma_capable (dev,sg_dma_address (sg), + sg->length))) { +report_addr (dev,sg_dma_address (sg), sg->length);return 0 ; + }sg_dma_len (sg) = sg->length; }
Signature · 1 line
2.19.1
PATCH 4/5 dma-direct: use dma_direct_map_page to implement dma_direct_map_sg
In reply to Christoph HellwigNo need to duplicate the mapping logic.
--- kernel/dma/direct.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
kernel/dma/direct.c +5 -9
@@ -217,6 +217,7 @@ static void dma_direct_sync_single_for_device(struct device *dev,arch_sync_dma_for_device (dev,dma_to_phys (dev, addr), size, dir); } +#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE )static void dma_direct_sync_sg_for_device (struct device *dev,struct scatterlist *sgl,int nents,enum dma_data_direction dir) {
@@ -229,6 +230,7 @@ static void dma_direct_sync_sg_for_device(struct device *dev,for_each_sg (sgl, sg, nents, i) arch_sync_dma_for_device(dev, sg_phys(sg), sg->length, dir); } +#endif #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU ) || \ defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL )
@@ -294,19 +296,13 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,struct scatterlist *sg;for_each_sg (sgl, sg, nents, i) { -BUG_ON (!sg_page (sg)); - -sg_dma_address (sg) =phys_to_dma (dev,sg_phys (sg)); -if (unlikely (dev && !dma_capable (dev,sg_dma_address (sg), - sg->length))) { -report_addr (dev,sg_dma_address (sg), sg->length); + sg->dma_address =dma_direct_map_page (dev,sg_page (sg), + sg->offset, sg->length, dir, attrs); +if (sg->dma_address =DMA_MAPPING_ERROR )return 0 ; - }sg_dma_len (sg) = sg->length; } -if (!(attrs &DMA_ATTR_SKIP_CPU_SYNC )) -dma_direct_sync_sg_for_device (dev, sgl, nents, dir);return nents; }
Signature · 1 line
2.19.1
PATCH 5/5 dma-direct: merge swiotlb_dma_ops into the dma_direct code
In reply to Christoph HellwigWhile the dma-direct code is (relatively) clean and simple we actually have to use the swiotlb ops for the mapping on many architectures due to devices with addressing limits. Instead of keeping two implementations around this commit allows the dma-direct implementation to call the swiotlb bounce buffering functions and thus share the guts of the mapping implementation. This also simplified the dma-mapping setup on a few architectures where we don't have to differenciate which implementation to use.
--- arch/arm64/mm/dma-mapping.c | 2 +- arch/ia64/hp/common/hwsw_iommu.c | 2 +- arch/ia64/hp/common/sba_iommu.c | 6 +- arch/ia64/kernel/dma-mapping.c | 2 +- arch/mips/include/asm/dma-mapping.h | 2 - arch/powerpc/kernel/dma-swiotlb.c | 16 +- arch/riscv/include/asm/dma-mapping.h | 15 -- arch/x86/kernel/pci-swiotlb.c | 4 +- arch/x86/mm/mem_encrypt.c | 7 - arch/x86/pci/sta2x11-fixup.c | 1 - include/linux/dma-direct.h | 12 ++ include/linux/swiotlb.h | 68 +++----- kernel/dma/direct.c | 113 +++++++++---- kernel/dma/swiotlb.c | 227 ++------------------------- 14 files changed, 144 insertions(+), 333 deletions(-) delete mode 100644 arch/riscv/include/asm/dma-mapping.h
arch/arm64/mm/dma-mapping.c +1 -1
@@ -549,7 +549,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, const struct iommu_ops *iommu, bool coherent) { if (!dev->dma_ops) - dev->dma_ops = &swiotlb_dma_ops; + dev->dma_ops = &dma_direct_ops; dev->dma_coherent = coherent;__iommu_setup_dma_ops (dev, dma_base, size, iommu);
arch/ia64/hp/common/hwsw_iommu.c +1 -1
@@ -38,7 +38,7 @@ static inline int use_swiotlb(struct device *dev)const struct dma_map_ops *hwsw_dma_get_ops (struct device *dev) {if (use_swiotlb (dev)) -return &swiotlb_dma_ops; +return &dma_direct_ops;return &sba_dma_ops; }EXPORT_SYMBOL (hwsw_dma_get_ops);
arch/ia64/hp/common/sba_iommu.c +2 -4
@@ -2065,8 +2065,6 @@ static int __init acpi_sba_ioc_init_acpi(void)/* This has to run before acpi_scan_init(). */ arch_initcall (acpi_sba_ioc_init_acpi); -extern const struct dma_map_ops swiotlb_dma_ops; -static int __init sba_init (void ) {
@@ -2080,7 +2078,7 @@ sba_init(void)* a successful kdump kernel boot is to use the swiotlb. */ if (is_kdump_kernel ()) { - dma_ops = &swiotlb_dma_ops; + dma_ops = &dma_direct_ops;if (swiotlb_late_init_with_default_size (64 * (1 <<20 )) !=0 )panic ("Unable to initialize software I/O TLB:" " Try machvec=dig boot option" );
@@ -2102,7 +2100,7 @@ sba_init(void)* If we didn't find something sba_iommu can claim, we * need to setup the swiotlb and switch to the dig machvec. */ - dma_ops = &swiotlb_dma_ops; + dma_ops = &dma_direct_ops;if (swiotlb_late_init_with_default_size (64 * (1 <<20 )) !=0 )panic ("Unable to find SBA IOMMU or initialize " "software I/O TLB: Try machvec=dig boot option" );
arch/ia64/kernel/dma-mapping.c +1 -1
@@ -36,7 +36,7 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,void __init swiotlb_dma_init (void ) { - dma_ops = &swiotlb_dma_ops; + dma_ops = &dma_direct_ops;swiotlb_init (1 ); }#endif
arch/mips/include/asm/dma-mapping.h +0 -2
@@ -10,8 +10,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) {#if defined(CONFIG_MACH_JAZZ )return &jazz_dma_ops; -#elif defined(CONFIG_SWIOTLB ) -return &swiotlb_dma_ops;#else return &dma_direct_ops;#endif
arch/powerpc/kernel/dma-swiotlb.c +8 -8
@@ -50,15 +50,15 @@ const struct dma_map_ops powerpc_swiotlb_dma_ops = { .alloc = __dma_nommu_alloc_coherent, .free = __dma_nommu_free_coherent, .mmap = dma_nommu_mmap_coherent, - .map_sg = swiotlb_map_sg_attrs, - .unmap_sg = swiotlb_unmap_sg_attrs, + .map_sg = dma_direct_map_page, + .unmap_sg = dma_direct_unmap_sg, .dma_supported = swiotlb_dma_supported, - .map_page = swiotlb_map_page, - .unmap_page = swiotlb_unmap_page, - .sync_single_for_cpu = swiotlb_sync_single_for_cpu, - .sync_single_for_device = swiotlb_sync_single_for_device, - .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, - .sync_sg_for_device = swiotlb_sync_sg_for_device, + .map_page = dma_direct_map_page, + .unmap_page = dma_direct_unmap_page, + .sync_single_for_cpu = dma_direct_sync_single_for_cpu, + .sync_single_for_device = dma_direct_sync_single_for_device, + .sync_sg_for_cpu = dma_direct_sync_sg_for_cpu, + .sync_sg_for_device = dma_direct_sync_sg_for_device, .get_required_mask = swiotlb_powerpc_get_required, };
arch/riscv/include/asm/dma-mapping.h deleted +0 -15
@@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef _RISCV_ASM_DMA_MAPPING_H -#define _RISCV_ASM_DMA_MAPPING_H 1 - -#ifdef CONFIG_SWIOTLB -#include <linux/swiotlb.h> -static inline const struct dma_map_ops *get_arch_dma_ops (struct bus_type *bus) -{ -return &swiotlb_dma_ops; -} -#else -#include <asm-generic/dma-mapping.h> -#endif /* CONFIG_SWIOTLB */ - -#endif /* _RISCV_ASM_DMA_MAPPING_H */
arch/x86/kernel/pci-swiotlb.c +1 -3
@@ -62,10 +62,8 @@ IOMMU_INIT(pci_swiotlb_detect_4gb,void __init pci_swiotlb_init (void ) { -if (swiotlb) { +if (swiotlb)swiotlb_init (0 ); - dma_ops = &swiotlb_dma_ops; - } }void __init pci_swiotlb_late_init (void )
arch/x86/mm/mem_encrypt.c +0 -7
@@ -380,13 +380,6 @@ void __init mem_encrypt_init(void)/* Call into SWIOTLB to update the SWIOTLB DMA buffers */ swiotlb_update_mem_attributes (); -/* -* With SEV, DMA operations cannot use encryption, we need to use -* SWIOTLB to bounce buffer DMA operation. -*/ -if (sev_active ()) - dma_ops = &swiotlb_dma_ops; -/* * With SEV, we need to unroll the rep string I/O instructions. */
arch/x86/pci/sta2x11-fixup.c +0 -1
@@ -168,7 +168,6 @@ static void sta2x11_setup_pdev(struct pci_dev *pdev)return ;pci_set_consistent_dma_mask (pdev,STA2X11_AMBA_SIZE -1 );pci_set_dma_mask (pdev,STA2X11_AMBA_SIZE -1 ); - pdev->dev.dma_ops = &swiotlb_dma_ops; pdev->dev.archdata.is_sta2x11 = true;/* We must enable all devices as master, for audio DMA to work */
include/linux/dma-direct.h +12 -0
@@ -63,7 +63,19 @@ void __dma_direct_free_pages(struct device *dev, size_t size, struct page *page)dma_addr_t dma_direct_map_page (struct device *dev,struct page *page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs); +void dma_direct_unmap_page (struct device *dev,dma_addr_t addr, +size_t size,enum dma_data_direction dir,unsigned long attrs);int dma_direct_map_sg (struct device *dev,struct scatterlist *sgl,int nents,enum dma_data_direction dir,unsigned long attrs); +void dma_direct_unmap_sg (struct device *dev,struct scatterlist *sgl, +int nents,enum dma_data_direction dir,unsigned long attrs); +void dma_direct_sync_single_for_device (struct device *dev, +dma_addr_t addr,size_t size,enum dma_data_direction dir); +void dma_direct_sync_sg_for_device (struct device *dev, +struct scatterlist *sgl,int nents,enum dma_data_direction dir); +void dma_direct_sync_single_for_cpu (struct device *dev, +dma_addr_t addr,size_t size,enum dma_data_direction dir); +void dma_direct_sync_sg_for_cpu (struct device *dev, +struct scatterlist *sgl,int nents,enum dma_data_direction dir);int dma_direct_supported (struct device *dev,u64 mask);#endif /* _LINUX_DMA_DIRECT_H */
include/linux/swiotlb.h +24 -44
88 lines not on this page · raw message
kernel/dma/direct.c +81 -32
192 lines not on this page · raw message
kernel/dma/swiotlb.c +13 -214
266 lines not on this page · raw message
Signature · 1 line
2.19.1