diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 117 |
1 files changed, 70 insertions, 47 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index c3ceebb5be84..4789f8e8bf7a 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 | { |
@@ -3761,6 +3757,33 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | |||
3761 | 3757 | ||
3762 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); | 3758 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); |
3763 | 3759 | ||
3760 | #define GGC 0x52 | ||
3761 | #define GGC_MEMORY_SIZE_MASK (0xf << 8) | ||
3762 | #define GGC_MEMORY_SIZE_NONE (0x0 << 8) | ||
3763 | #define GGC_MEMORY_SIZE_1M (0x1 << 8) | ||
3764 | #define GGC_MEMORY_SIZE_2M (0x3 << 8) | ||
3765 | #define GGC_MEMORY_VT_ENABLED (0x8 << 8) | ||
3766 | #define GGC_MEMORY_SIZE_2M_VT (0x9 << 8) | ||
3767 | #define GGC_MEMORY_SIZE_3M_VT (0xa << 8) | ||
3768 | #define GGC_MEMORY_SIZE_4M_VT (0xb << 8) | ||
3769 | |||
3770 | static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev) | ||
3771 | { | ||
3772 | unsigned short ggc; | ||
3773 | |||
3774 | if (pci_read_config_word(dev, GGC, &ggc)) | ||
3775 | return; | ||
3776 | |||
3777 | if (!(ggc & GGC_MEMORY_VT_ENABLED)) { | ||
3778 | printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n"); | ||
3779 | dmar_map_gfx = 0; | ||
3780 | } | ||
3781 | } | ||
3782 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); | ||
3783 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt); | ||
3784 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt); | ||
3785 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt); | ||
3786 | |||
3764 | /* On Tylersburg chipsets, some BIOSes have been known to enable the | 3787 | /* On Tylersburg chipsets, some BIOSes have been known to enable the |
3765 | ISOCH DMAR unit for the Azalia sound device, but not give it any | 3788 | ISOCH DMAR unit for the Azalia sound device, but not give it any |
3766 | TLB entries, which causes it to deadlock. Check for that. We do | 3789 | TLB entries, which causes it to deadlock. Check for that. We do |