diff options
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index c25210e6ac88..de39e1f2ede5 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -29,9 +29,6 @@ | |||
29 | 29 | ||
30 | #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28)) | 30 | #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28)) |
31 | 31 | ||
32 | #define to_pages(addr, size) \ | ||
33 | (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) | ||
34 | |||
35 | #define EXIT_LOOP_COUNT 10000000 | 32 | #define EXIT_LOOP_COUNT 10000000 |
36 | 33 | ||
37 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 34 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
@@ -104,16 +101,13 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
104 | */ | 101 | */ |
105 | static int iommu_completion_wait(struct amd_iommu *iommu) | 102 | static int iommu_completion_wait(struct amd_iommu *iommu) |
106 | { | 103 | { |
107 | int ret; | 104 | int ret, ready = 0; |
105 | unsigned status = 0; | ||
108 | struct iommu_cmd cmd; | 106 | struct iommu_cmd cmd; |
109 | volatile u64 ready = 0; | ||
110 | unsigned long ready_phys = virt_to_phys(&ready); | ||
111 | unsigned long i = 0; | 107 | unsigned long i = 0; |
112 | 108 | ||
113 | memset(&cmd, 0, sizeof(cmd)); | 109 | memset(&cmd, 0, sizeof(cmd)); |
114 | cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK; | 110 | cmd.data[0] = CMD_COMPL_WAIT_INT_MASK; |
115 | cmd.data[1] = upper_32_bits(ready_phys); | ||
116 | cmd.data[2] = 1; /* value written to 'ready' */ | ||
117 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); | 111 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); |
118 | 112 | ||
119 | iommu->need_sync = 0; | 113 | iommu->need_sync = 0; |
@@ -125,9 +119,15 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
125 | 119 | ||
126 | while (!ready && (i < EXIT_LOOP_COUNT)) { | 120 | while (!ready && (i < EXIT_LOOP_COUNT)) { |
127 | ++i; | 121 | ++i; |
128 | cpu_relax(); | 122 | /* wait for the bit to become one */ |
123 | status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
124 | ready = status & MMIO_STATUS_COM_WAIT_INT_MASK; | ||
129 | } | 125 | } |
130 | 126 | ||
127 | /* set bit back to zero */ | ||
128 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | ||
129 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
130 | |||
131 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) | 131 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) |
132 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); | 132 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); |
133 | 133 | ||
@@ -164,7 +164,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | |||
164 | address &= PAGE_MASK; | 164 | address &= PAGE_MASK; |
165 | CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES); | 165 | CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES); |
166 | cmd.data[1] |= domid; | 166 | cmd.data[1] |= domid; |
167 | cmd.data[2] = LOW_U32(address); | 167 | cmd.data[2] = lower_32_bits(address); |
168 | cmd.data[3] = upper_32_bits(address); | 168 | cmd.data[3] = upper_32_bits(address); |
169 | if (s) /* size bit - we flush more than one 4kb page */ | 169 | if (s) /* size bit - we flush more than one 4kb page */ |
170 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | 170 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; |
@@ -185,7 +185,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, | |||
185 | u64 address, size_t size) | 185 | u64 address, size_t size) |
186 | { | 186 | { |
187 | int s = 0; | 187 | int s = 0; |
188 | unsigned pages = to_pages(address, size); | 188 | unsigned pages = iommu_num_pages(address, size); |
189 | 189 | ||
190 | address &= PAGE_MASK; | 190 | address &= PAGE_MASK; |
191 | 191 | ||
@@ -557,8 +557,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
557 | if (iommu->exclusion_start && | 557 | if (iommu->exclusion_start && |
558 | iommu->exclusion_start < dma_dom->aperture_size) { | 558 | iommu->exclusion_start < dma_dom->aperture_size) { |
559 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | 559 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; |
560 | int pages = to_pages(iommu->exclusion_start, | 560 | int pages = iommu_num_pages(iommu->exclusion_start, |
561 | iommu->exclusion_length); | 561 | iommu->exclusion_length); |
562 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | 562 | dma_ops_reserve_addresses(dma_dom, startpage, pages); |
563 | } | 563 | } |
564 | 564 | ||
@@ -667,7 +667,7 @@ static int get_device_resources(struct device *dev, | |||
667 | _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); | 667 | _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); |
668 | 668 | ||
669 | /* device not translated by any IOMMU in the system? */ | 669 | /* device not translated by any IOMMU in the system? */ |
670 | if (_bdf >= amd_iommu_last_bdf) { | 670 | if (_bdf > amd_iommu_last_bdf) { |
671 | *iommu = NULL; | 671 | *iommu = NULL; |
672 | *domain = NULL; | 672 | *domain = NULL; |
673 | *bdf = 0xffff; | 673 | *bdf = 0xffff; |
@@ -767,7 +767,7 @@ static dma_addr_t __map_single(struct device *dev, | |||
767 | unsigned int pages; | 767 | unsigned int pages; |
768 | int i; | 768 | int i; |
769 | 769 | ||
770 | pages = to_pages(paddr, size); | 770 | pages = iommu_num_pages(paddr, size); |
771 | paddr &= PAGE_MASK; | 771 | paddr &= PAGE_MASK; |
772 | 772 | ||
773 | address = dma_ops_alloc_addresses(dev, dma_dom, pages); | 773 | address = dma_ops_alloc_addresses(dev, dma_dom, pages); |
@@ -802,7 +802,7 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
802 | if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size)) | 802 | if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size)) |
803 | return; | 803 | return; |
804 | 804 | ||
805 | pages = to_pages(dma_addr, size); | 805 | pages = iommu_num_pages(dma_addr, size); |
806 | dma_addr &= PAGE_MASK; | 806 | dma_addr &= PAGE_MASK; |
807 | start = dma_addr; | 807 | start = dma_addr; |
808 | 808 | ||
@@ -1085,7 +1085,7 @@ void prealloc_protection_domains(void) | |||
1085 | 1085 | ||
1086 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 1086 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
1087 | devid = (dev->bus->number << 8) | dev->devfn; | 1087 | devid = (dev->bus->number << 8) | dev->devfn; |
1088 | if (devid >= amd_iommu_last_bdf) | 1088 | if (devid > amd_iommu_last_bdf) |
1089 | continue; | 1089 | continue; |
1090 | devid = amd_iommu_alias_table[devid]; | 1090 | devid = amd_iommu_alias_table[devid]; |
1091 | if (domain_for_device(devid)) | 1091 | if (domain_for_device(devid)) |