mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 19:59:34 -04:00
Merge branch 'core' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu into drm/tegra/for-next
This commit is contained in:
@@ -6764,6 +6764,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iommu/
|
||||
F: drivers/iommu/
|
||||
F: include/linux/iommu.h
|
||||
F: include/linux/iova.h
|
||||
|
||||
IP MASQUERADING
|
||||
M: Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar>
|
||||
|
||||
@@ -100,6 +100,34 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert the iova into domain rbtree by holding writer lock */
|
||||
static void
|
||||
iova_insert_rbtree(struct rb_root *root, struct iova *iova,
|
||||
struct rb_node *start)
|
||||
{
|
||||
struct rb_node **new, *parent = NULL;
|
||||
|
||||
new = (start) ? &start : &(root->rb_node);
|
||||
/* Figure out where to put new node */
|
||||
while (*new) {
|
||||
struct iova *this = rb_entry(*new, struct iova, node);
|
||||
|
||||
parent = *new;
|
||||
|
||||
if (iova->pfn_lo < this->pfn_lo)
|
||||
new = &((*new)->rb_left);
|
||||
else if (iova->pfn_lo > this->pfn_lo)
|
||||
new = &((*new)->rb_right);
|
||||
else {
|
||||
WARN_ON(1); /* this should not happen */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Add new node and rebalance tree. */
|
||||
rb_link_node(&iova->node, parent, new);
|
||||
rb_insert_color(&iova->node, root);
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes the padding size required, to make the start address
|
||||
* naturally aligned on the power-of-two order of its size
|
||||
@@ -157,35 +185,8 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
|
||||
new->pfn_lo = limit_pfn - (size + pad_size) + 1;
|
||||
new->pfn_hi = new->pfn_lo + size - 1;
|
||||
|
||||
/* Insert the new_iova into domain rbtree by holding writer lock */
|
||||
/* Add new node and rebalance tree. */
|
||||
{
|
||||
struct rb_node **entry, *parent = NULL;
|
||||
|
||||
/* If we have 'prev', it's a valid place to start the
|
||||
insertion. Otherwise, start from the root. */
|
||||
if (prev)
|
||||
entry = &prev;
|
||||
else
|
||||
entry = &iovad->rbroot.rb_node;
|
||||
|
||||
/* Figure out where to put new node */
|
||||
while (*entry) {
|
||||
struct iova *this = rb_entry(*entry, struct iova, node);
|
||||
parent = *entry;
|
||||
|
||||
if (new->pfn_lo < this->pfn_lo)
|
||||
entry = &((*entry)->rb_left);
|
||||
else if (new->pfn_lo > this->pfn_lo)
|
||||
entry = &((*entry)->rb_right);
|
||||
else
|
||||
BUG(); /* this should not happen */
|
||||
}
|
||||
|
||||
/* Add new node and rebalance tree. */
|
||||
rb_link_node(&new->node, parent, entry);
|
||||
rb_insert_color(&new->node, &iovad->rbroot);
|
||||
}
|
||||
/* If we have 'prev', it's a valid place to start the insertion. */
|
||||
iova_insert_rbtree(&iovad->rbroot, new, prev);
|
||||
__cached_rbnode_insert_update(iovad, saved_pfn, new);
|
||||
|
||||
spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
|
||||
@@ -194,28 +195,6 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iova_insert_rbtree(struct rb_root *root, struct iova *iova)
|
||||
{
|
||||
struct rb_node **new = &(root->rb_node), *parent = NULL;
|
||||
/* Figure out where to put new node */
|
||||
while (*new) {
|
||||
struct iova *this = rb_entry(*new, struct iova, node);
|
||||
|
||||
parent = *new;
|
||||
|
||||
if (iova->pfn_lo < this->pfn_lo)
|
||||
new = &((*new)->rb_left);
|
||||
else if (iova->pfn_lo > this->pfn_lo)
|
||||
new = &((*new)->rb_right);
|
||||
else
|
||||
BUG(); /* this should not happen */
|
||||
}
|
||||
/* Add new node and rebalance tree. */
|
||||
rb_link_node(&iova->node, parent, new);
|
||||
rb_insert_color(&iova->node, root);
|
||||
}
|
||||
|
||||
static struct kmem_cache *iova_cache;
|
||||
static unsigned int iova_cache_users;
|
||||
static DEFINE_MUTEX(iova_cache_mutex);
|
||||
@@ -505,7 +484,7 @@ __insert_new_range(struct iova_domain *iovad,
|
||||
|
||||
iova = alloc_and_init_iova(pfn_lo, pfn_hi);
|
||||
if (iova)
|
||||
iova_insert_rbtree(&iovad->rbroot, iova);
|
||||
iova_insert_rbtree(&iovad->rbroot, iova, NULL);
|
||||
|
||||
return iova;
|
||||
}
|
||||
@@ -612,11 +591,11 @@ split_and_remove_iova(struct iova_domain *iovad, struct iova *iova,
|
||||
rb_erase(&iova->node, &iovad->rbroot);
|
||||
|
||||
if (prev) {
|
||||
iova_insert_rbtree(&iovad->rbroot, prev);
|
||||
iova_insert_rbtree(&iovad->rbroot, prev, NULL);
|
||||
iova->pfn_lo = pfn_lo;
|
||||
}
|
||||
if (next) {
|
||||
iova_insert_rbtree(&iovad->rbroot, next);
|
||||
iova_insert_rbtree(&iovad->rbroot, next, NULL);
|
||||
iova->pfn_hi = pfn_hi;
|
||||
}
|
||||
spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
|
||||
|
||||
@@ -82,6 +82,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
|
||||
return iova >> iova_shift(iovad);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IOMMU_IOVA)
|
||||
int iova_cache_get(void);
|
||||
void iova_cache_put(void);
|
||||
|
||||
@@ -106,5 +107,95 @@ void put_iova_domain(struct iova_domain *iovad);
|
||||
struct iova *split_and_remove_iova(struct iova_domain *iovad,
|
||||
struct iova *iova, unsigned long pfn_lo, unsigned long pfn_hi);
|
||||
void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad);
|
||||
#else
|
||||
static inline int iova_cache_get(void)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void iova_cache_put(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct iova *alloc_iova_mem(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void free_iova_mem(struct iova *iova)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void free_iova(struct iova_domain *iovad, unsigned long pfn)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void __free_iova(struct iova_domain *iovad, struct iova *iova)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct iova *alloc_iova(struct iova_domain *iovad,
|
||||
unsigned long size,
|
||||
unsigned long limit_pfn,
|
||||
bool size_aligned)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void free_iova_fast(struct iova_domain *iovad,
|
||||
unsigned long pfn,
|
||||
unsigned long size)
|
||||
{
|
||||
}
|
||||
|
||||
static inline unsigned long alloc_iova_fast(struct iova_domain *iovad,
|
||||
unsigned long size,
|
||||
unsigned long limit_pfn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct iova *reserve_iova(struct iova_domain *iovad,
|
||||
unsigned long pfn_lo,
|
||||
unsigned long pfn_hi)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void copy_reserved_iova(struct iova_domain *from,
|
||||
struct iova_domain *to)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void init_iova_domain(struct iova_domain *iovad,
|
||||
unsigned long granule,
|
||||
unsigned long start_pfn,
|
||||
unsigned long pfn_32bit)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct iova *find_iova(struct iova_domain *iovad,
|
||||
unsigned long pfn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void put_iova_domain(struct iova_domain *iovad)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct iova *split_and_remove_iova(struct iova_domain *iovad,
|
||||
struct iova *iova,
|
||||
unsigned long pfn_lo,
|
||||
unsigned long pfn_hi)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void free_cpu_cached_iovas(unsigned int cpu,
|
||||
struct iova_domain *iovad)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user