Separate the IOVA library from the intel-iommu driver
Subsystems (4)
cover Separate the IOVA library from the intel-iommu driver
Hi,
This set separates the IOVA library from the intel-iommu driver, and makes it usable for other implementations (such as DMA mapping) as well.
While I don't have a DMA mapping implementation to share at the moment, the patches might be useful for the others in the meantime and I wouldn't mind having them in upstream either.
Signature · 2 lines
Kind regards, Sakari
A message that is not in the archive (sent off-list or not yet received): 1416568303-677-1-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/[email protected]
RFC 1/4 iommu: iova: Move iova cache management to the iova library
alloc_iova_mem() and free_iova_mem() are moved to iova.c and made static as well. printk(KERN_ERR, ...) is also replaced by pr_err().
This is done in order to separate intel-iommu from the iova library. As a result, the user of the IOVA library must use iova_cache_get() before using alloc_iova_mem() or free_iova_mem(), and correspondingly iova_cache_put() after using the IOVA library.
--- drivers/iommu/intel-iommu.c | 34 +++----------------------------- drivers/iommu/iova.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/iova.h | 4 ++-- 3 files changed, 53 insertions(+), 33 deletions(-)
drivers/iommu/intel-iommu.c +3 -31
@@ -490,7 +490,6 @@ __setup("intel_iommu=", intel_iommu_setup);static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache; -static struct kmem_cache *iommu_iova_cache;static inline void *alloc_pgtable_page (int node) {
@@ -528,16 +527,6 @@ static inline void free_devinfo_mem(void *vaddr)kmem_cache_free (iommu_devinfo_cache, vaddr); } -struct iova *alloc_iova_mem (void ) -{ -return kmem_cache_alloc (iommu_iova_cache,GFP_ATOMIC ); -} - -void free_iova_mem (struct iova *iova) -{ -kmem_cache_free (iommu_iova_cache, iova); -} -static inline int domain_type_is_vm (struct dmar_domain *domain) {return domain->flags &DOMAIN_FLAG_VIRTUAL_MACHINE ;
@@ -3429,27 +3418,10 @@ static inline int iommu_devinfo_cache_init(void)return ret; } -static inline int iommu_iova_cache_init (void ) -{ -int ret =0 ; - - iommu_iova_cache =kmem_cache_create ("iommu_iova" , -sizeof (struct iova ), -0 , -SLAB_HWCACHE_ALIGN , -NULL ); -if (!iommu_iova_cache) { -printk (KERN_ERR "Couldn't create iova cache\n" ); - ret = -ENOMEM ; - } - -return ret; -} -static int __init iommu_init_mempool (void ) {int ret; - ret =iommu_iova_cache_init (); + ret =iova_cache_get ();if (ret)return ret;
@@ -3463,7 +3435,7 @@ static int __init iommu_init_mempool(void)kmem_cache_destroy (iommu_domain_cache); domain_error: -kmem_cache_destroy (iommu_iova_cache); +iova_cache_put ();return -ENOMEM ; }
@@ -3472,7 +3444,7 @@ static void __init iommu_exit_mempool(void) {kmem_cache_destroy (iommu_devinfo_cache);kmem_cache_destroy (iommu_domain_cache); -kmem_cache_destroy (iommu_iova_cache); +iova_cache_put (); }
drivers/iommu/iova.c +48 -0
60 lines not on this page · raw message
include/linux/iova.h +2 -2
@@ -39,8 +39,8 @@ static inline unsigned long iova_size(struct iova *iova)return iova->pfn_hi - iova->pfn_lo +1 ; } -struct iova *alloc_iova_mem (void ); -void free_iova_mem (struct iova *iova); +int iova_cache_get (void ); +void iova_cache_put (void );void free_iova (struct iova_domain *iovad,unsigned long pfn);void __free_iova (struct iova_domain *iovad,struct iova *iova); struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
Signature · 1 line
2.1.0.231.g7484e3b
RFC 2/4 iommu: iova: Export symbols
In reply to a message not in the archiveUse EXPORT_SYMBOL_GPL() to export the iova library symbols. The symbols include:
init_iova_domain(); iova_cache_get(); iova_cache_put(); alloc_iova(); find_iova(); __free_iova(); free_iova(); put_iova_domain(); reserve_iova();
This is necessary in order to use the iova library from a kernel module.
--- drivers/iommu/iova.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/iommu/iova.c +9 -0
@@ -28,6 +28,7 @@ init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit) iovad->cached32_node =NULL ; iovad->dma_32bit_pfn = pfn_32bit; } +EXPORT_SYMBOL_GPL (init_iova_domain);static struct rb_node *__get_cached_rbnode (struct iova_domain *iovad,unsigned long *limit_pfn)
@@ -230,6 +231,7 @@ int iova_cache_get(void)return 0 ; } +EXPORT_SYMBOL_GPL (iova_cache_get);void iova_cache_put (void ) {
@@ -243,6 +245,7 @@ void iova_cache_put(void)kmem_cache_destroy (iova_cache);mutex_unlock (&iova_cache_mutex); } +EXPORT_SYMBOL_GPL (iova_cache_put);/** * alloc_iova - allocates an iova
@@ -283,6 +286,7 @@ alloc_iova(struct iova_domain *iovad, unsigned long size,return new_iova; } +EXPORT_SYMBOL_GPL (alloc_iova);/** * find_iova - find's an iova for a given pfn
@@ -323,6 +327,7 @@ struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)spin_unlock_irqrestore (&iovad->iova_rbtree_lock, flags);return NULL ; } +EXPORT_SYMBOL_GPL (find_iova);/** * __free_iova - frees the given iova
@@ -341,6 +346,7 @@ __free_iova(struct iova_domain *iovad, struct iova *iova)spin_unlock_irqrestore (&iovad->iova_rbtree_lock, flags);free_iova_mem (iova); } +EXPORT_SYMBOL_GPL (__free_iova);/** * free_iova - finds and frees the iova for a given pfn
@@ -357,6 +363,7 @@ free_iova(struct iova_domain *iovad, unsigned long pfn)__free_iova (iovad, iova); } +EXPORT_SYMBOL_GPL (free_iova);/** * put_iova_domain - destroys the iova doamin
@@ -378,6 +385,7 @@ void put_iova_domain(struct iova_domain *iovad) }spin_unlock_irqrestore (&iovad->iova_rbtree_lock, flags); } +EXPORT_SYMBOL_GPL (put_iova_domain); static int __is_range_overlap(struct rb_node *node,
@@ -467,6 +475,7 @@ finish:spin_unlock_irqrestore (&iovad->iova_rbtree_lock, flags);return iova; } +EXPORT_SYMBOL_GPL (reserve_iova);/** * copy_reserved_iova - copies the reserved between domains
Signature · 1 line
2.1.0.231.g7484e3b
RFC 3/4 iommu: iova: Make the iova library buildable as a module
In reply to a message not in the archiveThe iova library is usable elsewhere than just the intel-iommu driver, thus make it also buildable a module.
--- drivers/iommu/Kconfig | 4 ++++ drivers/iommu/Makefile | 3 ++- drivers/iommu/iova.c | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-)
drivers/iommu/Kconfig +4 -0
@@ -87,11 +87,15 @@ config AMD_IOMMU_V2 config DMAR_TABLE bool +config IOMMU_IOVA + tristate + config INTEL_IOMMU bool "Support for Intel IOMMU using DMA Remapping Devices" depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC) select IOMMU_API select DMAR_TABLE + select IOMMU_IOVA help DMA remapping (DMAR) devices support enables independent address translations for Direct Memory Access (DMA) from devices.
drivers/iommu/Makefile +2 -1
@@ -7,7 +7,8 @@ obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_DMAR_TABLE) += dmar.o -obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o +obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o +obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
drivers/iommu/iova.c +4 -0
@@ -18,6 +18,7 @@*/ #include <linux/iova.h> +#include <linux/module.h> #include <linux/slab.h> void
@@ -542,3 +543,6 @@ error:free_iova_mem (prev);return NULL ; } + +MODULE_AUTHOR ("Anil S Keshavamurthy <[email protected]>" ); +MODULE_LICENSE ("GPL" );
Signature · 1 line
2.1.0.231.g7484e3b
RFC 4/4 mm: EXPORT_SYMBOL_GPL({find_vm_area,get_vm_area_caller});
In reply to a message not in the archiveThese APIs are needed in DMA mapping API implementation as a module. Device specific IOMMUs with associated DMA mapping implementations should be buildable as modules.
--- mm/vmalloc.c | 2 ++ 1 file changed, 2 insertions(+)
mm/vmalloc.c +2 -0
@@ -1379,6 +1379,7 @@ struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,return __get_vm_area_node (size,1 , flags,VMALLOC_START ,VMALLOC_END ,NUMA_NO_NODE ,GFP_KERNEL , caller); } +EXPORT_SYMBOL_GPL (get_vm_area_caller);/** * find_vm_area - find a continuous kernel virtual area
@@ -1398,6 +1399,7 @@ struct vm_struct *find_vm_area(const void *addr)return NULL ; } +EXPORT_SYMBOL_GPL (find_vm_area);/** * remove_vm_area - find and remove a continuous kernel virtual area
Signature · 1 line
2.1.0.231.g7484e3b
David Woodhouse
Acked-byQuoted 8 lines · Sakari Ailus
Hi,
This set separates the IOVA library from the intel-iommu driver, and makes it usable for other implementations (such as DMA mapping) as well.
While I don't have a DMA mapping implementation to share at the moment, the patches might be useful for the others in the meantime and I wouldn't mind having them in upstream either.
the caveat that I don't actually want to see various IOMMU drivers *using* the IOVA code directly.
Where possible, we really want to be *losing* the separate DMA API implementation, which would do nothing but call this library and then use the underlying IOMMU API functions with the IOVAs that result. Let the whole of that wrapper be generic, rather than just abstracting out the IOVA allocator for everyone to use in their own wrapper.
Signature · 1 line
dwmw2