diff options
| -rw-r--r-- | drivers/pci/intel-iommu.c | 90 |
1 files changed, 43 insertions, 47 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index c3ceebb5be84..5ac2aa783f58 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
| @@ -71,6 +71,49 @@ | |||
| 71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) | 71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) |
| 72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) | 72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) |
| 73 | 73 | ||
| 74 | /* page table handling */ | ||
| 75 | #define LEVEL_STRIDE (9) | ||
| 76 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
| 77 | |||
| 78 | static inline int agaw_to_level(int agaw) | ||
| 79 | { | ||
| 80 | return agaw + 2; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline int agaw_to_width(int agaw) | ||
| 84 | { | ||
| 85 | return 30 + agaw * LEVEL_STRIDE; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline int width_to_agaw(int width) | ||
| 89 | { | ||
| 90 | return (width - 30) / LEVEL_STRIDE; | ||
| 91 | } | ||
| 92 | |||
| 93 | static inline unsigned int level_to_offset_bits(int level) | ||
| 94 | { | ||
| 95 | return (level - 1) * LEVEL_STRIDE; | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
| 99 | { | ||
| 100 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
| 101 | } | ||
| 102 | |||
| 103 | static inline unsigned long level_mask(int level) | ||
| 104 | { | ||
| 105 | return -1UL << level_to_offset_bits(level); | ||
| 106 | } | ||
| 107 | |||
| 108 | static inline unsigned long level_size(int level) | ||
| 109 | { | ||
| 110 | return 1UL << level_to_offset_bits(level); | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
| 114 | { | ||
| 115 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
| 116 | } | ||
| 74 | 117 | ||
| 75 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things | 118 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
| 76 | are never going to work. */ | 119 | are never going to work. */ |
| @@ -434,8 +477,6 @@ void free_iova_mem(struct iova *iova) | |||
| 434 | } | 477 | } |
| 435 | 478 | ||
| 436 | 479 | ||
| 437 | static inline int width_to_agaw(int width); | ||
| 438 | |||
| 439 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) | 480 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) |
| 440 | { | 481 | { |
| 441 | unsigned long sagaw; | 482 | unsigned long sagaw; |
| @@ -646,51 +687,6 @@ out: | |||
| 646 | spin_unlock_irqrestore(&iommu->lock, flags); | 687 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 647 | } | 688 | } |
| 648 | 689 | ||
| 649 | /* page table handling */ | ||
| 650 | #define LEVEL_STRIDE (9) | ||
| 651 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
| 652 | |||
| 653 | static inline int agaw_to_level(int agaw) | ||
| 654 | { | ||
| 655 | return agaw + 2; | ||
| 656 | } | ||
| 657 | |||
| 658 | static inline int agaw_to_width(int agaw) | ||
| 659 | { | ||
| 660 | return 30 + agaw * LEVEL_STRIDE; | ||
| 661 | |||
| 662 | } | ||
| 663 | |||
| 664 | static inline int width_to_agaw(int width) | ||
| 665 | { | ||
| 666 | return (width - 30) / LEVEL_STRIDE; | ||
| 667 | } | ||
| 668 | |||
| 669 | static inline unsigned int level_to_offset_bits(int level) | ||
| 670 | { | ||
| 671 | return (level - 1) * LEVEL_STRIDE; | ||
| 672 | } | ||
| 673 | |||
| 674 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
| 675 | { | ||
| 676 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
| 677 | } | ||
| 678 | |||
| 679 | static inline unsigned long level_mask(int level) | ||
| 680 | { | ||
| 681 | return -1UL << level_to_offset_bits(level); | ||
| 682 | } | ||
| 683 | |||
| 684 | static inline unsigned long level_size(int level) | ||
| 685 | { | ||
| 686 | return 1UL << level_to_offset_bits(level); | ||
| 687 | } | ||
| 688 | |||
| 689 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
| 690 | { | ||
| 691 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
| 692 | } | ||
| 693 | |||
| 694 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | 690 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
| 695 | unsigned long pfn) | 691 | unsigned long pfn) |
| 696 | { | 692 | { |
