|
@@ -36,6 +36,30 @@ struct iova_rcache {
|
|
|
struct iova_cpu_rcache __percpu *cpu_rcaches;
|
|
|
};
|
|
|
|
|
|
+struct iova_domain;
|
|
|
+
|
|
|
+/* Call-Back from IOVA code into IOMMU drivers */
|
|
|
+typedef void (* iova_flush_cb)(struct iova_domain *domain);
|
|
|
+
|
|
|
+/* Destructor for per-entry data */
|
|
|
+typedef void (* iova_entry_dtor)(unsigned long data);
|
|
|
+
|
|
|
+/* Number of entries per Flush Queue */
|
|
|
+#define IOVA_FQ_SIZE 256
|
|
|
+
|
|
|
+/* Flush Queue entry for defered flushing */
|
|
|
+struct iova_fq_entry {
|
|
|
+ unsigned long iova_pfn;
|
|
|
+ unsigned long pages;
|
|
|
+ unsigned long data;
|
|
|
+};
|
|
|
+
|
|
|
+/* Per-CPU Flush Queue structure */
|
|
|
+struct iova_fq {
|
|
|
+ struct iova_fq_entry entries[IOVA_FQ_SIZE];
|
|
|
+ unsigned head, tail;
|
|
|
+};
|
|
|
+
|
|
|
/* holds all the iova translations for a domain */
|
|
|
struct iova_domain {
|
|
|
spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */
|
|
@@ -45,6 +69,14 @@ struct iova_domain {
|
|
|
unsigned long start_pfn; /* Lower limit for this domain */
|
|
|
unsigned long dma_32bit_pfn;
|
|
|
struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE]; /* IOVA range caches */
|
|
|
+
|
|
|
+ iova_flush_cb flush_cb; /* Call-Back function to flush IOMMU
|
|
|
+ TLBs */
|
|
|
+
|
|
|
+ iova_entry_dtor entry_dtor; /* IOMMU driver specific destructor for
|
|
|
+ iova entry */
|
|
|
+
|
|
|
+ struct iova_fq __percpu *fq; /* Flush Queue */
|
|
|
};
|
|
|
|
|
|
static inline unsigned long iova_size(struct iova *iova)
|
|
@@ -102,6 +134,8 @@ struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
|
|
|
void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
|
|
|
void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
|
|
|
unsigned long start_pfn, unsigned long pfn_32bit);
|
|
|
+int init_iova_flush_queue(struct iova_domain *iovad,
|
|
|
+ iova_flush_cb flush_cb, iova_entry_dtor entry_dtor);
|
|
|
struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
|
|
|
void put_iova_domain(struct iova_domain *iovad);
|
|
|
struct iova *split_and_remove_iova(struct iova_domain *iovad,
|
|
@@ -174,6 +208,13 @@ static inline void init_iova_domain(struct iova_domain *iovad,
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+static inline int init_iova_flush_queue(struct iova_domain *iovad,
|
|
|
+ iova_flush_cb flush_cb,
|
|
|
+ iova_entry_dtor entry_dtor)
|
|
|
+{
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
static inline struct iova *find_iova(struct iova_domain *iovad,
|
|
|
unsigned long pfn)
|
|
|
{
|