|
@@ -71,6 +71,49 @@
|
|
|
#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
|
|
|
#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
|
|
|
|
|
|
+/* page table handling */
|
|
|
+#define LEVEL_STRIDE (9)
|
|
|
+#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
|
|
|
+
|
|
|
+static inline int agaw_to_level(int agaw)
|
|
|
+{
|
|
|
+ return agaw + 2;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int agaw_to_width(int agaw)
|
|
|
+{
|
|
|
+ return 30 + agaw * LEVEL_STRIDE;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int width_to_agaw(int width)
|
|
|
+{
|
|
|
+ return (width - 30) / LEVEL_STRIDE;
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned int level_to_offset_bits(int level)
|
|
|
+{
|
|
|
+ return (level - 1) * LEVEL_STRIDE;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int pfn_level_offset(unsigned long pfn, int level)
|
|
|
+{
|
|
|
+ return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned long level_mask(int level)
|
|
|
+{
|
|
|
+ return -1UL << level_to_offset_bits(level);
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned long level_size(int level)
|
|
|
+{
|
|
|
+ return 1UL << level_to_offset_bits(level);
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned long align_to_level(unsigned long pfn, int level)
|
|
|
+{
|
|
|
+ return (pfn + level_size(level) - 1) & level_mask(level);
|
|
|
+}
|
|
|
|
|
|
/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
|
|
|
are never going to work. */
|
|
@@ -434,8 +477,6 @@ void free_iova_mem(struct iova *iova)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static inline int width_to_agaw(int width);
|
|
|
-
|
|
|
static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
|
|
|
{
|
|
|
unsigned long sagaw;
|
|
@@ -646,51 +687,6 @@ out:
|
|
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
|
|
}
|
|
|
|
|
|
-/* page table handling */
|
|
|
-#define LEVEL_STRIDE (9)
|
|
|
-#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
|
|
|
-
|
|
|
-static inline int agaw_to_level(int agaw)
|
|
|
-{
|
|
|
- return agaw + 2;
|
|
|
-}
|
|
|
-
|
|
|
-static inline int agaw_to_width(int agaw)
|
|
|
-{
|
|
|
- return 30 + agaw * LEVEL_STRIDE;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-static inline int width_to_agaw(int width)
|
|
|
-{
|
|
|
- return (width - 30) / LEVEL_STRIDE;
|
|
|
-}
|
|
|
-
|
|
|
-static inline unsigned int level_to_offset_bits(int level)
|
|
|
-{
|
|
|
- return (level - 1) * LEVEL_STRIDE;
|
|
|
-}
|
|
|
-
|
|
|
-static inline int pfn_level_offset(unsigned long pfn, int level)
|
|
|
-{
|
|
|
- return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
|
|
|
-}
|
|
|
-
|
|
|
-static inline unsigned long level_mask(int level)
|
|
|
-{
|
|
|
- return -1UL << level_to_offset_bits(level);
|
|
|
-}
|
|
|
-
|
|
|
-static inline unsigned long level_size(int level)
|
|
|
-{
|
|
|
- return 1UL << level_to_offset_bits(level);
|
|
|
-}
|
|
|
-
|
|
|
-static inline unsigned long align_to_level(unsigned long pfn, int level)
|
|
|
-{
|
|
|
- return (pfn + level_size(level) - 1) & level_mask(level);
|
|
|
-}
|
|
|
-
|
|
|
static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
|
|
|
unsigned long pfn)
|
|
|
{
|