Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/iommu: Move pSeries specific functions to pseries/iommu.c

The PowerNV specific table_group_ops are defined in powernv/pci-ioda.c.
The pSeries specific table_group_ops are sitting in the generic powerpc
file. Move it to where it actually belong(pseries/iommu.c).

The functions are currently defined even for CONFIG_PPC_POWERNV
which are unused on PowerNV.

Only code movement, no functional changes intended.

Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/171923269701.1397.15758640002786937132.stgit@linux.ibm.com

authored by

Shivaprasad G Bhat and committed by
Michael Ellerman
b09c031d 932bed41

+149 -148
+3 -1
arch/powerpc/include/asm/iommu.h
··· 158 158 extern struct iommu_table *iommu_init_table(struct iommu_table *tbl, 159 159 int nid, unsigned long res_start, unsigned long res_end); 160 160 bool iommu_table_in_use(struct iommu_table *tbl); 161 + extern void iommu_table_reserve_pages(struct iommu_table *tbl, 162 + unsigned long res_start, unsigned long res_end); 163 + extern void iommu_table_clear(struct iommu_table *tbl); 161 164 162 165 #define IOMMU_TABLE_GROUP_MAX_TABLES 2 163 166 ··· 223 220 extern void iommu_tce_kill(struct iommu_table *tbl, 224 221 unsigned long entry, unsigned long pages); 225 222 226 - extern struct iommu_table_group_ops spapr_tce_table_group_ops; 227 223 #else 228 224 static inline void iommu_register_group(struct iommu_table_group *table_group, 229 225 int pci_domain_number,
+2 -147
arch/powerpc/kernel/iommu.c
··· 643 643 tbl->it_ops->flush(tbl); 644 644 } 645 645 646 - static void iommu_table_clear(struct iommu_table *tbl) 646 + void iommu_table_clear(struct iommu_table *tbl) 647 647 { 648 648 /* 649 649 * In case of firmware assisted dump system goes through clean ··· 684 684 #endif 685 685 } 686 686 687 - static void iommu_table_reserve_pages(struct iommu_table *tbl, 687 + void iommu_table_reserve_pages(struct iommu_table *tbl, 688 688 unsigned long res_start, unsigned long res_end) 689 689 { 690 690 int i; ··· 1102 1102 } 1103 1103 EXPORT_SYMBOL_GPL(iommu_tce_kill); 1104 1104 1105 - #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 1106 - static int iommu_take_ownership(struct iommu_table *tbl) 1107 - { 1108 - unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; 1109 - int ret = 0; 1110 - 1111 - /* 1112 - * VFIO does not control TCE entries allocation and the guest 1113 - * can write new TCEs on top of existing ones so iommu_tce_build() 1114 - * must be able to release old pages. This functionality 1115 - * requires exchange() callback defined so if it is not 1116 - * implemented, we disallow taking ownership over the table. 1117 - */ 1118 - if (!tbl->it_ops->xchg_no_kill) 1119 - return -EINVAL; 1120 - 1121 - spin_lock_irqsave(&tbl->large_pool.lock, flags); 1122 - for (i = 0; i < tbl->nr_pools; i++) 1123 - spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); 1124 - 1125 - if (iommu_table_in_use(tbl)) { 1126 - pr_err("iommu_tce: it_map is not empty"); 1127 - ret = -EBUSY; 1128 - } else { 1129 - memset(tbl->it_map, 0xff, sz); 1130 - } 1131 - 1132 - for (i = 0; i < tbl->nr_pools; i++) 1133 - spin_unlock(&tbl->pools[i].lock); 1134 - spin_unlock_irqrestore(&tbl->large_pool.lock, flags); 1135 - 1136 - return ret; 1137 - } 1138 - 1139 - static void iommu_release_ownership(struct iommu_table *tbl) 1140 - { 1141 - unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; 1142 - 1143 - spin_lock_irqsave(&tbl->large_pool.lock, flags); 1144 - for (i = 0; i < tbl->nr_pools; i++) 1145 - spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); 1146 - 1147 - memset(tbl->it_map, 0, sz); 1148 - 1149 - iommu_table_reserve_pages(tbl, tbl->it_reserved_start, 1150 - tbl->it_reserved_end); 1151 - 1152 - for (i = 0; i < tbl->nr_pools; i++) 1153 - spin_unlock(&tbl->pools[i].lock); 1154 - spin_unlock_irqrestore(&tbl->large_pool.lock, flags); 1155 - } 1156 - #endif 1157 - 1158 1105 int iommu_add_device(struct iommu_table_group *table_group, struct device *dev) 1159 1106 { 1160 1107 /* ··· 1133 1186 EXPORT_SYMBOL_GPL(iommu_add_device); 1134 1187 1135 1188 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 1136 - /* 1137 - * A simple iommu_table_group_ops which only allows reusing the existing 1138 - * iommu_table. This handles VFIO for POWER7 or the nested KVM. 1139 - * The ops does not allow creating windows and only allows reusing the existing 1140 - * one if it matches table_group->tce32_start/tce32_size/page_shift. 1141 - */ 1142 - static unsigned long spapr_tce_get_table_size(__u32 page_shift, 1143 - __u64 window_size, __u32 levels) 1144 - { 1145 - unsigned long size; 1146 - 1147 - if (levels > 1) 1148 - return ~0U; 1149 - size = window_size >> (page_shift - 3); 1150 - return size; 1151 - } 1152 - 1153 - static long spapr_tce_create_table(struct iommu_table_group *table_group, int num, 1154 - __u32 page_shift, __u64 window_size, __u32 levels, 1155 - struct iommu_table **ptbl) 1156 - { 1157 - struct iommu_table *tbl = table_group->tables[0]; 1158 - 1159 - if (num > 0) 1160 - return -EPERM; 1161 - 1162 - if (tbl->it_page_shift != page_shift || 1163 - tbl->it_size != (window_size >> page_shift) || 1164 - tbl->it_indirect_levels != levels - 1) 1165 - return -EINVAL; 1166 - 1167 - *ptbl = iommu_tce_table_get(tbl); 1168 - return 0; 1169 - } 1170 - 1171 - static long spapr_tce_set_window(struct iommu_table_group *table_group, 1172 - int num, struct iommu_table *tbl) 1173 - { 1174 - return tbl == table_group->tables[num] ? 0 : -EPERM; 1175 - } 1176 - 1177 - static long spapr_tce_unset_window(struct iommu_table_group *table_group, int num) 1178 - { 1179 - return 0; 1180 - } 1181 - 1182 - static long spapr_tce_take_ownership(struct iommu_table_group *table_group) 1183 - { 1184 - int i, j, rc = 0; 1185 - 1186 - for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { 1187 - struct iommu_table *tbl = table_group->tables[i]; 1188 - 1189 - if (!tbl || !tbl->it_map) 1190 - continue; 1191 - 1192 - rc = iommu_take_ownership(tbl); 1193 - if (!rc) 1194 - continue; 1195 - 1196 - for (j = 0; j < i; ++j) 1197 - iommu_release_ownership(table_group->tables[j]); 1198 - return rc; 1199 - } 1200 - return 0; 1201 - } 1202 - 1203 - static void spapr_tce_release_ownership(struct iommu_table_group *table_group) 1204 - { 1205 - int i; 1206 - 1207 - for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { 1208 - struct iommu_table *tbl = table_group->tables[i]; 1209 - 1210 - if (!tbl) 1211 - continue; 1212 - 1213 - iommu_table_clear(tbl); 1214 - if (tbl->it_map) 1215 - iommu_release_ownership(tbl); 1216 - } 1217 - } 1218 - 1219 - struct iommu_table_group_ops spapr_tce_table_group_ops = { 1220 - .get_table_size = spapr_tce_get_table_size, 1221 - .create_table = spapr_tce_create_table, 1222 - .set_window = spapr_tce_set_window, 1223 - .unset_window = spapr_tce_unset_window, 1224 - .take_ownership = spapr_tce_take_ownership, 1225 - .release_ownership = spapr_tce_release_ownership, 1226 - }; 1227 - 1228 1189 /* 1229 1190 * A simple iommu_ops to allow less cruft in generic VFIO code. 1230 1191 */
+144
arch/powerpc/platforms/pseries/iommu.c
··· 54 54 DDW_EXT_QUERY_OUT_SIZE = 2 55 55 }; 56 56 57 + static int iommu_take_ownership(struct iommu_table *tbl) 58 + { 59 + unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; 60 + int ret = 0; 61 + 62 + /* 63 + * VFIO does not control TCE entries allocation and the guest 64 + * can write new TCEs on top of existing ones so iommu_tce_build() 65 + * must be able to release old pages. This functionality 66 + * requires exchange() callback defined so if it is not 67 + * implemented, we disallow taking ownership over the table. 68 + */ 69 + if (!tbl->it_ops->xchg_no_kill) 70 + return -EINVAL; 71 + 72 + spin_lock_irqsave(&tbl->large_pool.lock, flags); 73 + for (i = 0; i < tbl->nr_pools; i++) 74 + spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); 75 + 76 + if (iommu_table_in_use(tbl)) { 77 + pr_err("iommu_tce: it_map is not empty"); 78 + ret = -EBUSY; 79 + } else { 80 + memset(tbl->it_map, 0xff, sz); 81 + } 82 + 83 + for (i = 0; i < tbl->nr_pools; i++) 84 + spin_unlock(&tbl->pools[i].lock); 85 + spin_unlock_irqrestore(&tbl->large_pool.lock, flags); 86 + 87 + return ret; 88 + } 89 + 90 + static void iommu_release_ownership(struct iommu_table *tbl) 91 + { 92 + unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; 93 + 94 + spin_lock_irqsave(&tbl->large_pool.lock, flags); 95 + for (i = 0; i < tbl->nr_pools; i++) 96 + spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); 97 + 98 + memset(tbl->it_map, 0, sz); 99 + 100 + iommu_table_reserve_pages(tbl, tbl->it_reserved_start, 101 + tbl->it_reserved_end); 102 + 103 + for (i = 0; i < tbl->nr_pools; i++) 104 + spin_unlock(&tbl->pools[i].lock); 105 + spin_unlock_irqrestore(&tbl->large_pool.lock, flags); 106 + } 107 + 57 108 static struct iommu_table *iommu_pseries_alloc_table(int node) 58 109 { 59 110 struct iommu_table *tbl; ··· 117 66 kref_init(&tbl->it_kref); 118 67 return tbl; 119 68 } 69 + 70 + static struct iommu_table_group_ops spapr_tce_table_group_ops; 120 71 121 72 static struct iommu_table_group *iommu_pseries_alloc_group(int node) 122 73 { ··· 1738 1685 1739 1686 return false; 1740 1687 } 1688 + 1689 + /* 1690 + * A simple iommu_table_group_ops which only allows reusing the existing 1691 + * iommu_table. This handles VFIO for POWER7 or the nested KVM. 1692 + * The ops does not allow creating windows and only allows reusing the existing 1693 + * one if it matches table_group->tce32_start/tce32_size/page_shift. 1694 + */ 1695 + static unsigned long spapr_tce_get_table_size(__u32 page_shift, 1696 + __u64 window_size, __u32 levels) 1697 + { 1698 + unsigned long size; 1699 + 1700 + if (levels > 1) 1701 + return ~0U; 1702 + size = window_size >> (page_shift - 3); 1703 + return size; 1704 + } 1705 + 1706 + static long spapr_tce_create_table(struct iommu_table_group *table_group, int num, 1707 + __u32 page_shift, __u64 window_size, __u32 levels, 1708 + struct iommu_table **ptbl) 1709 + { 1710 + struct iommu_table *tbl = table_group->tables[0]; 1711 + 1712 + if (num > 0) 1713 + return -EPERM; 1714 + 1715 + if (tbl->it_page_shift != page_shift || 1716 + tbl->it_size != (window_size >> page_shift) || 1717 + tbl->it_indirect_levels != levels - 1) 1718 + return -EINVAL; 1719 + 1720 + *ptbl = iommu_tce_table_get(tbl); 1721 + return 0; 1722 + } 1723 + 1724 + static long spapr_tce_set_window(struct iommu_table_group *table_group, 1725 + int num, struct iommu_table *tbl) 1726 + { 1727 + return tbl == table_group->tables[num] ? 0 : -EPERM; 1728 + } 1729 + 1730 + static long spapr_tce_unset_window(struct iommu_table_group *table_group, int num) 1731 + { 1732 + return 0; 1733 + } 1734 + 1735 + static long spapr_tce_take_ownership(struct iommu_table_group *table_group) 1736 + { 1737 + int i, j, rc = 0; 1738 + 1739 + for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { 1740 + struct iommu_table *tbl = table_group->tables[i]; 1741 + 1742 + if (!tbl || !tbl->it_map) 1743 + continue; 1744 + 1745 + rc = iommu_take_ownership(tbl); 1746 + if (!rc) 1747 + continue; 1748 + 1749 + for (j = 0; j < i; ++j) 1750 + iommu_release_ownership(table_group->tables[j]); 1751 + return rc; 1752 + } 1753 + return 0; 1754 + } 1755 + 1756 + static void spapr_tce_release_ownership(struct iommu_table_group *table_group) 1757 + { 1758 + int i; 1759 + 1760 + for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { 1761 + struct iommu_table *tbl = table_group->tables[i]; 1762 + 1763 + if (!tbl) 1764 + continue; 1765 + 1766 + if (tbl->it_map) 1767 + iommu_release_ownership(tbl); 1768 + } 1769 + } 1770 + 1771 + static struct iommu_table_group_ops spapr_tce_table_group_ops = { 1772 + .get_table_size = spapr_tce_get_table_size, 1773 + .create_table = spapr_tce_create_table, 1774 + .set_window = spapr_tce_set_window, 1775 + .unset_window = spapr_tce_unset_window, 1776 + .take_ownership = spapr_tce_take_ownership, 1777 + .release_ownership = spapr_tce_release_ownership, 1778 + }; 1741 1779 1742 1780 static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, 1743 1781 void *data)