diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 387 |
1 files changed, 160 insertions, 227 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index f3f686581a90..23e56a564e05 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -164,7 +164,8 @@ static inline void context_clear_entry(struct context_entry *context) | |||
164 | * 1: writable | 164 | * 1: writable |
165 | * 2-6: reserved | 165 | * 2-6: reserved |
166 | * 7: super page | 166 | * 7: super page |
167 | * 8-11: available | 167 | * 8-10: available |
168 | * 11: snoop behavior | ||
168 | * 12-63: Host physcial address | 169 | * 12-63: Host physcial address |
169 | */ | 170 | */ |
170 | struct dma_pte { | 171 | struct dma_pte { |
@@ -186,6 +187,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte) | |||
186 | pte->val |= DMA_PTE_WRITE; | 187 | pte->val |= DMA_PTE_WRITE; |
187 | } | 188 | } |
188 | 189 | ||
190 | static inline void dma_set_pte_snp(struct dma_pte *pte) | ||
191 | { | ||
192 | pte->val |= DMA_PTE_SNP; | ||
193 | } | ||
194 | |||
189 | static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) | 195 | static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) |
190 | { | 196 | { |
191 | pte->val = (pte->val & ~3) | (prot & 3); | 197 | pte->val = (pte->val & ~3) | (prot & 3); |
@@ -231,6 +237,7 @@ struct dmar_domain { | |||
231 | int flags; /* flags to find out type of domain */ | 237 | int flags; /* flags to find out type of domain */ |
232 | 238 | ||
233 | int iommu_coherency;/* indicate coherency of iommu access */ | 239 | int iommu_coherency;/* indicate coherency of iommu access */ |
240 | int iommu_snooping; /* indicate snooping control feature*/ | ||
234 | int iommu_count; /* reference count of iommu */ | 241 | int iommu_count; /* reference count of iommu */ |
235 | spinlock_t iommu_lock; /* protect iommu set in domain */ | 242 | spinlock_t iommu_lock; /* protect iommu set in domain */ |
236 | u64 max_addr; /* maximum mapped address */ | 243 | u64 max_addr; /* maximum mapped address */ |
@@ -421,7 +428,6 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) | |||
421 | return g_iommus[iommu_id]; | 428 | return g_iommus[iommu_id]; |
422 | } | 429 | } |
423 | 430 | ||
424 | /* "Coherency" capability may be different across iommus */ | ||
425 | static void domain_update_iommu_coherency(struct dmar_domain *domain) | 431 | static void domain_update_iommu_coherency(struct dmar_domain *domain) |
426 | { | 432 | { |
427 | int i; | 433 | int i; |
@@ -438,6 +444,29 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) | |||
438 | } | 444 | } |
439 | } | 445 | } |
440 | 446 | ||
447 | static void domain_update_iommu_snooping(struct dmar_domain *domain) | ||
448 | { | ||
449 | int i; | ||
450 | |||
451 | domain->iommu_snooping = 1; | ||
452 | |||
453 | i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); | ||
454 | for (; i < g_num_of_iommus; ) { | ||
455 | if (!ecap_sc_support(g_iommus[i]->ecap)) { | ||
456 | domain->iommu_snooping = 0; | ||
457 | break; | ||
458 | } | ||
459 | i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | /* Some capabilities may be different across iommus */ | ||
464 | static void domain_update_iommu_cap(struct dmar_domain *domain) | ||
465 | { | ||
466 | domain_update_iommu_coherency(domain); | ||
467 | domain_update_iommu_snooping(domain); | ||
468 | } | ||
469 | |||
441 | static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn) | 470 | static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn) |
442 | { | 471 | { |
443 | struct dmar_drhd_unit *drhd = NULL; | 472 | struct dmar_drhd_unit *drhd = NULL; |
@@ -689,15 +718,17 @@ static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr) | |||
689 | static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) | 718 | static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) |
690 | { | 719 | { |
691 | int addr_width = agaw_to_width(domain->agaw); | 720 | int addr_width = agaw_to_width(domain->agaw); |
721 | int npages; | ||
692 | 722 | ||
693 | start &= (((u64)1) << addr_width) - 1; | 723 | start &= (((u64)1) << addr_width) - 1; |
694 | end &= (((u64)1) << addr_width) - 1; | 724 | end &= (((u64)1) << addr_width) - 1; |
695 | /* in case it's partial page */ | 725 | /* in case it's partial page */ |
696 | start = PAGE_ALIGN(start); | 726 | start = PAGE_ALIGN(start); |
697 | end &= PAGE_MASK; | 727 | end &= PAGE_MASK; |
728 | npages = (end - start) / VTD_PAGE_SIZE; | ||
698 | 729 | ||
699 | /* we don't need lock here, nobody else touches the iova range */ | 730 | /* we don't need lock here, nobody else touches the iova range */ |
700 | while (start < end) { | 731 | while (npages--) { |
701 | dma_pte_clear_one(domain, start); | 732 | dma_pte_clear_one(domain, start); |
702 | start += VTD_PAGE_SIZE; | 733 | start += VTD_PAGE_SIZE; |
703 | } | 734 | } |
@@ -1004,194 +1035,6 @@ static int iommu_disable_translation(struct intel_iommu *iommu) | |||
1004 | return 0; | 1035 | return 0; |
1005 | } | 1036 | } |
1006 | 1037 | ||
1007 | /* iommu interrupt handling. Most stuff are MSI-like. */ | ||
1008 | |||
1009 | static const char *fault_reason_strings[] = | ||
1010 | { | ||
1011 | "Software", | ||
1012 | "Present bit in root entry is clear", | ||
1013 | "Present bit in context entry is clear", | ||
1014 | "Invalid context entry", | ||
1015 | "Access beyond MGAW", | ||
1016 | "PTE Write access is not set", | ||
1017 | "PTE Read access is not set", | ||
1018 | "Next page table ptr is invalid", | ||
1019 | "Root table address invalid", | ||
1020 | "Context table ptr is invalid", | ||
1021 | "non-zero reserved fields in RTP", | ||
1022 | "non-zero reserved fields in CTP", | ||
1023 | "non-zero reserved fields in PTE", | ||
1024 | }; | ||
1025 | #define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1) | ||
1026 | |||
1027 | const char *dmar_get_fault_reason(u8 fault_reason) | ||
1028 | { | ||
1029 | if (fault_reason > MAX_FAULT_REASON_IDX) | ||
1030 | return "Unknown"; | ||
1031 | else | ||
1032 | return fault_reason_strings[fault_reason]; | ||
1033 | } | ||
1034 | |||
1035 | void dmar_msi_unmask(unsigned int irq) | ||
1036 | { | ||
1037 | struct intel_iommu *iommu = get_irq_data(irq); | ||
1038 | unsigned long flag; | ||
1039 | |||
1040 | /* unmask it */ | ||
1041 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1042 | writel(0, iommu->reg + DMAR_FECTL_REG); | ||
1043 | /* Read a reg to force flush the post write */ | ||
1044 | readl(iommu->reg + DMAR_FECTL_REG); | ||
1045 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1046 | } | ||
1047 | |||
1048 | void dmar_msi_mask(unsigned int irq) | ||
1049 | { | ||
1050 | unsigned long flag; | ||
1051 | struct intel_iommu *iommu = get_irq_data(irq); | ||
1052 | |||
1053 | /* mask it */ | ||
1054 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1055 | writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG); | ||
1056 | /* Read a reg to force flush the post write */ | ||
1057 | readl(iommu->reg + DMAR_FECTL_REG); | ||
1058 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1059 | } | ||
1060 | |||
1061 | void dmar_msi_write(int irq, struct msi_msg *msg) | ||
1062 | { | ||
1063 | struct intel_iommu *iommu = get_irq_data(irq); | ||
1064 | unsigned long flag; | ||
1065 | |||
1066 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1067 | writel(msg->data, iommu->reg + DMAR_FEDATA_REG); | ||
1068 | writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG); | ||
1069 | writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG); | ||
1070 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1071 | } | ||
1072 | |||
1073 | void dmar_msi_read(int irq, struct msi_msg *msg) | ||
1074 | { | ||
1075 | struct intel_iommu *iommu = get_irq_data(irq); | ||
1076 | unsigned long flag; | ||
1077 | |||
1078 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1079 | msg->data = readl(iommu->reg + DMAR_FEDATA_REG); | ||
1080 | msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG); | ||
1081 | msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG); | ||
1082 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1083 | } | ||
1084 | |||
1085 | static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type, | ||
1086 | u8 fault_reason, u16 source_id, unsigned long long addr) | ||
1087 | { | ||
1088 | const char *reason; | ||
1089 | |||
1090 | reason = dmar_get_fault_reason(fault_reason); | ||
1091 | |||
1092 | printk(KERN_ERR | ||
1093 | "DMAR:[%s] Request device [%02x:%02x.%d] " | ||
1094 | "fault addr %llx \n" | ||
1095 | "DMAR:[fault reason %02d] %s\n", | ||
1096 | (type ? "DMA Read" : "DMA Write"), | ||
1097 | (source_id >> 8), PCI_SLOT(source_id & 0xFF), | ||
1098 | PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | #define PRIMARY_FAULT_REG_LEN (16) | ||
1103 | static irqreturn_t iommu_page_fault(int irq, void *dev_id) | ||
1104 | { | ||
1105 | struct intel_iommu *iommu = dev_id; | ||
1106 | int reg, fault_index; | ||
1107 | u32 fault_status; | ||
1108 | unsigned long flag; | ||
1109 | |||
1110 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1111 | fault_status = readl(iommu->reg + DMAR_FSTS_REG); | ||
1112 | |||
1113 | /* TBD: ignore advanced fault log currently */ | ||
1114 | if (!(fault_status & DMA_FSTS_PPF)) | ||
1115 | goto clear_overflow; | ||
1116 | |||
1117 | fault_index = dma_fsts_fault_record_index(fault_status); | ||
1118 | reg = cap_fault_reg_offset(iommu->cap); | ||
1119 | while (1) { | ||
1120 | u8 fault_reason; | ||
1121 | u16 source_id; | ||
1122 | u64 guest_addr; | ||
1123 | int type; | ||
1124 | u32 data; | ||
1125 | |||
1126 | /* highest 32 bits */ | ||
1127 | data = readl(iommu->reg + reg + | ||
1128 | fault_index * PRIMARY_FAULT_REG_LEN + 12); | ||
1129 | if (!(data & DMA_FRCD_F)) | ||
1130 | break; | ||
1131 | |||
1132 | fault_reason = dma_frcd_fault_reason(data); | ||
1133 | type = dma_frcd_type(data); | ||
1134 | |||
1135 | data = readl(iommu->reg + reg + | ||
1136 | fault_index * PRIMARY_FAULT_REG_LEN + 8); | ||
1137 | source_id = dma_frcd_source_id(data); | ||
1138 | |||
1139 | guest_addr = dmar_readq(iommu->reg + reg + | ||
1140 | fault_index * PRIMARY_FAULT_REG_LEN); | ||
1141 | guest_addr = dma_frcd_page_addr(guest_addr); | ||
1142 | /* clear the fault */ | ||
1143 | writel(DMA_FRCD_F, iommu->reg + reg + | ||
1144 | fault_index * PRIMARY_FAULT_REG_LEN + 12); | ||
1145 | |||
1146 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1147 | |||
1148 | iommu_page_fault_do_one(iommu, type, fault_reason, | ||
1149 | source_id, guest_addr); | ||
1150 | |||
1151 | fault_index++; | ||
1152 | if (fault_index > cap_num_fault_regs(iommu->cap)) | ||
1153 | fault_index = 0; | ||
1154 | spin_lock_irqsave(&iommu->register_lock, flag); | ||
1155 | } | ||
1156 | clear_overflow: | ||
1157 | /* clear primary fault overflow */ | ||
1158 | fault_status = readl(iommu->reg + DMAR_FSTS_REG); | ||
1159 | if (fault_status & DMA_FSTS_PFO) | ||
1160 | writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG); | ||
1161 | |||
1162 | spin_unlock_irqrestore(&iommu->register_lock, flag); | ||
1163 | return IRQ_HANDLED; | ||
1164 | } | ||
1165 | |||
1166 | int dmar_set_interrupt(struct intel_iommu *iommu) | ||
1167 | { | ||
1168 | int irq, ret; | ||
1169 | |||
1170 | irq = create_irq(); | ||
1171 | if (!irq) { | ||
1172 | printk(KERN_ERR "IOMMU: no free vectors\n"); | ||
1173 | return -EINVAL; | ||
1174 | } | ||
1175 | |||
1176 | set_irq_data(irq, iommu); | ||
1177 | iommu->irq = irq; | ||
1178 | |||
1179 | ret = arch_setup_dmar_msi(irq); | ||
1180 | if (ret) { | ||
1181 | set_irq_data(irq, NULL); | ||
1182 | iommu->irq = 0; | ||
1183 | destroy_irq(irq); | ||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | /* Force fault register is cleared */ | ||
1188 | iommu_page_fault(irq, iommu); | ||
1189 | |||
1190 | ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu); | ||
1191 | if (ret) | ||
1192 | printk(KERN_ERR "IOMMU: can't request irq\n"); | ||
1193 | return ret; | ||
1194 | } | ||
1195 | 1038 | ||
1196 | static int iommu_init_domains(struct intel_iommu *iommu) | 1039 | static int iommu_init_domains(struct intel_iommu *iommu) |
1197 | { | 1040 | { |
@@ -1429,6 +1272,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1429 | else | 1272 | else |
1430 | domain->iommu_coherency = 0; | 1273 | domain->iommu_coherency = 0; |
1431 | 1274 | ||
1275 | if (ecap_sc_support(iommu->ecap)) | ||
1276 | domain->iommu_snooping = 1; | ||
1277 | else | ||
1278 | domain->iommu_snooping = 0; | ||
1279 | |||
1432 | domain->iommu_count = 1; | 1280 | domain->iommu_count = 1; |
1433 | 1281 | ||
1434 | /* always allocate the top pgd */ | 1282 | /* always allocate the top pgd */ |
@@ -1557,7 +1405,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, | |||
1557 | spin_lock_irqsave(&domain->iommu_lock, flags); | 1405 | spin_lock_irqsave(&domain->iommu_lock, flags); |
1558 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { | 1406 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { |
1559 | domain->iommu_count++; | 1407 | domain->iommu_count++; |
1560 | domain_update_iommu_coherency(domain); | 1408 | domain_update_iommu_cap(domain); |
1561 | } | 1409 | } |
1562 | spin_unlock_irqrestore(&domain->iommu_lock, flags); | 1410 | spin_unlock_irqrestore(&domain->iommu_lock, flags); |
1563 | return 0; | 1411 | return 0; |
@@ -1657,6 +1505,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | |||
1657 | BUG_ON(dma_pte_addr(pte)); | 1505 | BUG_ON(dma_pte_addr(pte)); |
1658 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); | 1506 | dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); |
1659 | dma_set_pte_prot(pte, prot); | 1507 | dma_set_pte_prot(pte, prot); |
1508 | if (prot & DMA_PTE_SNP) | ||
1509 | dma_set_pte_snp(pte); | ||
1660 | domain_flush_cache(domain, pte, sizeof(*pte)); | 1510 | domain_flush_cache(domain, pte, sizeof(*pte)); |
1661 | start_pfn++; | 1511 | start_pfn++; |
1662 | index++; | 1512 | index++; |
@@ -1970,7 +1820,7 @@ static inline void iommu_prepare_isa(void) | |||
1970 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); | 1820 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); |
1971 | 1821 | ||
1972 | if (ret) | 1822 | if (ret) |
1973 | printk("IOMMU: Failed to create 0-64M identity map, " | 1823 | printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " |
1974 | "floppy might not work\n"); | 1824 | "floppy might not work\n"); |
1975 | 1825 | ||
1976 | } | 1826 | } |
@@ -1987,7 +1837,7 @@ static int __init init_dmars(void) | |||
1987 | struct dmar_rmrr_unit *rmrr; | 1837 | struct dmar_rmrr_unit *rmrr; |
1988 | struct pci_dev *pdev; | 1838 | struct pci_dev *pdev; |
1989 | struct intel_iommu *iommu; | 1839 | struct intel_iommu *iommu; |
1990 | int i, ret, unit = 0; | 1840 | int i, ret; |
1991 | 1841 | ||
1992 | /* | 1842 | /* |
1993 | * for each drhd | 1843 | * for each drhd |
@@ -2043,11 +1893,40 @@ static int __init init_dmars(void) | |||
2043 | } | 1893 | } |
2044 | } | 1894 | } |
2045 | 1895 | ||
1896 | /* | ||
1897 | * Start from the sane iommu hardware state. | ||
1898 | */ | ||
2046 | for_each_drhd_unit(drhd) { | 1899 | for_each_drhd_unit(drhd) { |
2047 | if (drhd->ignored) | 1900 | if (drhd->ignored) |
2048 | continue; | 1901 | continue; |
2049 | 1902 | ||
2050 | iommu = drhd->iommu; | 1903 | iommu = drhd->iommu; |
1904 | |||
1905 | /* | ||
1906 | * If the queued invalidation is already initialized by us | ||
1907 | * (for example, while enabling interrupt-remapping) then | ||
1908 | * we got the things already rolling from a sane state. | ||
1909 | */ | ||
1910 | if (iommu->qi) | ||
1911 | continue; | ||
1912 | |||
1913 | /* | ||
1914 | * Clear any previous faults. | ||
1915 | */ | ||
1916 | dmar_fault(-1, iommu); | ||
1917 | /* | ||
1918 | * Disable queued invalidation if supported and already enabled | ||
1919 | * before OS handover. | ||
1920 | */ | ||
1921 | dmar_disable_qi(iommu); | ||
1922 | } | ||
1923 | |||
1924 | for_each_drhd_unit(drhd) { | ||
1925 | if (drhd->ignored) | ||
1926 | continue; | ||
1927 | |||
1928 | iommu = drhd->iommu; | ||
1929 | |||
2051 | if (dmar_enable_qi(iommu)) { | 1930 | if (dmar_enable_qi(iommu)) { |
2052 | /* | 1931 | /* |
2053 | * Queued Invalidate not enabled, use Register Based | 1932 | * Queued Invalidate not enabled, use Register Based |
@@ -2109,7 +1988,6 @@ static int __init init_dmars(void) | |||
2109 | if (drhd->ignored) | 1988 | if (drhd->ignored) |
2110 | continue; | 1989 | continue; |
2111 | iommu = drhd->iommu; | 1990 | iommu = drhd->iommu; |
2112 | sprintf (iommu->name, "dmar%d", unit++); | ||
2113 | 1991 | ||
2114 | iommu_flush_write_buffer(iommu); | 1992 | iommu_flush_write_buffer(iommu); |
2115 | 1993 | ||
@@ -2279,16 +2157,18 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2279 | error: | 2157 | error: |
2280 | if (iova) | 2158 | if (iova) |
2281 | __free_iova(&domain->iovad, iova); | 2159 | __free_iova(&domain->iovad, iova); |
2282 | printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n", | 2160 | printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n", |
2283 | pci_name(pdev), size, (unsigned long long)paddr, dir); | 2161 | pci_name(pdev), size, (unsigned long long)paddr, dir); |
2284 | return 0; | 2162 | return 0; |
2285 | } | 2163 | } |
2286 | 2164 | ||
2287 | dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr, | 2165 | static dma_addr_t intel_map_page(struct device *dev, struct page *page, |
2288 | size_t size, int dir) | 2166 | unsigned long offset, size_t size, |
2167 | enum dma_data_direction dir, | ||
2168 | struct dma_attrs *attrs) | ||
2289 | { | 2169 | { |
2290 | return __intel_map_single(hwdev, paddr, size, dir, | 2170 | return __intel_map_single(dev, page_to_phys(page) + offset, size, |
2291 | to_pci_dev(hwdev)->dma_mask); | 2171 | dir, to_pci_dev(dev)->dma_mask); |
2292 | } | 2172 | } |
2293 | 2173 | ||
2294 | static void flush_unmaps(void) | 2174 | static void flush_unmaps(void) |
@@ -2352,8 +2232,9 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova) | |||
2352 | spin_unlock_irqrestore(&async_umap_flush_lock, flags); | 2232 | spin_unlock_irqrestore(&async_umap_flush_lock, flags); |
2353 | } | 2233 | } |
2354 | 2234 | ||
2355 | void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, | 2235 | static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, |
2356 | int dir) | 2236 | size_t size, enum dma_data_direction dir, |
2237 | struct dma_attrs *attrs) | ||
2357 | { | 2238 | { |
2358 | struct pci_dev *pdev = to_pci_dev(dev); | 2239 | struct pci_dev *pdev = to_pci_dev(dev); |
2359 | struct dmar_domain *domain; | 2240 | struct dmar_domain *domain; |
@@ -2375,7 +2256,7 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, | |||
2375 | start_addr = iova->pfn_lo << PAGE_SHIFT; | 2256 | start_addr = iova->pfn_lo << PAGE_SHIFT; |
2376 | size = aligned_size((u64)dev_addr, size); | 2257 | size = aligned_size((u64)dev_addr, size); |
2377 | 2258 | ||
2378 | pr_debug("Device %s unmapping: %lx@%llx\n", | 2259 | pr_debug("Device %s unmapping: %zx@%llx\n", |
2379 | pci_name(pdev), size, (unsigned long long)start_addr); | 2260 | pci_name(pdev), size, (unsigned long long)start_addr); |
2380 | 2261 | ||
2381 | /* clear the whole page */ | 2262 | /* clear the whole page */ |
@@ -2397,8 +2278,14 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, | |||
2397 | } | 2278 | } |
2398 | } | 2279 | } |
2399 | 2280 | ||
2400 | void *intel_alloc_coherent(struct device *hwdev, size_t size, | 2281 | static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, |
2401 | dma_addr_t *dma_handle, gfp_t flags) | 2282 | int dir) |
2283 | { | ||
2284 | intel_unmap_page(dev, dev_addr, size, dir, NULL); | ||
2285 | } | ||
2286 | |||
2287 | static void *intel_alloc_coherent(struct device *hwdev, size_t size, | ||
2288 | dma_addr_t *dma_handle, gfp_t flags) | ||
2402 | { | 2289 | { |
2403 | void *vaddr; | 2290 | void *vaddr; |
2404 | int order; | 2291 | int order; |
@@ -2421,8 +2308,8 @@ void *intel_alloc_coherent(struct device *hwdev, size_t size, | |||
2421 | return NULL; | 2308 | return NULL; |
2422 | } | 2309 | } |
2423 | 2310 | ||
2424 | void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 2311 | static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
2425 | dma_addr_t dma_handle) | 2312 | dma_addr_t dma_handle) |
2426 | { | 2313 | { |
2427 | int order; | 2314 | int order; |
2428 | 2315 | ||
@@ -2433,10 +2320,9 @@ void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
2433 | free_pages((unsigned long)vaddr, order); | 2320 | free_pages((unsigned long)vaddr, order); |
2434 | } | 2321 | } |
2435 | 2322 | ||
2436 | #define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) | 2323 | static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, |
2437 | 2324 | int nelems, enum dma_data_direction dir, | |
2438 | void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | 2325 | struct dma_attrs *attrs) |
2439 | int nelems, int dir) | ||
2440 | { | 2326 | { |
2441 | int i; | 2327 | int i; |
2442 | struct pci_dev *pdev = to_pci_dev(hwdev); | 2328 | struct pci_dev *pdev = to_pci_dev(hwdev); |
@@ -2444,7 +2330,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
2444 | unsigned long start_addr; | 2330 | unsigned long start_addr; |
2445 | struct iova *iova; | 2331 | struct iova *iova; |
2446 | size_t size = 0; | 2332 | size_t size = 0; |
2447 | void *addr; | 2333 | phys_addr_t addr; |
2448 | struct scatterlist *sg; | 2334 | struct scatterlist *sg; |
2449 | struct intel_iommu *iommu; | 2335 | struct intel_iommu *iommu; |
2450 | 2336 | ||
@@ -2460,7 +2346,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
2460 | if (!iova) | 2346 | if (!iova) |
2461 | return; | 2347 | return; |
2462 | for_each_sg(sglist, sg, nelems, i) { | 2348 | for_each_sg(sglist, sg, nelems, i) { |
2463 | addr = SG_ENT_VIRT_ADDRESS(sg); | 2349 | addr = page_to_phys(sg_page(sg)) + sg->offset; |
2464 | size += aligned_size((u64)addr, sg->length); | 2350 | size += aligned_size((u64)addr, sg->length); |
2465 | } | 2351 | } |
2466 | 2352 | ||
@@ -2487,16 +2373,16 @@ static int intel_nontranslate_map_sg(struct device *hddev, | |||
2487 | 2373 | ||
2488 | for_each_sg(sglist, sg, nelems, i) { | 2374 | for_each_sg(sglist, sg, nelems, i) { |
2489 | BUG_ON(!sg_page(sg)); | 2375 | BUG_ON(!sg_page(sg)); |
2490 | sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)); | 2376 | sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset; |
2491 | sg->dma_length = sg->length; | 2377 | sg->dma_length = sg->length; |
2492 | } | 2378 | } |
2493 | return nelems; | 2379 | return nelems; |
2494 | } | 2380 | } |
2495 | 2381 | ||
2496 | int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | 2382 | static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, |
2497 | int dir) | 2383 | enum dma_data_direction dir, struct dma_attrs *attrs) |
2498 | { | 2384 | { |
2499 | void *addr; | 2385 | phys_addr_t addr; |
2500 | int i; | 2386 | int i; |
2501 | struct pci_dev *pdev = to_pci_dev(hwdev); | 2387 | struct pci_dev *pdev = to_pci_dev(hwdev); |
2502 | struct dmar_domain *domain; | 2388 | struct dmar_domain *domain; |
@@ -2520,8 +2406,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
2520 | iommu = domain_get_iommu(domain); | 2406 | iommu = domain_get_iommu(domain); |
2521 | 2407 | ||
2522 | for_each_sg(sglist, sg, nelems, i) { | 2408 | for_each_sg(sglist, sg, nelems, i) { |
2523 | addr = SG_ENT_VIRT_ADDRESS(sg); | 2409 | addr = page_to_phys(sg_page(sg)) + sg->offset; |
2524 | addr = (void *)virt_to_phys(addr); | ||
2525 | size += aligned_size((u64)addr, sg->length); | 2410 | size += aligned_size((u64)addr, sg->length); |
2526 | } | 2411 | } |
2527 | 2412 | ||
@@ -2544,8 +2429,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
2544 | start_addr = iova->pfn_lo << PAGE_SHIFT; | 2429 | start_addr = iova->pfn_lo << PAGE_SHIFT; |
2545 | offset = 0; | 2430 | offset = 0; |
2546 | for_each_sg(sglist, sg, nelems, i) { | 2431 | for_each_sg(sglist, sg, nelems, i) { |
2547 | addr = SG_ENT_VIRT_ADDRESS(sg); | 2432 | addr = page_to_phys(sg_page(sg)) + sg->offset; |
2548 | addr = (void *)virt_to_phys(addr); | ||
2549 | size = aligned_size((u64)addr, sg->length); | 2433 | size = aligned_size((u64)addr, sg->length); |
2550 | ret = domain_page_mapping(domain, start_addr + offset, | 2434 | ret = domain_page_mapping(domain, start_addr + offset, |
2551 | ((u64)addr) & PAGE_MASK, | 2435 | ((u64)addr) & PAGE_MASK, |
@@ -2574,13 +2458,19 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, | |||
2574 | return nelems; | 2458 | return nelems; |
2575 | } | 2459 | } |
2576 | 2460 | ||
2577 | static struct dma_mapping_ops intel_dma_ops = { | 2461 | static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr) |
2462 | { | ||
2463 | return !dma_addr; | ||
2464 | } | ||
2465 | |||
2466 | struct dma_map_ops intel_dma_ops = { | ||
2578 | .alloc_coherent = intel_alloc_coherent, | 2467 | .alloc_coherent = intel_alloc_coherent, |
2579 | .free_coherent = intel_free_coherent, | 2468 | .free_coherent = intel_free_coherent, |
2580 | .map_single = intel_map_single, | ||
2581 | .unmap_single = intel_unmap_single, | ||
2582 | .map_sg = intel_map_sg, | 2469 | .map_sg = intel_map_sg, |
2583 | .unmap_sg = intel_unmap_sg, | 2470 | .unmap_sg = intel_unmap_sg, |
2471 | .map_page = intel_map_page, | ||
2472 | .unmap_page = intel_unmap_page, | ||
2473 | .mapping_error = intel_mapping_error, | ||
2584 | }; | 2474 | }; |
2585 | 2475 | ||
2586 | static inline int iommu_domain_cache_init(void) | 2476 | static inline int iommu_domain_cache_init(void) |
@@ -2772,6 +2662,33 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain, | |||
2772 | return 0; | 2662 | return 0; |
2773 | } | 2663 | } |
2774 | 2664 | ||
2665 | static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | ||
2666 | struct pci_dev *pdev) | ||
2667 | { | ||
2668 | struct pci_dev *tmp, *parent; | ||
2669 | |||
2670 | if (!iommu || !pdev) | ||
2671 | return; | ||
2672 | |||
2673 | /* dependent device detach */ | ||
2674 | tmp = pci_find_upstream_pcie_bridge(pdev); | ||
2675 | /* Secondary interface's bus number and devfn 0 */ | ||
2676 | if (tmp) { | ||
2677 | parent = pdev->bus->self; | ||
2678 | while (parent != tmp) { | ||
2679 | iommu_detach_dev(iommu, parent->bus->number, | ||
2680 | parent->devfn); | ||
2681 | parent = parent->bus->self; | ||
2682 | } | ||
2683 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | ||
2684 | iommu_detach_dev(iommu, | ||
2685 | tmp->subordinate->number, 0); | ||
2686 | else /* this is a legacy PCI bridge */ | ||
2687 | iommu_detach_dev(iommu, | ||
2688 | tmp->bus->number, tmp->devfn); | ||
2689 | } | ||
2690 | } | ||
2691 | |||
2775 | static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, | 2692 | static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, |
2776 | struct pci_dev *pdev) | 2693 | struct pci_dev *pdev) |
2777 | { | 2694 | { |
@@ -2797,6 +2714,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, | |||
2797 | spin_unlock_irqrestore(&device_domain_lock, flags); | 2714 | spin_unlock_irqrestore(&device_domain_lock, flags); |
2798 | 2715 | ||
2799 | iommu_detach_dev(iommu, info->bus, info->devfn); | 2716 | iommu_detach_dev(iommu, info->bus, info->devfn); |
2717 | iommu_detach_dependent_devices(iommu, pdev); | ||
2800 | free_devinfo_mem(info); | 2718 | free_devinfo_mem(info); |
2801 | 2719 | ||
2802 | spin_lock_irqsave(&device_domain_lock, flags); | 2720 | spin_lock_irqsave(&device_domain_lock, flags); |
@@ -2820,7 +2738,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, | |||
2820 | spin_lock_irqsave(&domain->iommu_lock, tmp_flags); | 2738 | spin_lock_irqsave(&domain->iommu_lock, tmp_flags); |
2821 | clear_bit(iommu->seq_id, &domain->iommu_bmp); | 2739 | clear_bit(iommu->seq_id, &domain->iommu_bmp); |
2822 | domain->iommu_count--; | 2740 | domain->iommu_count--; |
2823 | domain_update_iommu_coherency(domain); | 2741 | domain_update_iommu_cap(domain); |
2824 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | 2742 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
2825 | } | 2743 | } |
2826 | 2744 | ||
@@ -2846,15 +2764,16 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain) | |||
2846 | 2764 | ||
2847 | iommu = device_to_iommu(info->bus, info->devfn); | 2765 | iommu = device_to_iommu(info->bus, info->devfn); |
2848 | iommu_detach_dev(iommu, info->bus, info->devfn); | 2766 | iommu_detach_dev(iommu, info->bus, info->devfn); |
2767 | iommu_detach_dependent_devices(iommu, info->dev); | ||
2849 | 2768 | ||
2850 | /* clear this iommu in iommu_bmp, update iommu count | 2769 | /* clear this iommu in iommu_bmp, update iommu count |
2851 | * and coherency | 2770 | * and capabilities |
2852 | */ | 2771 | */ |
2853 | spin_lock_irqsave(&domain->iommu_lock, flags2); | 2772 | spin_lock_irqsave(&domain->iommu_lock, flags2); |
2854 | if (test_and_clear_bit(iommu->seq_id, | 2773 | if (test_and_clear_bit(iommu->seq_id, |
2855 | &domain->iommu_bmp)) { | 2774 | &domain->iommu_bmp)) { |
2856 | domain->iommu_count--; | 2775 | domain->iommu_count--; |
2857 | domain_update_iommu_coherency(domain); | 2776 | domain_update_iommu_cap(domain); |
2858 | } | 2777 | } |
2859 | spin_unlock_irqrestore(&domain->iommu_lock, flags2); | 2778 | spin_unlock_irqrestore(&domain->iommu_lock, flags2); |
2860 | 2779 | ||
@@ -3077,6 +2996,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain, | |||
3077 | prot |= DMA_PTE_READ; | 2996 | prot |= DMA_PTE_READ; |
3078 | if (iommu_prot & IOMMU_WRITE) | 2997 | if (iommu_prot & IOMMU_WRITE) |
3079 | prot |= DMA_PTE_WRITE; | 2998 | prot |= DMA_PTE_WRITE; |
2999 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) | ||
3000 | prot |= DMA_PTE_SNP; | ||
3080 | 3001 | ||
3081 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); | 3002 | max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); |
3082 | if (dmar_domain->max_addr < max_addr) { | 3003 | if (dmar_domain->max_addr < max_addr) { |
@@ -3130,6 +3051,17 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | |||
3130 | return phys; | 3051 | return phys; |
3131 | } | 3052 | } |
3132 | 3053 | ||
3054 | static int intel_iommu_domain_has_cap(struct iommu_domain *domain, | ||
3055 | unsigned long cap) | ||
3056 | { | ||
3057 | struct dmar_domain *dmar_domain = domain->priv; | ||
3058 | |||
3059 | if (cap == IOMMU_CAP_CACHE_COHERENCY) | ||
3060 | return dmar_domain->iommu_snooping; | ||
3061 | |||
3062 | return 0; | ||
3063 | } | ||
3064 | |||
3133 | static struct iommu_ops intel_iommu_ops = { | 3065 | static struct iommu_ops intel_iommu_ops = { |
3134 | .domain_init = intel_iommu_domain_init, | 3066 | .domain_init = intel_iommu_domain_init, |
3135 | .domain_destroy = intel_iommu_domain_destroy, | 3067 | .domain_destroy = intel_iommu_domain_destroy, |
@@ -3138,6 +3070,7 @@ static struct iommu_ops intel_iommu_ops = { | |||
3138 | .map = intel_iommu_map_range, | 3070 | .map = intel_iommu_map_range, |
3139 | .unmap = intel_iommu_unmap_range, | 3071 | .unmap = intel_iommu_unmap_range, |
3140 | .iova_to_phys = intel_iommu_iova_to_phys, | 3072 | .iova_to_phys = intel_iommu_iova_to_phys, |
3073 | .domain_has_cap = intel_iommu_domain_has_cap, | ||
3141 | }; | 3074 | }; |
3142 | 3075 | ||
3143 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | 3076 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) |