Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171/* SPDX-License-Identifier: GPL-2.0-only *//* * Copyright (c) 2006, Intel Corporation. * * Copyright (C) 2006-2008 Intel Corporation * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> */
#ifndef _IOVA_H_#define _IOVA_H_
#include <linux/types.h>#include <linux/kernel.h>#include <linux/rbtree.h>#include <linux/dma-mapping.h>
/* iova structure */struct iova { struct rb_node node; unsigned long pfn_hi; /* Highest allocated pfn */ unsigned long pfn_lo; /* Lowest allocated pfn */};
struct iova_rcache;
/* holds all the iova translations for a domain */struct iova_domain { spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ struct rb_root rbroot; /* iova domain rbtree root */ struct rb_node *cached_node; /* Save last alloced node */ struct rb_node *cached32_node; /* Save last 32-bit alloced node */ unsigned long granule; /* pfn granularity for this domain */ unsigned long start_pfn; /* Lower limit for this domain */ unsigned long dma_32bit_pfn; unsigned long max32_alloc_size; /* Size of last failed allocation */ struct iova anchor; /* rbtree lookup anchor */
struct iova_rcache *rcaches; struct hlist_node cpuhp_dead;};
static inline unsigned long iova_size(struct iova *iova){ return iova->pfn_hi - iova->pfn_lo + 1;}
static inline unsigned long iova_shift(struct iova_domain *iovad){ return __ffs(iovad->granule);}
static inline unsigned long iova_mask(struct iova_domain *iovad){ return iovad->granule - 1;}
static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova){ return iova & iova_mask(iovad);}
static inline size_t iova_align(struct iova_domain *iovad, size_t size){ return ALIGN(size, iovad->granule);}
static inline size_t iova_align_down(struct iova_domain *iovad, size_t size){ return ALIGN_DOWN(size, iovad->granule);}
static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova){ return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);}
static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova){ return iova >> iova_shift(iovad);}
#if IS_REACHABLE(CONFIG_IOMMU_IOVA)int iova_cache_get(void);void iova_cache_put(void);
unsigned long iova_rcache_range(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, unsigned long limit_pfn, bool size_aligned);void free_iova_fast(struct iova_domain *iovad, unsigned long pfn, unsigned long size);unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size, unsigned long limit_pfn, bool flush_rcache);struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, unsigned long pfn_hi);void init_iova_domain(struct iova_domain *iovad, unsigned long granule, unsigned long start_pfn);int iova_domain_init_rcaches(struct iova_domain *iovad);struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);void put_iova_domain(struct iova_domain *iovad);#elsestatic inline int iova_cache_get(void){ return -ENOTSUPP;}
static inline void iova_cache_put(void){}
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, bool flush_rcache){ 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 init_iova_domain(struct iova_domain *iovad, unsigned long granule, unsigned long start_pfn){}
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){}
#endif
#endif