Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (c) 2006, Intel Corporation.
0004  *
0005  * Copyright (C) 2006-2008 Intel Corporation
0006  * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
0007  */
0008 
0009 #ifndef _IOVA_H_
0010 #define _IOVA_H_
0011 
0012 #include <linux/types.h>
0013 #include <linux/kernel.h>
0014 #include <linux/rbtree.h>
0015 #include <linux/dma-mapping.h>
0016 
0017 /* iova structure */
0018 struct iova {
0019     struct rb_node  node;
0020     unsigned long   pfn_hi; /* Highest allocated pfn */
0021     unsigned long   pfn_lo; /* Lowest allocated pfn */
0022 };
0023 
0024 
0025 struct iova_rcache;
0026 
0027 /* holds all the iova translations for a domain */
0028 struct iova_domain {
0029     spinlock_t  iova_rbtree_lock; /* Lock to protect update of rbtree */
0030     struct rb_root  rbroot;     /* iova domain rbtree root */
0031     struct rb_node  *cached_node;   /* Save last alloced node */
0032     struct rb_node  *cached32_node; /* Save last 32-bit alloced node */
0033     unsigned long   granule;    /* pfn granularity for this domain */
0034     unsigned long   start_pfn;  /* Lower limit for this domain */
0035     unsigned long   dma_32bit_pfn;
0036     unsigned long   max32_alloc_size; /* Size of last failed allocation */
0037     struct iova anchor;     /* rbtree lookup anchor */
0038 
0039     struct iova_rcache  *rcaches;
0040     struct hlist_node   cpuhp_dead;
0041 };
0042 
0043 static inline unsigned long iova_size(struct iova *iova)
0044 {
0045     return iova->pfn_hi - iova->pfn_lo + 1;
0046 }
0047 
0048 static inline unsigned long iova_shift(struct iova_domain *iovad)
0049 {
0050     return __ffs(iovad->granule);
0051 }
0052 
0053 static inline unsigned long iova_mask(struct iova_domain *iovad)
0054 {
0055     return iovad->granule - 1;
0056 }
0057 
0058 static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
0059 {
0060     return iova & iova_mask(iovad);
0061 }
0062 
0063 static inline size_t iova_align(struct iova_domain *iovad, size_t size)
0064 {
0065     return ALIGN(size, iovad->granule);
0066 }
0067 
0068 static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova)
0069 {
0070     return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);
0071 }
0072 
0073 static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
0074 {
0075     return iova >> iova_shift(iovad);
0076 }
0077 
0078 #if IS_ENABLED(CONFIG_IOMMU_IOVA)
0079 int iova_cache_get(void);
0080 void iova_cache_put(void);
0081 
0082 unsigned long iova_rcache_range(void);
0083 
0084 void free_iova(struct iova_domain *iovad, unsigned long pfn);
0085 void __free_iova(struct iova_domain *iovad, struct iova *iova);
0086 struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
0087     unsigned long limit_pfn,
0088     bool size_aligned);
0089 void free_iova_fast(struct iova_domain *iovad, unsigned long pfn,
0090             unsigned long size);
0091 unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size,
0092                   unsigned long limit_pfn, bool flush_rcache);
0093 struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
0094     unsigned long pfn_hi);
0095 void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
0096     unsigned long start_pfn);
0097 int iova_domain_init_rcaches(struct iova_domain *iovad);
0098 struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
0099 void put_iova_domain(struct iova_domain *iovad);
0100 #else
0101 static inline int iova_cache_get(void)
0102 {
0103     return -ENOTSUPP;
0104 }
0105 
0106 static inline void iova_cache_put(void)
0107 {
0108 }
0109 
0110 static inline void free_iova(struct iova_domain *iovad, unsigned long pfn)
0111 {
0112 }
0113 
0114 static inline void __free_iova(struct iova_domain *iovad, struct iova *iova)
0115 {
0116 }
0117 
0118 static inline struct iova *alloc_iova(struct iova_domain *iovad,
0119                       unsigned long size,
0120                       unsigned long limit_pfn,
0121                       bool size_aligned)
0122 {
0123     return NULL;
0124 }
0125 
0126 static inline void free_iova_fast(struct iova_domain *iovad,
0127                   unsigned long pfn,
0128                   unsigned long size)
0129 {
0130 }
0131 
0132 static inline unsigned long alloc_iova_fast(struct iova_domain *iovad,
0133                         unsigned long size,
0134                         unsigned long limit_pfn,
0135                         bool flush_rcache)
0136 {
0137     return 0;
0138 }
0139 
0140 static inline struct iova *reserve_iova(struct iova_domain *iovad,
0141                     unsigned long pfn_lo,
0142                     unsigned long pfn_hi)
0143 {
0144     return NULL;
0145 }
0146 
0147 static inline void init_iova_domain(struct iova_domain *iovad,
0148                     unsigned long granule,
0149                     unsigned long start_pfn)
0150 {
0151 }
0152 
0153 static inline struct iova *find_iova(struct iova_domain *iovad,
0154                      unsigned long pfn)
0155 {
0156     return NULL;
0157 }
0158 
0159 static inline void put_iova_domain(struct iova_domain *iovad)
0160 {
0161 }
0162 
0163 #endif
0164 
0165 #endif