linux/include/linux/iova.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (c) 2006, Intel Corporation.
   4 *
   5 * Copyright (C) 2006-2008 Intel Corporation
   6 * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
   7 */
   8
   9#ifndef _IOVA_H_
  10#define _IOVA_H_
  11
  12#include <linux/types.h>
  13#include <linux/kernel.h>
  14#include <linux/rbtree.h>
  15#include <linux/dma-mapping.h>
  16
  17/* iova structure */
  18struct iova {
  19        struct rb_node  node;
  20        unsigned long   pfn_hi; /* Highest allocated pfn */
  21        unsigned long   pfn_lo; /* Lowest allocated pfn */
  22};
  23
  24struct iova_magazine;
  25struct iova_cpu_rcache;
  26
  27#define IOVA_RANGE_CACHE_MAX_SIZE 6     /* log of max cached IOVA range size (in pages) */
  28#define MAX_GLOBAL_MAGS 32      /* magazines per bin */
  29
  30struct iova_rcache {
  31        spinlock_t lock;
  32        unsigned long depot_size;
  33        struct iova_magazine *depot[MAX_GLOBAL_MAGS];
  34        struct iova_cpu_rcache __percpu *cpu_rcaches;
  35};
  36
  37/* holds all the iova translations for a domain */
  38struct iova_domain {
  39        spinlock_t      iova_rbtree_lock; /* Lock to protect update of rbtree */
  40        struct rb_root  rbroot;         /* iova domain rbtree root */
  41        struct rb_node  *cached_node;   /* Save last alloced node */
  42        struct rb_node  *cached32_node; /* Save last 32-bit alloced node */
  43        unsigned long   granule;        /* pfn granularity for this domain */
  44        unsigned long   start_pfn;      /* Lower limit for this domain */
  45        unsigned long   dma_32bit_pfn;
  46        unsigned long   max32_alloc_size; /* Size of last failed allocation */
  47        struct iova     anchor;         /* rbtree lookup anchor */
  48
  49        struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE];  /* IOVA range caches */
  50        struct hlist_node       cpuhp_dead;
  51};
  52
  53static inline unsigned long iova_size(struct iova *iova)
  54{
  55        return iova->pfn_hi - iova->pfn_lo + 1;
  56}
  57
  58static inline unsigned long iova_shift(struct iova_domain *iovad)
  59{
  60        return __ffs(iovad->granule);
  61}
  62
  63static inline unsigned long iova_mask(struct iova_domain *iovad)
  64{
  65        return iovad->granule - 1;
  66}
  67
  68static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
  69{
  70        return iova & iova_mask(iovad);
  71}
  72
  73static inline size_t iova_align(struct iova_domain *iovad, size_t size)
  74{
  75        return ALIGN(size, iovad->granule);
  76}
  77
  78static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova)
  79{
  80        return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);
  81}
  82
  83static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
  84{
  85        return iova >> iova_shift(iovad);
  86}
  87
  88#if IS_ENABLED(CONFIG_IOMMU_IOVA)
  89int iova_cache_get(void);
  90void iova_cache_put(void);
  91
  92void free_iova(struct iova_domain *iovad, unsigned long pfn);
  93void __free_iova(struct iova_domain *iovad, struct iova *iova);
  94struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
  95        unsigned long limit_pfn,
  96        bool size_aligned);
  97void free_iova_fast(struct iova_domain *iovad, unsigned long pfn,
  98                    unsigned long size);
  99unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size,
 100                              unsigned long limit_pfn, bool flush_rcache);
 101struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
 102        unsigned long pfn_hi);
 103void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
 104        unsigned long start_pfn);
 105struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
 106void put_iova_domain(struct iova_domain *iovad);
 107#else
 108static inline int iova_cache_get(void)
 109{
 110        return -ENOTSUPP;
 111}
 112
 113static inline void iova_cache_put(void)
 114{
 115}
 116
 117static inline void free_iova(struct iova_domain *iovad, unsigned long pfn)
 118{
 119}
 120
 121static inline void __free_iova(struct iova_domain *iovad, struct iova *iova)
 122{
 123}
 124
 125static inline struct iova *alloc_iova(struct iova_domain *iovad,
 126                                      unsigned long size,
 127                                      unsigned long limit_pfn,
 128                                      bool size_aligned)
 129{
 130        return NULL;
 131}
 132
 133static inline void free_iova_fast(struct iova_domain *iovad,
 134                                  unsigned long pfn,
 135                                  unsigned long size)
 136{
 137}
 138
 139static inline unsigned long alloc_iova_fast(struct iova_domain *iovad,
 140                                            unsigned long size,
 141                                            unsigned long limit_pfn,
 142                                            bool flush_rcache)
 143{
 144        return 0;
 145}
 146
 147static inline struct iova *reserve_iova(struct iova_domain *iovad,
 148                                        unsigned long pfn_lo,
 149                                        unsigned long pfn_hi)
 150{
 151        return NULL;
 152}
 153
 154static inline void init_iova_domain(struct iova_domain *iovad,
 155                                    unsigned long granule,
 156                                    unsigned long start_pfn)
 157{
 158}
 159
 160static inline struct iova *find_iova(struct iova_domain *iovad,
 161                                     unsigned long pfn)
 162{
 163        return NULL;
 164}
 165
 166static inline void put_iova_domain(struct iova_domain *iovad)
 167{
 168}
 169
 170#endif
 171
 172#endif
 173