diff options
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 883 |
1 files changed, 845 insertions, 38 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 4ee277a8521a..cce1f03b8895 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/ratelimit.h> | ||
20 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
21 | #include <linux/pci-ats.h> | 22 | #include <linux/pci-ats.h> |
22 | #include <linux/bitmap.h> | 23 | #include <linux/bitmap.h> |
@@ -28,6 +29,8 @@ | |||
28 | #include <linux/iommu.h> | 29 | #include <linux/iommu.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/amd-iommu.h> | 31 | #include <linux/amd-iommu.h> |
32 | #include <linux/notifier.h> | ||
33 | #include <linux/export.h> | ||
31 | #include <asm/msidef.h> | 34 | #include <asm/msidef.h> |
32 | #include <asm/proto.h> | 35 | #include <asm/proto.h> |
33 | #include <asm/iommu.h> | 36 | #include <asm/iommu.h> |
@@ -41,6 +44,24 @@ | |||
41 | 44 | ||
42 | #define LOOP_TIMEOUT 100000 | 45 | #define LOOP_TIMEOUT 100000 |
43 | 46 | ||
47 | /* | ||
48 | * This bitmap is used to advertise the page sizes our hardware support | ||
49 | * to the IOMMU core, which will then use this information to split | ||
50 | * physically contiguous memory regions it is mapping into page sizes | ||
51 | * that we support. | ||
52 | * | ||
53 | * Traditionally the IOMMU core just handed us the mappings directly, | ||
54 | * after making sure the size is an order of a 4KiB page and that the | ||
55 | * mapping has natural alignment. | ||
56 | * | ||
57 | * To retain this behavior, we currently advertise that we support | ||
58 | * all page sizes that are an order of 4KiB. | ||
59 | * | ||
60 | * If at some point we'd like to utilize the IOMMU core's new behavior, | ||
61 | * we could change this to advertise the real page sizes we support. | ||
62 | */ | ||
63 | #define AMD_IOMMU_PGSIZES (~0xFFFUL) | ||
64 | |||
44 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 65 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
45 | 66 | ||
46 | /* A list of preallocated protection domains */ | 67 | /* A list of preallocated protection domains */ |
@@ -59,6 +80,9 @@ static struct protection_domain *pt_domain; | |||
59 | 80 | ||
60 | static struct iommu_ops amd_iommu_ops; | 81 | static struct iommu_ops amd_iommu_ops; |
61 | 82 | ||
83 | static ATOMIC_NOTIFIER_HEAD(ppr_notifier); | ||
84 | int amd_iommu_max_glx_val = -1; | ||
85 | |||
62 | /* | 86 | /* |
63 | * general struct to manage commands send to an IOMMU | 87 | * general struct to manage commands send to an IOMMU |
64 | */ | 88 | */ |
@@ -67,6 +91,7 @@ struct iommu_cmd { | |||
67 | }; | 91 | }; |
68 | 92 | ||
69 | static void update_domain(struct protection_domain *domain); | 93 | static void update_domain(struct protection_domain *domain); |
94 | static int __init alloc_passthrough_domain(void); | ||
70 | 95 | ||
71 | /**************************************************************************** | 96 | /**************************************************************************** |
72 | * | 97 | * |
@@ -147,6 +172,33 @@ static struct iommu_dev_data *get_dev_data(struct device *dev) | |||
147 | return dev->archdata.iommu; | 172 | return dev->archdata.iommu; |
148 | } | 173 | } |
149 | 174 | ||
175 | static bool pci_iommuv2_capable(struct pci_dev *pdev) | ||
176 | { | ||
177 | static const int caps[] = { | ||
178 | PCI_EXT_CAP_ID_ATS, | ||
179 | PCI_EXT_CAP_ID_PRI, | ||
180 | PCI_EXT_CAP_ID_PASID, | ||
181 | }; | ||
182 | int i, pos; | ||
183 | |||
184 | for (i = 0; i < 3; ++i) { | ||
185 | pos = pci_find_ext_capability(pdev, caps[i]); | ||
186 | if (pos == 0) | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | |||
193 | static bool pdev_pri_erratum(struct pci_dev *pdev, u32 erratum) | ||
194 | { | ||
195 | struct iommu_dev_data *dev_data; | ||
196 | |||
197 | dev_data = get_dev_data(&pdev->dev); | ||
198 | |||
199 | return dev_data->errata & (1 << erratum) ? true : false; | ||
200 | } | ||
201 | |||
150 | /* | 202 | /* |
151 | * In this function the list of preallocated protection domains is traversed to | 203 | * In this function the list of preallocated protection domains is traversed to |
152 | * find the domain for a specific device | 204 | * find the domain for a specific device |
@@ -204,6 +256,7 @@ static bool check_device(struct device *dev) | |||
204 | 256 | ||
205 | static int iommu_init_device(struct device *dev) | 257 | static int iommu_init_device(struct device *dev) |
206 | { | 258 | { |
259 | struct pci_dev *pdev = to_pci_dev(dev); | ||
207 | struct iommu_dev_data *dev_data; | 260 | struct iommu_dev_data *dev_data; |
208 | u16 alias; | 261 | u16 alias; |
209 | 262 | ||
@@ -228,6 +281,13 @@ static int iommu_init_device(struct device *dev) | |||
228 | dev_data->alias_data = alias_data; | 281 | dev_data->alias_data = alias_data; |
229 | } | 282 | } |
230 | 283 | ||
284 | if (pci_iommuv2_capable(pdev)) { | ||
285 | struct amd_iommu *iommu; | ||
286 | |||
287 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
288 | dev_data->iommu_v2 = iommu->is_iommu_v2; | ||
289 | } | ||
290 | |||
231 | dev->archdata.iommu = dev_data; | 291 | dev->archdata.iommu = dev_data; |
232 | 292 | ||
233 | return 0; | 293 | return 0; |
@@ -317,6 +377,11 @@ DECLARE_STATS_COUNTER(domain_flush_single); | |||
317 | DECLARE_STATS_COUNTER(domain_flush_all); | 377 | DECLARE_STATS_COUNTER(domain_flush_all); |
318 | DECLARE_STATS_COUNTER(alloced_io_mem); | 378 | DECLARE_STATS_COUNTER(alloced_io_mem); |
319 | DECLARE_STATS_COUNTER(total_map_requests); | 379 | DECLARE_STATS_COUNTER(total_map_requests); |
380 | DECLARE_STATS_COUNTER(complete_ppr); | ||
381 | DECLARE_STATS_COUNTER(invalidate_iotlb); | ||
382 | DECLARE_STATS_COUNTER(invalidate_iotlb_all); | ||
383 | DECLARE_STATS_COUNTER(pri_requests); | ||
384 | |||
320 | 385 | ||
321 | static struct dentry *stats_dir; | 386 | static struct dentry *stats_dir; |
322 | static struct dentry *de_fflush; | 387 | static struct dentry *de_fflush; |
@@ -351,6 +416,10 @@ static void amd_iommu_stats_init(void) | |||
351 | amd_iommu_stats_add(&domain_flush_all); | 416 | amd_iommu_stats_add(&domain_flush_all); |
352 | amd_iommu_stats_add(&alloced_io_mem); | 417 | amd_iommu_stats_add(&alloced_io_mem); |
353 | amd_iommu_stats_add(&total_map_requests); | 418 | amd_iommu_stats_add(&total_map_requests); |
419 | amd_iommu_stats_add(&complete_ppr); | ||
420 | amd_iommu_stats_add(&invalidate_iotlb); | ||
421 | amd_iommu_stats_add(&invalidate_iotlb_all); | ||
422 | amd_iommu_stats_add(&pri_requests); | ||
354 | } | 423 | } |
355 | 424 | ||
356 | #endif | 425 | #endif |
@@ -365,8 +434,8 @@ static void dump_dte_entry(u16 devid) | |||
365 | { | 434 | { |
366 | int i; | 435 | int i; |
367 | 436 | ||
368 | for (i = 0; i < 8; ++i) | 437 | for (i = 0; i < 4; ++i) |
369 | pr_err("AMD-Vi: DTE[%d]: %08x\n", i, | 438 | pr_err("AMD-Vi: DTE[%d]: %016llx\n", i, |
370 | amd_iommu_dev_table[devid].data[i]); | 439 | amd_iommu_dev_table[devid].data[i]); |
371 | } | 440 | } |
372 | 441 | ||
@@ -461,12 +530,84 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
461 | spin_unlock_irqrestore(&iommu->lock, flags); | 530 | spin_unlock_irqrestore(&iommu->lock, flags); |
462 | } | 531 | } |
463 | 532 | ||
533 | static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head) | ||
534 | { | ||
535 | struct amd_iommu_fault fault; | ||
536 | volatile u64 *raw; | ||
537 | int i; | ||
538 | |||
539 | INC_STATS_COUNTER(pri_requests); | ||
540 | |||
541 | raw = (u64 *)(iommu->ppr_log + head); | ||
542 | |||
543 | /* | ||
544 | * Hardware bug: Interrupt may arrive before the entry is written to | ||
545 | * memory. If this happens we need to wait for the entry to arrive. | ||
546 | */ | ||
547 | for (i = 0; i < LOOP_TIMEOUT; ++i) { | ||
548 | if (PPR_REQ_TYPE(raw[0]) != 0) | ||
549 | break; | ||
550 | udelay(1); | ||
551 | } | ||
552 | |||
553 | if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) { | ||
554 | pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n"); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | fault.address = raw[1]; | ||
559 | fault.pasid = PPR_PASID(raw[0]); | ||
560 | fault.device_id = PPR_DEVID(raw[0]); | ||
561 | fault.tag = PPR_TAG(raw[0]); | ||
562 | fault.flags = PPR_FLAGS(raw[0]); | ||
563 | |||
564 | /* | ||
565 | * To detect the hardware bug we need to clear the entry | ||
566 | * to back to zero. | ||
567 | */ | ||
568 | raw[0] = raw[1] = 0; | ||
569 | |||
570 | atomic_notifier_call_chain(&ppr_notifier, 0, &fault); | ||
571 | } | ||
572 | |||
573 | static void iommu_poll_ppr_log(struct amd_iommu *iommu) | ||
574 | { | ||
575 | unsigned long flags; | ||
576 | u32 head, tail; | ||
577 | |||
578 | if (iommu->ppr_log == NULL) | ||
579 | return; | ||
580 | |||
581 | spin_lock_irqsave(&iommu->lock, flags); | ||
582 | |||
583 | head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
584 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | ||
585 | |||
586 | while (head != tail) { | ||
587 | |||
588 | /* Handle PPR entry */ | ||
589 | iommu_handle_ppr_entry(iommu, head); | ||
590 | |||
591 | /* Update and refresh ring-buffer state*/ | ||
592 | head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; | ||
593 | writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
594 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | ||
595 | } | ||
596 | |||
597 | /* enable ppr interrupts again */ | ||
598 | writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
599 | |||
600 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
601 | } | ||
602 | |||
464 | irqreturn_t amd_iommu_int_thread(int irq, void *data) | 603 | irqreturn_t amd_iommu_int_thread(int irq, void *data) |
465 | { | 604 | { |
466 | struct amd_iommu *iommu; | 605 | struct amd_iommu *iommu; |
467 | 606 | ||
468 | for_each_iommu(iommu) | 607 | for_each_iommu(iommu) { |
469 | iommu_poll_events(iommu); | 608 | iommu_poll_events(iommu); |
609 | iommu_poll_ppr_log(iommu); | ||
610 | } | ||
470 | 611 | ||
471 | return IRQ_HANDLED; | 612 | return IRQ_HANDLED; |
472 | } | 613 | } |
@@ -595,6 +736,60 @@ static void build_inv_iotlb_pages(struct iommu_cmd *cmd, u16 devid, int qdep, | |||
595 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | 736 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; |
596 | } | 737 | } |
597 | 738 | ||
739 | static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid, | ||
740 | u64 address, bool size) | ||
741 | { | ||
742 | memset(cmd, 0, sizeof(*cmd)); | ||
743 | |||
744 | address &= ~(0xfffULL); | ||
745 | |||
746 | cmd->data[0] = pasid & PASID_MASK; | ||
747 | cmd->data[1] = domid; | ||
748 | cmd->data[2] = lower_32_bits(address); | ||
749 | cmd->data[3] = upper_32_bits(address); | ||
750 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; | ||
751 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK; | ||
752 | if (size) | ||
753 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
754 | CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES); | ||
755 | } | ||
756 | |||
757 | static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid, | ||
758 | int qdep, u64 address, bool size) | ||
759 | { | ||
760 | memset(cmd, 0, sizeof(*cmd)); | ||
761 | |||
762 | address &= ~(0xfffULL); | ||
763 | |||
764 | cmd->data[0] = devid; | ||
765 | cmd->data[0] |= (pasid & 0xff) << 16; | ||
766 | cmd->data[0] |= (qdep & 0xff) << 24; | ||
767 | cmd->data[1] = devid; | ||
768 | cmd->data[1] |= ((pasid >> 8) & 0xfff) << 16; | ||
769 | cmd->data[2] = lower_32_bits(address); | ||
770 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK; | ||
771 | cmd->data[3] = upper_32_bits(address); | ||
772 | if (size) | ||
773 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
774 | CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES); | ||
775 | } | ||
776 | |||
777 | static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid, | ||
778 | int status, int tag, bool gn) | ||
779 | { | ||
780 | memset(cmd, 0, sizeof(*cmd)); | ||
781 | |||
782 | cmd->data[0] = devid; | ||
783 | if (gn) { | ||
784 | cmd->data[1] = pasid & PASID_MASK; | ||
785 | cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; | ||
786 | } | ||
787 | cmd->data[3] = tag & 0x1ff; | ||
788 | cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT; | ||
789 | |||
790 | CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR); | ||
791 | } | ||
792 | |||
598 | static void build_inv_all(struct iommu_cmd *cmd) | 793 | static void build_inv_all(struct iommu_cmd *cmd) |
599 | { | 794 | { |
600 | memset(cmd, 0, sizeof(*cmd)); | 795 | memset(cmd, 0, sizeof(*cmd)); |
@@ -1496,6 +1691,48 @@ static void free_pagetable(struct protection_domain *domain) | |||
1496 | domain->pt_root = NULL; | 1691 | domain->pt_root = NULL; |
1497 | } | 1692 | } |
1498 | 1693 | ||
1694 | static void free_gcr3_tbl_level1(u64 *tbl) | ||
1695 | { | ||
1696 | u64 *ptr; | ||
1697 | int i; | ||
1698 | |||
1699 | for (i = 0; i < 512; ++i) { | ||
1700 | if (!(tbl[i] & GCR3_VALID)) | ||
1701 | continue; | ||
1702 | |||
1703 | ptr = __va(tbl[i] & PAGE_MASK); | ||
1704 | |||
1705 | free_page((unsigned long)ptr); | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | static void free_gcr3_tbl_level2(u64 *tbl) | ||
1710 | { | ||
1711 | u64 *ptr; | ||
1712 | int i; | ||
1713 | |||
1714 | for (i = 0; i < 512; ++i) { | ||
1715 | if (!(tbl[i] & GCR3_VALID)) | ||
1716 | continue; | ||
1717 | |||
1718 | ptr = __va(tbl[i] & PAGE_MASK); | ||
1719 | |||
1720 | free_gcr3_tbl_level1(ptr); | ||
1721 | } | ||
1722 | } | ||
1723 | |||
1724 | static void free_gcr3_table(struct protection_domain *domain) | ||
1725 | { | ||
1726 | if (domain->glx == 2) | ||
1727 | free_gcr3_tbl_level2(domain->gcr3_tbl); | ||
1728 | else if (domain->glx == 1) | ||
1729 | free_gcr3_tbl_level1(domain->gcr3_tbl); | ||
1730 | else if (domain->glx != 0) | ||
1731 | BUG(); | ||
1732 | |||
1733 | free_page((unsigned long)domain->gcr3_tbl); | ||
1734 | } | ||
1735 | |||
1499 | /* | 1736 | /* |
1500 | * Free a domain, only used if something went wrong in the | 1737 | * Free a domain, only used if something went wrong in the |
1501 | * allocation path and we need to free an already allocated page table | 1738 | * allocation path and we need to free an already allocated page table |
@@ -1582,20 +1819,52 @@ static bool dma_ops_domain(struct protection_domain *domain) | |||
1582 | 1819 | ||
1583 | static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) | 1820 | static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) |
1584 | { | 1821 | { |
1585 | u64 pte_root = virt_to_phys(domain->pt_root); | 1822 | u64 pte_root = 0; |
1586 | u32 flags = 0; | 1823 | u64 flags = 0; |
1824 | |||
1825 | if (domain->mode != PAGE_MODE_NONE) | ||
1826 | pte_root = virt_to_phys(domain->pt_root); | ||
1587 | 1827 | ||
1588 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | 1828 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) |
1589 | << DEV_ENTRY_MODE_SHIFT; | 1829 | << DEV_ENTRY_MODE_SHIFT; |
1590 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | 1830 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; |
1591 | 1831 | ||
1832 | flags = amd_iommu_dev_table[devid].data[1]; | ||
1833 | |||
1592 | if (ats) | 1834 | if (ats) |
1593 | flags |= DTE_FLAG_IOTLB; | 1835 | flags |= DTE_FLAG_IOTLB; |
1594 | 1836 | ||
1595 | amd_iommu_dev_table[devid].data[3] |= flags; | 1837 | if (domain->flags & PD_IOMMUV2_MASK) { |
1596 | amd_iommu_dev_table[devid].data[2] = domain->id; | 1838 | u64 gcr3 = __pa(domain->gcr3_tbl); |
1597 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | 1839 | u64 glx = domain->glx; |
1598 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | 1840 | u64 tmp; |
1841 | |||
1842 | pte_root |= DTE_FLAG_GV; | ||
1843 | pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT; | ||
1844 | |||
1845 | /* First mask out possible old values for GCR3 table */ | ||
1846 | tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B; | ||
1847 | flags &= ~tmp; | ||
1848 | |||
1849 | tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C; | ||
1850 | flags &= ~tmp; | ||
1851 | |||
1852 | /* Encode GCR3 table into DTE */ | ||
1853 | tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A; | ||
1854 | pte_root |= tmp; | ||
1855 | |||
1856 | tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B; | ||
1857 | flags |= tmp; | ||
1858 | |||
1859 | tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C; | ||
1860 | flags |= tmp; | ||
1861 | } | ||
1862 | |||
1863 | flags &= ~(0xffffUL); | ||
1864 | flags |= domain->id; | ||
1865 | |||
1866 | amd_iommu_dev_table[devid].data[1] = flags; | ||
1867 | amd_iommu_dev_table[devid].data[0] = pte_root; | ||
1599 | } | 1868 | } |
1600 | 1869 | ||
1601 | static void clear_dte_entry(u16 devid) | 1870 | static void clear_dte_entry(u16 devid) |
@@ -1603,7 +1872,6 @@ static void clear_dte_entry(u16 devid) | |||
1603 | /* remove entry from the device table seen by the hardware */ | 1872 | /* remove entry from the device table seen by the hardware */ |
1604 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; | 1873 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; |
1605 | amd_iommu_dev_table[devid].data[1] = 0; | 1874 | amd_iommu_dev_table[devid].data[1] = 0; |
1606 | amd_iommu_dev_table[devid].data[2] = 0; | ||
1607 | 1875 | ||
1608 | amd_iommu_apply_erratum_63(devid); | 1876 | amd_iommu_apply_erratum_63(devid); |
1609 | } | 1877 | } |
@@ -1696,6 +1964,93 @@ out_unlock: | |||
1696 | return ret; | 1964 | return ret; |
1697 | } | 1965 | } |
1698 | 1966 | ||
1967 | |||
1968 | static void pdev_iommuv2_disable(struct pci_dev *pdev) | ||
1969 | { | ||
1970 | pci_disable_ats(pdev); | ||
1971 | pci_disable_pri(pdev); | ||
1972 | pci_disable_pasid(pdev); | ||
1973 | } | ||
1974 | |||
1975 | /* FIXME: Change generic reset-function to do the same */ | ||
1976 | static int pri_reset_while_enabled(struct pci_dev *pdev) | ||
1977 | { | ||
1978 | u16 control; | ||
1979 | int pos; | ||
1980 | |||
1981 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); | ||
1982 | if (!pos) | ||
1983 | return -EINVAL; | ||
1984 | |||
1985 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); | ||
1986 | control |= PCI_PRI_CTRL_RESET; | ||
1987 | pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); | ||
1988 | |||
1989 | return 0; | ||
1990 | } | ||
1991 | |||
1992 | static int pdev_iommuv2_enable(struct pci_dev *pdev) | ||
1993 | { | ||
1994 | bool reset_enable; | ||
1995 | int reqs, ret; | ||
1996 | |||
1997 | /* FIXME: Hardcode number of outstanding requests for now */ | ||
1998 | reqs = 32; | ||
1999 | if (pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE)) | ||
2000 | reqs = 1; | ||
2001 | reset_enable = pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_ENABLE_RESET); | ||
2002 | |||
2003 | /* Only allow access to user-accessible pages */ | ||
2004 | ret = pci_enable_pasid(pdev, 0); | ||
2005 | if (ret) | ||
2006 | goto out_err; | ||
2007 | |||
2008 | /* First reset the PRI state of the device */ | ||
2009 | ret = pci_reset_pri(pdev); | ||
2010 | if (ret) | ||
2011 | goto out_err; | ||
2012 | |||
2013 | /* Enable PRI */ | ||
2014 | ret = pci_enable_pri(pdev, reqs); | ||
2015 | if (ret) | ||
2016 | goto out_err; | ||
2017 | |||
2018 | if (reset_enable) { | ||
2019 | ret = pri_reset_while_enabled(pdev); | ||
2020 | if (ret) | ||
2021 | goto out_err; | ||
2022 | } | ||
2023 | |||
2024 | ret = pci_enable_ats(pdev, PAGE_SHIFT); | ||
2025 | if (ret) | ||
2026 | goto out_err; | ||
2027 | |||
2028 | return 0; | ||
2029 | |||
2030 | out_err: | ||
2031 | pci_disable_pri(pdev); | ||
2032 | pci_disable_pasid(pdev); | ||
2033 | |||
2034 | return ret; | ||
2035 | } | ||
2036 | |||
2037 | /* FIXME: Move this to PCI code */ | ||
2038 | #define PCI_PRI_TLP_OFF (1 << 2) | ||
2039 | |||
2040 | bool pci_pri_tlp_required(struct pci_dev *pdev) | ||
2041 | { | ||
2042 | u16 control; | ||
2043 | int pos; | ||
2044 | |||
2045 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); | ||
2046 | if (!pos) | ||
2047 | return false; | ||
2048 | |||
2049 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); | ||
2050 | |||
2051 | return (control & PCI_PRI_TLP_OFF) ? true : false; | ||
2052 | } | ||
2053 | |||
1699 | /* | 2054 | /* |
1700 | * If a device is not yet associated with a domain, this function does | 2055 | * If a device is not yet associated with a domain, this function does |
1701 | * assigns it visible for the hardware | 2056 | * assigns it visible for the hardware |
@@ -1710,7 +2065,18 @@ static int attach_device(struct device *dev, | |||
1710 | 2065 | ||
1711 | dev_data = get_dev_data(dev); | 2066 | dev_data = get_dev_data(dev); |
1712 | 2067 | ||
1713 | if (amd_iommu_iotlb_sup && pci_enable_ats(pdev, PAGE_SHIFT) == 0) { | 2068 | if (domain->flags & PD_IOMMUV2_MASK) { |
2069 | if (!dev_data->iommu_v2 || !dev_data->passthrough) | ||
2070 | return -EINVAL; | ||
2071 | |||
2072 | if (pdev_iommuv2_enable(pdev) != 0) | ||
2073 | return -EINVAL; | ||
2074 | |||
2075 | dev_data->ats.enabled = true; | ||
2076 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); | ||
2077 | dev_data->pri_tlp = pci_pri_tlp_required(pdev); | ||
2078 | } else if (amd_iommu_iotlb_sup && | ||
2079 | pci_enable_ats(pdev, PAGE_SHIFT) == 0) { | ||
1714 | dev_data->ats.enabled = true; | 2080 | dev_data->ats.enabled = true; |
1715 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); | 2081 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); |
1716 | } | 2082 | } |
@@ -1760,7 +2126,7 @@ static void __detach_device(struct iommu_dev_data *dev_data) | |||
1760 | * passthrough domain if it is detached from any other domain. | 2126 | * passthrough domain if it is detached from any other domain. |
1761 | * Make sure we can deassign from the pt_domain itself. | 2127 | * Make sure we can deassign from the pt_domain itself. |
1762 | */ | 2128 | */ |
1763 | if (iommu_pass_through && | 2129 | if (dev_data->passthrough && |
1764 | (dev_data->domain == NULL && domain != pt_domain)) | 2130 | (dev_data->domain == NULL && domain != pt_domain)) |
1765 | __attach_device(dev_data, pt_domain); | 2131 | __attach_device(dev_data, pt_domain); |
1766 | } | 2132 | } |
@@ -1770,20 +2136,24 @@ static void __detach_device(struct iommu_dev_data *dev_data) | |||
1770 | */ | 2136 | */ |
1771 | static void detach_device(struct device *dev) | 2137 | static void detach_device(struct device *dev) |
1772 | { | 2138 | { |
2139 | struct protection_domain *domain; | ||
1773 | struct iommu_dev_data *dev_data; | 2140 | struct iommu_dev_data *dev_data; |
1774 | unsigned long flags; | 2141 | unsigned long flags; |
1775 | 2142 | ||
1776 | dev_data = get_dev_data(dev); | 2143 | dev_data = get_dev_data(dev); |
2144 | domain = dev_data->domain; | ||
1777 | 2145 | ||
1778 | /* lock device table */ | 2146 | /* lock device table */ |
1779 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 2147 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
1780 | __detach_device(dev_data); | 2148 | __detach_device(dev_data); |
1781 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 2149 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
1782 | 2150 | ||
1783 | if (dev_data->ats.enabled) { | 2151 | if (domain->flags & PD_IOMMUV2_MASK) |
2152 | pdev_iommuv2_disable(to_pci_dev(dev)); | ||
2153 | else if (dev_data->ats.enabled) | ||
1784 | pci_disable_ats(to_pci_dev(dev)); | 2154 | pci_disable_ats(to_pci_dev(dev)); |
1785 | dev_data->ats.enabled = false; | 2155 | |
1786 | } | 2156 | dev_data->ats.enabled = false; |
1787 | } | 2157 | } |
1788 | 2158 | ||
1789 | /* | 2159 | /* |
@@ -1818,18 +2188,20 @@ static struct protection_domain *domain_for_device(struct device *dev) | |||
1818 | static int device_change_notifier(struct notifier_block *nb, | 2188 | static int device_change_notifier(struct notifier_block *nb, |
1819 | unsigned long action, void *data) | 2189 | unsigned long action, void *data) |
1820 | { | 2190 | { |
1821 | struct device *dev = data; | ||
1822 | u16 devid; | ||
1823 | struct protection_domain *domain; | ||
1824 | struct dma_ops_domain *dma_domain; | 2191 | struct dma_ops_domain *dma_domain; |
2192 | struct protection_domain *domain; | ||
2193 | struct iommu_dev_data *dev_data; | ||
2194 | struct device *dev = data; | ||
1825 | struct amd_iommu *iommu; | 2195 | struct amd_iommu *iommu; |
1826 | unsigned long flags; | 2196 | unsigned long flags; |
2197 | u16 devid; | ||
1827 | 2198 | ||
1828 | if (!check_device(dev)) | 2199 | if (!check_device(dev)) |
1829 | return 0; | 2200 | return 0; |
1830 | 2201 | ||
1831 | devid = get_device_id(dev); | 2202 | devid = get_device_id(dev); |
1832 | iommu = amd_iommu_rlookup_table[devid]; | 2203 | iommu = amd_iommu_rlookup_table[devid]; |
2204 | dev_data = get_dev_data(dev); | ||
1833 | 2205 | ||
1834 | switch (action) { | 2206 | switch (action) { |
1835 | case BUS_NOTIFY_UNBOUND_DRIVER: | 2207 | case BUS_NOTIFY_UNBOUND_DRIVER: |
@@ -1838,7 +2210,7 @@ static int device_change_notifier(struct notifier_block *nb, | |||
1838 | 2210 | ||
1839 | if (!domain) | 2211 | if (!domain) |
1840 | goto out; | 2212 | goto out; |
1841 | if (iommu_pass_through) | 2213 | if (dev_data->passthrough) |
1842 | break; | 2214 | break; |
1843 | detach_device(dev); | 2215 | detach_device(dev); |
1844 | break; | 2216 | break; |
@@ -2434,8 +2806,9 @@ static int amd_iommu_dma_supported(struct device *dev, u64 mask) | |||
2434 | */ | 2806 | */ |
2435 | static void prealloc_protection_domains(void) | 2807 | static void prealloc_protection_domains(void) |
2436 | { | 2808 | { |
2437 | struct pci_dev *dev = NULL; | 2809 | struct iommu_dev_data *dev_data; |
2438 | struct dma_ops_domain *dma_dom; | 2810 | struct dma_ops_domain *dma_dom; |
2811 | struct pci_dev *dev = NULL; | ||
2439 | u16 devid; | 2812 | u16 devid; |
2440 | 2813 | ||
2441 | for_each_pci_dev(dev) { | 2814 | for_each_pci_dev(dev) { |
@@ -2444,6 +2817,16 @@ static void prealloc_protection_domains(void) | |||
2444 | if (!check_device(&dev->dev)) | 2817 | if (!check_device(&dev->dev)) |
2445 | continue; | 2818 | continue; |
2446 | 2819 | ||
2820 | dev_data = get_dev_data(&dev->dev); | ||
2821 | if (!amd_iommu_force_isolation && dev_data->iommu_v2) { | ||
2822 | /* Make sure passthrough domain is allocated */ | ||
2823 | alloc_passthrough_domain(); | ||
2824 | dev_data->passthrough = true; | ||
2825 | attach_device(&dev->dev, pt_domain); | ||
2826 | pr_info("AMD-Vi: Using passthough domain for device %s\n", | ||
2827 | dev_name(&dev->dev)); | ||
2828 | } | ||
2829 | |||
2447 | /* Is there already any domain for it? */ | 2830 | /* Is there already any domain for it? */ |
2448 | if (domain_for_device(&dev->dev)) | 2831 | if (domain_for_device(&dev->dev)) |
2449 | continue; | 2832 | continue; |
@@ -2474,6 +2857,7 @@ static struct dma_map_ops amd_iommu_dma_ops = { | |||
2474 | 2857 | ||
2475 | static unsigned device_dma_ops_init(void) | 2858 | static unsigned device_dma_ops_init(void) |
2476 | { | 2859 | { |
2860 | struct iommu_dev_data *dev_data; | ||
2477 | struct pci_dev *pdev = NULL; | 2861 | struct pci_dev *pdev = NULL; |
2478 | unsigned unhandled = 0; | 2862 | unsigned unhandled = 0; |
2479 | 2863 | ||
@@ -2483,7 +2867,12 @@ static unsigned device_dma_ops_init(void) | |||
2483 | continue; | 2867 | continue; |
2484 | } | 2868 | } |
2485 | 2869 | ||
2486 | pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops; | 2870 | dev_data = get_dev_data(&pdev->dev); |
2871 | |||
2872 | if (!dev_data->passthrough) | ||
2873 | pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops; | ||
2874 | else | ||
2875 | pdev->dev.archdata.dma_ops = &nommu_dma_ops; | ||
2487 | } | 2876 | } |
2488 | 2877 | ||
2489 | return unhandled; | 2878 | return unhandled; |
@@ -2610,6 +2999,20 @@ out_err: | |||
2610 | return NULL; | 2999 | return NULL; |
2611 | } | 3000 | } |
2612 | 3001 | ||
3002 | static int __init alloc_passthrough_domain(void) | ||
3003 | { | ||
3004 | if (pt_domain != NULL) | ||
3005 | return 0; | ||
3006 | |||
3007 | /* allocate passthrough domain */ | ||
3008 | pt_domain = protection_domain_alloc(); | ||
3009 | if (!pt_domain) | ||
3010 | return -ENOMEM; | ||
3011 | |||
3012 | pt_domain->mode = PAGE_MODE_NONE; | ||
3013 | |||
3014 | return 0; | ||
3015 | } | ||
2613 | static int amd_iommu_domain_init(struct iommu_domain *dom) | 3016 | static int amd_iommu_domain_init(struct iommu_domain *dom) |
2614 | { | 3017 | { |
2615 | struct protection_domain *domain; | 3018 | struct protection_domain *domain; |
@@ -2623,6 +3026,8 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) | |||
2623 | if (!domain->pt_root) | 3026 | if (!domain->pt_root) |
2624 | goto out_free; | 3027 | goto out_free; |
2625 | 3028 | ||
3029 | domain->iommu_domain = dom; | ||
3030 | |||
2626 | dom->priv = domain; | 3031 | dom->priv = domain; |
2627 | 3032 | ||
2628 | return 0; | 3033 | return 0; |
@@ -2645,7 +3050,11 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) | |||
2645 | 3050 | ||
2646 | BUG_ON(domain->dev_cnt != 0); | 3051 | BUG_ON(domain->dev_cnt != 0); |
2647 | 3052 | ||
2648 | free_pagetable(domain); | 3053 | if (domain->mode != PAGE_MODE_NONE) |
3054 | free_pagetable(domain); | ||
3055 | |||
3056 | if (domain->flags & PD_IOMMUV2_MASK) | ||
3057 | free_gcr3_table(domain); | ||
2649 | 3058 | ||
2650 | protection_domain_free(domain); | 3059 | protection_domain_free(domain); |
2651 | 3060 | ||
@@ -2702,13 +3111,15 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, | |||
2702 | } | 3111 | } |
2703 | 3112 | ||
2704 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | 3113 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, |
2705 | phys_addr_t paddr, int gfp_order, int iommu_prot) | 3114 | phys_addr_t paddr, size_t page_size, int iommu_prot) |
2706 | { | 3115 | { |
2707 | unsigned long page_size = 0x1000UL << gfp_order; | ||
2708 | struct protection_domain *domain = dom->priv; | 3116 | struct protection_domain *domain = dom->priv; |
2709 | int prot = 0; | 3117 | int prot = 0; |
2710 | int ret; | 3118 | int ret; |
2711 | 3119 | ||
3120 | if (domain->mode == PAGE_MODE_NONE) | ||
3121 | return -EINVAL; | ||
3122 | |||
2712 | if (iommu_prot & IOMMU_READ) | 3123 | if (iommu_prot & IOMMU_READ) |
2713 | prot |= IOMMU_PROT_IR; | 3124 | prot |= IOMMU_PROT_IR; |
2714 | if (iommu_prot & IOMMU_WRITE) | 3125 | if (iommu_prot & IOMMU_WRITE) |
@@ -2721,13 +3132,14 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | |||
2721 | return ret; | 3132 | return ret; |
2722 | } | 3133 | } |
2723 | 3134 | ||
2724 | static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | 3135 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, |
2725 | int gfp_order) | 3136 | size_t page_size) |
2726 | { | 3137 | { |
2727 | struct protection_domain *domain = dom->priv; | 3138 | struct protection_domain *domain = dom->priv; |
2728 | unsigned long page_size, unmap_size; | 3139 | size_t unmap_size; |
2729 | 3140 | ||
2730 | page_size = 0x1000UL << gfp_order; | 3141 | if (domain->mode == PAGE_MODE_NONE) |
3142 | return -EINVAL; | ||
2731 | 3143 | ||
2732 | mutex_lock(&domain->api_lock); | 3144 | mutex_lock(&domain->api_lock); |
2733 | unmap_size = iommu_unmap_page(domain, iova, page_size); | 3145 | unmap_size = iommu_unmap_page(domain, iova, page_size); |
@@ -2735,7 +3147,7 @@ static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | |||
2735 | 3147 | ||
2736 | domain_flush_tlb_pde(domain); | 3148 | domain_flush_tlb_pde(domain); |
2737 | 3149 | ||
2738 | return get_order(unmap_size); | 3150 | return unmap_size; |
2739 | } | 3151 | } |
2740 | 3152 | ||
2741 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | 3153 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, |
@@ -2746,6 +3158,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | |||
2746 | phys_addr_t paddr; | 3158 | phys_addr_t paddr; |
2747 | u64 *pte, __pte; | 3159 | u64 *pte, __pte; |
2748 | 3160 | ||
3161 | if (domain->mode == PAGE_MODE_NONE) | ||
3162 | return iova; | ||
3163 | |||
2749 | pte = fetch_pte(domain, iova); | 3164 | pte = fetch_pte(domain, iova); |
2750 | 3165 | ||
2751 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) | 3166 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) |
@@ -2773,6 +3188,26 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain, | |||
2773 | return 0; | 3188 | return 0; |
2774 | } | 3189 | } |
2775 | 3190 | ||
3191 | static int amd_iommu_device_group(struct device *dev, unsigned int *groupid) | ||
3192 | { | ||
3193 | struct iommu_dev_data *dev_data = dev->archdata.iommu; | ||
3194 | struct pci_dev *pdev = to_pci_dev(dev); | ||
3195 | u16 devid; | ||
3196 | |||
3197 | if (!dev_data) | ||
3198 | return -ENODEV; | ||
3199 | |||
3200 | if (pdev->is_virtfn || !iommu_group_mf) | ||
3201 | devid = dev_data->devid; | ||
3202 | else | ||
3203 | devid = calc_devid(pdev->bus->number, | ||
3204 | PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); | ||
3205 | |||
3206 | *groupid = amd_iommu_alias_table[devid]; | ||
3207 | |||
3208 | return 0; | ||
3209 | } | ||
3210 | |||
2776 | static struct iommu_ops amd_iommu_ops = { | 3211 | static struct iommu_ops amd_iommu_ops = { |
2777 | .domain_init = amd_iommu_domain_init, | 3212 | .domain_init = amd_iommu_domain_init, |
2778 | .domain_destroy = amd_iommu_domain_destroy, | 3213 | .domain_destroy = amd_iommu_domain_destroy, |
@@ -2782,6 +3217,8 @@ static struct iommu_ops amd_iommu_ops = { | |||
2782 | .unmap = amd_iommu_unmap, | 3217 | .unmap = amd_iommu_unmap, |
2783 | .iova_to_phys = amd_iommu_iova_to_phys, | 3218 | .iova_to_phys = amd_iommu_iova_to_phys, |
2784 | .domain_has_cap = amd_iommu_domain_has_cap, | 3219 | .domain_has_cap = amd_iommu_domain_has_cap, |
3220 | .device_group = amd_iommu_device_group, | ||
3221 | .pgsize_bitmap = AMD_IOMMU_PGSIZES, | ||
2785 | }; | 3222 | }; |
2786 | 3223 | ||
2787 | /***************************************************************************** | 3224 | /***************************************************************************** |
@@ -2796,21 +3233,23 @@ static struct iommu_ops amd_iommu_ops = { | |||
2796 | 3233 | ||
2797 | int __init amd_iommu_init_passthrough(void) | 3234 | int __init amd_iommu_init_passthrough(void) |
2798 | { | 3235 | { |
2799 | struct amd_iommu *iommu; | 3236 | struct iommu_dev_data *dev_data; |
2800 | struct pci_dev *dev = NULL; | 3237 | struct pci_dev *dev = NULL; |
3238 | struct amd_iommu *iommu; | ||
2801 | u16 devid; | 3239 | u16 devid; |
3240 | int ret; | ||
2802 | 3241 | ||
2803 | /* allocate passthrough domain */ | 3242 | ret = alloc_passthrough_domain(); |
2804 | pt_domain = protection_domain_alloc(); | 3243 | if (ret) |
2805 | if (!pt_domain) | 3244 | return ret; |
2806 | return -ENOMEM; | ||
2807 | |||
2808 | pt_domain->mode |= PAGE_MODE_NONE; | ||
2809 | 3245 | ||
2810 | for_each_pci_dev(dev) { | 3246 | for_each_pci_dev(dev) { |
2811 | if (!check_device(&dev->dev)) | 3247 | if (!check_device(&dev->dev)) |
2812 | continue; | 3248 | continue; |
2813 | 3249 | ||
3250 | dev_data = get_dev_data(&dev->dev); | ||
3251 | dev_data->passthrough = true; | ||
3252 | |||
2814 | devid = get_device_id(&dev->dev); | 3253 | devid = get_device_id(&dev->dev); |
2815 | 3254 | ||
2816 | iommu = amd_iommu_rlookup_table[devid]; | 3255 | iommu = amd_iommu_rlookup_table[devid]; |
@@ -2820,7 +3259,375 @@ int __init amd_iommu_init_passthrough(void) | |||
2820 | attach_device(&dev->dev, pt_domain); | 3259 | attach_device(&dev->dev, pt_domain); |
2821 | } | 3260 | } |
2822 | 3261 | ||
3262 | amd_iommu_stats_init(); | ||
3263 | |||
2823 | pr_info("AMD-Vi: Initialized for Passthrough Mode\n"); | 3264 | pr_info("AMD-Vi: Initialized for Passthrough Mode\n"); |
2824 | 3265 | ||
2825 | return 0; | 3266 | return 0; |
2826 | } | 3267 | } |
3268 | |||
3269 | /* IOMMUv2 specific functions */ | ||
3270 | int amd_iommu_register_ppr_notifier(struct notifier_block *nb) | ||
3271 | { | ||
3272 | return atomic_notifier_chain_register(&ppr_notifier, nb); | ||
3273 | } | ||
3274 | EXPORT_SYMBOL(amd_iommu_register_ppr_notifier); | ||
3275 | |||
3276 | int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb) | ||
3277 | { | ||
3278 | return atomic_notifier_chain_unregister(&ppr_notifier, nb); | ||
3279 | } | ||
3280 | EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier); | ||
3281 | |||
3282 | void amd_iommu_domain_direct_map(struct iommu_domain *dom) | ||
3283 | { | ||
3284 | struct protection_domain *domain = dom->priv; | ||
3285 | unsigned long flags; | ||
3286 | |||
3287 | spin_lock_irqsave(&domain->lock, flags); | ||
3288 | |||
3289 | /* Update data structure */ | ||
3290 | domain->mode = PAGE_MODE_NONE; | ||
3291 | domain->updated = true; | ||
3292 | |||
3293 | /* Make changes visible to IOMMUs */ | ||
3294 | update_domain(domain); | ||
3295 | |||
3296 | /* Page-table is not visible to IOMMU anymore, so free it */ | ||
3297 | free_pagetable(domain); | ||
3298 | |||
3299 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3300 | } | ||
3301 | EXPORT_SYMBOL(amd_iommu_domain_direct_map); | ||
3302 | |||
3303 | int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids) | ||
3304 | { | ||
3305 | struct protection_domain *domain = dom->priv; | ||
3306 | unsigned long flags; | ||
3307 | int levels, ret; | ||
3308 | |||
3309 | if (pasids <= 0 || pasids > (PASID_MASK + 1)) | ||
3310 | return -EINVAL; | ||
3311 | |||
3312 | /* Number of GCR3 table levels required */ | ||
3313 | for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9) | ||
3314 | levels += 1; | ||
3315 | |||
3316 | if (levels > amd_iommu_max_glx_val) | ||
3317 | return -EINVAL; | ||
3318 | |||
3319 | spin_lock_irqsave(&domain->lock, flags); | ||
3320 | |||
3321 | /* | ||
3322 | * Save us all sanity checks whether devices already in the | ||
3323 | * domain support IOMMUv2. Just force that the domain has no | ||
3324 | * devices attached when it is switched into IOMMUv2 mode. | ||
3325 | */ | ||
3326 | ret = -EBUSY; | ||
3327 | if (domain->dev_cnt > 0 || domain->flags & PD_IOMMUV2_MASK) | ||
3328 | goto out; | ||
3329 | |||
3330 | ret = -ENOMEM; | ||
3331 | domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC); | ||
3332 | if (domain->gcr3_tbl == NULL) | ||
3333 | goto out; | ||
3334 | |||
3335 | domain->glx = levels; | ||
3336 | domain->flags |= PD_IOMMUV2_MASK; | ||
3337 | domain->updated = true; | ||
3338 | |||
3339 | update_domain(domain); | ||
3340 | |||
3341 | ret = 0; | ||
3342 | |||
3343 | out: | ||
3344 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3345 | |||
3346 | return ret; | ||
3347 | } | ||
3348 | EXPORT_SYMBOL(amd_iommu_domain_enable_v2); | ||
3349 | |||
3350 | static int __flush_pasid(struct protection_domain *domain, int pasid, | ||
3351 | u64 address, bool size) | ||
3352 | { | ||
3353 | struct iommu_dev_data *dev_data; | ||
3354 | struct iommu_cmd cmd; | ||
3355 | int i, ret; | ||
3356 | |||
3357 | if (!(domain->flags & PD_IOMMUV2_MASK)) | ||
3358 | return -EINVAL; | ||
3359 | |||
3360 | build_inv_iommu_pasid(&cmd, domain->id, pasid, address, size); | ||
3361 | |||
3362 | /* | ||
3363 | * IOMMU TLB needs to be flushed before Device TLB to | ||
3364 | * prevent device TLB refill from IOMMU TLB | ||
3365 | */ | ||
3366 | for (i = 0; i < amd_iommus_present; ++i) { | ||
3367 | if (domain->dev_iommu[i] == 0) | ||
3368 | continue; | ||
3369 | |||
3370 | ret = iommu_queue_command(amd_iommus[i], &cmd); | ||
3371 | if (ret != 0) | ||
3372 | goto out; | ||
3373 | } | ||
3374 | |||
3375 | /* Wait until IOMMU TLB flushes are complete */ | ||
3376 | domain_flush_complete(domain); | ||
3377 | |||
3378 | /* Now flush device TLBs */ | ||
3379 | list_for_each_entry(dev_data, &domain->dev_list, list) { | ||
3380 | struct amd_iommu *iommu; | ||
3381 | int qdep; | ||
3382 | |||
3383 | BUG_ON(!dev_data->ats.enabled); | ||
3384 | |||
3385 | qdep = dev_data->ats.qdep; | ||
3386 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
3387 | |||
3388 | build_inv_iotlb_pasid(&cmd, dev_data->devid, pasid, | ||
3389 | qdep, address, size); | ||
3390 | |||
3391 | ret = iommu_queue_command(iommu, &cmd); | ||
3392 | if (ret != 0) | ||
3393 | goto out; | ||
3394 | } | ||
3395 | |||
3396 | /* Wait until all device TLBs are flushed */ | ||
3397 | domain_flush_complete(domain); | ||
3398 | |||
3399 | ret = 0; | ||
3400 | |||
3401 | out: | ||
3402 | |||
3403 | return ret; | ||
3404 | } | ||
3405 | |||
3406 | static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid, | ||
3407 | u64 address) | ||
3408 | { | ||
3409 | INC_STATS_COUNTER(invalidate_iotlb); | ||
3410 | |||
3411 | return __flush_pasid(domain, pasid, address, false); | ||
3412 | } | ||
3413 | |||
3414 | int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, | ||
3415 | u64 address) | ||
3416 | { | ||
3417 | struct protection_domain *domain = dom->priv; | ||
3418 | unsigned long flags; | ||
3419 | int ret; | ||
3420 | |||
3421 | spin_lock_irqsave(&domain->lock, flags); | ||
3422 | ret = __amd_iommu_flush_page(domain, pasid, address); | ||
3423 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3424 | |||
3425 | return ret; | ||
3426 | } | ||
3427 | EXPORT_SYMBOL(amd_iommu_flush_page); | ||
3428 | |||
3429 | static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid) | ||
3430 | { | ||
3431 | INC_STATS_COUNTER(invalidate_iotlb_all); | ||
3432 | |||
3433 | return __flush_pasid(domain, pasid, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | ||
3434 | true); | ||
3435 | } | ||
3436 | |||
3437 | int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid) | ||
3438 | { | ||
3439 | struct protection_domain *domain = dom->priv; | ||
3440 | unsigned long flags; | ||
3441 | int ret; | ||
3442 | |||
3443 | spin_lock_irqsave(&domain->lock, flags); | ||
3444 | ret = __amd_iommu_flush_tlb(domain, pasid); | ||
3445 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3446 | |||
3447 | return ret; | ||
3448 | } | ||
3449 | EXPORT_SYMBOL(amd_iommu_flush_tlb); | ||
3450 | |||
3451 | static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc) | ||
3452 | { | ||
3453 | int index; | ||
3454 | u64 *pte; | ||
3455 | |||
3456 | while (true) { | ||
3457 | |||
3458 | index = (pasid >> (9 * level)) & 0x1ff; | ||
3459 | pte = &root[index]; | ||
3460 | |||
3461 | if (level == 0) | ||
3462 | break; | ||
3463 | |||
3464 | if (!(*pte & GCR3_VALID)) { | ||
3465 | if (!alloc) | ||
3466 | return NULL; | ||
3467 | |||
3468 | root = (void *)get_zeroed_page(GFP_ATOMIC); | ||
3469 | if (root == NULL) | ||
3470 | return NULL; | ||
3471 | |||
3472 | *pte = __pa(root) | GCR3_VALID; | ||
3473 | } | ||
3474 | |||
3475 | root = __va(*pte & PAGE_MASK); | ||
3476 | |||
3477 | level -= 1; | ||
3478 | } | ||
3479 | |||
3480 | return pte; | ||
3481 | } | ||
3482 | |||
3483 | static int __set_gcr3(struct protection_domain *domain, int pasid, | ||
3484 | unsigned long cr3) | ||
3485 | { | ||
3486 | u64 *pte; | ||
3487 | |||
3488 | if (domain->mode != PAGE_MODE_NONE) | ||
3489 | return -EINVAL; | ||
3490 | |||
3491 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true); | ||
3492 | if (pte == NULL) | ||
3493 | return -ENOMEM; | ||
3494 | |||
3495 | *pte = (cr3 & PAGE_MASK) | GCR3_VALID; | ||
3496 | |||
3497 | return __amd_iommu_flush_tlb(domain, pasid); | ||
3498 | } | ||
3499 | |||
3500 | static int __clear_gcr3(struct protection_domain *domain, int pasid) | ||
3501 | { | ||
3502 | u64 *pte; | ||
3503 | |||
3504 | if (domain->mode != PAGE_MODE_NONE) | ||
3505 | return -EINVAL; | ||
3506 | |||
3507 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false); | ||
3508 | if (pte == NULL) | ||
3509 | return 0; | ||
3510 | |||
3511 | *pte = 0; | ||
3512 | |||
3513 | return __amd_iommu_flush_tlb(domain, pasid); | ||
3514 | } | ||
3515 | |||
3516 | int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, | ||
3517 | unsigned long cr3) | ||
3518 | { | ||
3519 | struct protection_domain *domain = dom->priv; | ||
3520 | unsigned long flags; | ||
3521 | int ret; | ||
3522 | |||
3523 | spin_lock_irqsave(&domain->lock, flags); | ||
3524 | ret = __set_gcr3(domain, pasid, cr3); | ||
3525 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3526 | |||
3527 | return ret; | ||
3528 | } | ||
3529 | EXPORT_SYMBOL(amd_iommu_domain_set_gcr3); | ||
3530 | |||
3531 | int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) | ||
3532 | { | ||
3533 | struct protection_domain *domain = dom->priv; | ||
3534 | unsigned long flags; | ||
3535 | int ret; | ||
3536 | |||
3537 | spin_lock_irqsave(&domain->lock, flags); | ||
3538 | ret = __clear_gcr3(domain, pasid); | ||
3539 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3540 | |||
3541 | return ret; | ||
3542 | } | ||
3543 | EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3); | ||
3544 | |||
3545 | int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, | ||
3546 | int status, int tag) | ||
3547 | { | ||
3548 | struct iommu_dev_data *dev_data; | ||
3549 | struct amd_iommu *iommu; | ||
3550 | struct iommu_cmd cmd; | ||
3551 | |||
3552 | INC_STATS_COUNTER(complete_ppr); | ||
3553 | |||
3554 | dev_data = get_dev_data(&pdev->dev); | ||
3555 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
3556 | |||
3557 | build_complete_ppr(&cmd, dev_data->devid, pasid, status, | ||
3558 | tag, dev_data->pri_tlp); | ||
3559 | |||
3560 | return iommu_queue_command(iommu, &cmd); | ||
3561 | } | ||
3562 | EXPORT_SYMBOL(amd_iommu_complete_ppr); | ||
3563 | |||
3564 | struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev) | ||
3565 | { | ||
3566 | struct protection_domain *domain; | ||
3567 | |||
3568 | domain = get_domain(&pdev->dev); | ||
3569 | if (IS_ERR(domain)) | ||
3570 | return NULL; | ||
3571 | |||
3572 | /* Only return IOMMUv2 domains */ | ||
3573 | if (!(domain->flags & PD_IOMMUV2_MASK)) | ||
3574 | return NULL; | ||
3575 | |||
3576 | return domain->iommu_domain; | ||
3577 | } | ||
3578 | EXPORT_SYMBOL(amd_iommu_get_v2_domain); | ||
3579 | |||
3580 | void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum) | ||
3581 | { | ||
3582 | struct iommu_dev_data *dev_data; | ||
3583 | |||
3584 | if (!amd_iommu_v2_supported()) | ||
3585 | return; | ||
3586 | |||
3587 | dev_data = get_dev_data(&pdev->dev); | ||
3588 | dev_data->errata |= (1 << erratum); | ||
3589 | } | ||
3590 | EXPORT_SYMBOL(amd_iommu_enable_device_erratum); | ||
3591 | |||
3592 | int amd_iommu_device_info(struct pci_dev *pdev, | ||
3593 | struct amd_iommu_device_info *info) | ||
3594 | { | ||
3595 | int max_pasids; | ||
3596 | int pos; | ||
3597 | |||
3598 | if (pdev == NULL || info == NULL) | ||
3599 | return -EINVAL; | ||
3600 | |||
3601 | if (!amd_iommu_v2_supported()) | ||
3602 | return -EINVAL; | ||
3603 | |||
3604 | memset(info, 0, sizeof(*info)); | ||
3605 | |||
3606 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS); | ||
3607 | if (pos) | ||
3608 | info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP; | ||
3609 | |||
3610 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); | ||
3611 | if (pos) | ||
3612 | info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP; | ||
3613 | |||
3614 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); | ||
3615 | if (pos) { | ||
3616 | int features; | ||
3617 | |||
3618 | max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1)); | ||
3619 | max_pasids = min(max_pasids, (1 << 20)); | ||
3620 | |||
3621 | info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP; | ||
3622 | info->max_pasids = min(pci_max_pasids(pdev), max_pasids); | ||
3623 | |||
3624 | features = pci_pasid_features(pdev); | ||
3625 | if (features & PCI_PASID_CAP_EXEC) | ||
3626 | info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP; | ||
3627 | if (features & PCI_PASID_CAP_PRIV) | ||
3628 | info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP; | ||
3629 | } | ||
3630 | |||
3631 | return 0; | ||
3632 | } | ||
3633 | EXPORT_SYMBOL(amd_iommu_device_info); | ||