@@ -365,7 +365,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
365365 /* Put the TCEs in the HW table */
366366 build_fail = tbl -> it_ops -> set (tbl , entry , npages ,
367367 (unsigned long )page &
368- IOMMU_PAGE_MASK (tbl ), direction , attrs );
368+ IOMMU_PAGE_MASK (tbl ), direction , attrs , false );
369369
370370 /* tbl->it_ops->set() only returns non-zero for transient errors.
371371 * Clean up the table bitmap in this case and return
@@ -539,7 +539,7 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl,
539539 /* Insert into HW table */
540540 build_fail = tbl -> it_ops -> set (tbl , entry , npages ,
541541 vaddr & IOMMU_PAGE_MASK (tbl ),
542- direction , attrs );
542+ direction , attrs , false );
543543 if (unlikely (build_fail ))
544544 goto failure ;
545545
@@ -1201,7 +1201,15 @@ spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain,
12011201 * also sets the dma_api ops
12021202 */
12031203 table_group = iommu_group_get_iommudata (grp );
1204+
1205+ if (old && old -> type == IOMMU_DOMAIN_DMA ) {
1206+ ret = table_group -> ops -> unset_window (table_group , 0 );
1207+ if (ret )
1208+ goto exit ;
1209+ }
1210+
12041211 ret = table_group -> ops -> take_ownership (table_group , dev );
1212+ exit :
12051213 iommu_group_put (grp );
12061214
12071215 return ret ;
@@ -1260,13 +1268,182 @@ static struct iommu_group *spapr_tce_iommu_device_group(struct device *dev)
12601268 return hose -> controller_ops .device_group (hose , pdev );
12611269}
12621270
1271+ struct ppc64_domain {
1272+ struct iommu_domain domain ;
1273+ struct device * device ; /* Make it a list */
1274+ struct iommu_table * table ;
1275+ spinlock_t list_lock ;
1276+ struct rcu_head rcu ;
1277+ };
1278+
1279+ static struct ppc64_domain * to_ppc64_domain (struct iommu_domain * dom )
1280+ {
1281+ return container_of (dom , struct ppc64_domain , domain );
1282+ }
1283+
1284+ static void spapr_tce_domain_free (struct iommu_domain * domain )
1285+ {
1286+ struct ppc64_domain * ppc64_domain = to_ppc64_domain (domain );
1287+
1288+ kfree (ppc64_domain );
1289+ }
1290+
1291+ static const struct iommu_ops spapr_tce_iommu_ops ;
1292+ static struct iommu_domain * spapr_tce_domain_alloc_paging (struct device * dev )
1293+ {
1294+ struct iommu_group * grp = iommu_group_get (dev );
1295+ struct iommu_table_group * table_group ;
1296+ struct ppc64_domain * ppc64_domain ;
1297+ struct iommu_table * ptbl ;
1298+ int ret = -1 ;
1299+
1300+ table_group = iommu_group_get_iommudata (grp );
1301+ ppc64_domain = kzalloc (sizeof (* ppc64_domain ), GFP_KERNEL );
1302+ if (!ppc64_domain )
1303+ return NULL ;
1304+
1305+ /* Just the default window hardcode for now */
1306+ ret = table_group -> ops -> create_table (table_group , 0 , 0xc , 0x40000000 , 1 , & ptbl );
1307+ iommu_tce_table_get (ptbl );
1308+ ppc64_domain -> table = ptbl ; /* REVISIT: Single device for now */
1309+ if (!ppc64_domain -> table ) {
1310+ kfree (ppc64_domain );
1311+ iommu_tce_table_put (ptbl );
1312+ iommu_group_put (grp );
1313+ return NULL ;
1314+ }
1315+
1316+ table_group -> ops -> set_window (table_group , 0 , ptbl );
1317+ iommu_group_put (grp );
1318+
1319+ ppc64_domain -> domain .pgsize_bitmap = SZ_4K ;
1320+ ppc64_domain -> domain .geometry .force_aperture = true;
1321+ ppc64_domain -> domain .geometry .aperture_start = 0 ;
1322+ ppc64_domain -> domain .geometry .aperture_end = 0x40000000 ; /*default window */
1323+ ppc64_domain -> domain .ops = spapr_tce_iommu_ops .default_domain_ops ;
1324+
1325+ spin_lock_init (& ppc64_domain -> list_lock );
1326+
1327+ return & ppc64_domain -> domain ;
1328+ }
1329+
1330+ static size_t spapr_tce_iommu_unmap_pages (struct iommu_domain * domain ,
1331+ unsigned long iova ,
1332+ size_t pgsize , size_t pgcount ,
1333+ struct iommu_iotlb_gather * gather )
1334+ {
1335+ struct ppc64_domain * ppc64_domain = to_ppc64_domain (domain );
1336+ struct iommu_table * tbl = ppc64_domain -> table ;
1337+ unsigned long pgshift = __ffs (pgsize );
1338+ size_t size = pgcount << pgshift ;
1339+ size_t mapped = 0 ;
1340+ unsigned int tcenum ;
1341+ int mask ;
1342+
1343+ if (pgsize != SZ_4K )
1344+ return - EINVAL ;
1345+
1346+ size = PAGE_ALIGN (size );
1347+
1348+ mask = IOMMU_PAGE_MASK (tbl );
1349+ tcenum = iova >> tbl -> it_page_shift ;
1350+
1351+ tbl -> it_ops -> clear (tbl , tcenum , pgcount );
1352+
1353+ mapped = pgsize * pgcount ;
1354+
1355+ return mapped ;
1356+ }
1357+
1358+ static phys_addr_t spapr_tce_iommu_iova_to_phys (struct iommu_domain * domain , dma_addr_t iova )
1359+ {
1360+ struct ppc64_domain * ppc64_domain = to_ppc64_domain (domain );
1361+ struct iommu_table * tbl = ppc64_domain -> table ;
1362+ phys_addr_t paddr , rpn , tceval ;
1363+ unsigned int tcenum ;
1364+
1365+ tcenum = iova >> tbl -> it_page_shift ;
1366+ tceval = tbl -> it_ops -> get (tbl , tcenum );
1367+
1368+ /* Ignore the direction bits */
1369+ rpn = tceval >> tbl -> it_page_shift ;
1370+ paddr = rpn << tbl -> it_page_shift ;
1371+
1372+ return paddr ;
1373+ }
1374+
1375+ static int spapr_tce_iommu_map_pages (struct iommu_domain * domain ,
1376+ unsigned long iova , phys_addr_t paddr ,
1377+ size_t pgsize , size_t pgcount ,
1378+ int prot , gfp_t gfp , size_t * mapped )
1379+ {
1380+ struct ppc64_domain * ppc64_domain = to_ppc64_domain (domain );
1381+ enum dma_data_direction direction = DMA_BIDIRECTIONAL ;
1382+ struct iommu_table * tbl = ppc64_domain -> table ;
1383+ unsigned long pgshift = __ffs (pgsize );
1384+ size_t size = pgcount << pgshift ;
1385+ unsigned int tcenum ;
1386+ int ret ;
1387+
1388+ if (pgsize != SZ_4K )
1389+ return - EINVAL ;
1390+
1391+ if (iova < ppc64_domain -> domain .geometry .aperture_start ||
1392+ (iova + size - 1 ) > ppc64_domain -> domain .geometry .aperture_end )
1393+ return - EINVAL ;
1394+
1395+ if (!IS_ALIGNED (iova | paddr , pgsize ))
1396+ return - EINVAL ;
1397+
1398+ if (!(prot & IOMMU_WRITE ))
1399+ direction = DMA_FROM_DEVICE ;
1400+
1401+ if (!(prot & IOMMU_READ ))
1402+ direction = DMA_TO_DEVICE ;
1403+
1404+ size = PAGE_ALIGN (size );
1405+ tcenum = iova >> tbl -> it_page_shift ;
1406+
1407+ /* Put the TCEs in the HW table */
1408+ ret = tbl -> it_ops -> set (tbl , tcenum , pgcount ,
1409+ paddr , direction , 0 , true);
1410+ if (!ret && mapped )
1411+ * mapped = pgsize ;
1412+
1413+ return 0 ;
1414+ }
1415+
1416+ static int spapr_tce_iommu_attach_device (struct iommu_domain * domain ,
1417+ struct device * dev , struct iommu_domain * old )
1418+ {
1419+ struct ppc64_domain * ppc64_domain = to_ppc64_domain (domain );
1420+
1421+ /* REVISIT */
1422+ if (!domain )
1423+ return 0 ;
1424+
1425+ /* REVISIT: Check table group, list handling */
1426+ ppc64_domain -> device = dev ;
1427+
1428+ return 0 ;
1429+ }
1430+
1431+
12631432static const struct iommu_ops spapr_tce_iommu_ops = {
12641433 .default_domain = & spapr_tce_platform_domain ,
12651434 .blocked_domain = & spapr_tce_blocked_domain ,
12661435 .capable = spapr_tce_iommu_capable ,
12671436 .probe_device = spapr_tce_iommu_probe_device ,
12681437 .release_device = spapr_tce_iommu_release_device ,
12691438 .device_group = spapr_tce_iommu_device_group ,
1439+ .domain_alloc_paging = spapr_tce_domain_alloc_paging ,
1440+ .default_domain_ops = & (const struct iommu_domain_ops ) {
1441+ .attach_dev = spapr_tce_iommu_attach_device ,
1442+ .map_pages = spapr_tce_iommu_map_pages ,
1443+ .unmap_pages = spapr_tce_iommu_unmap_pages ,
1444+ .iova_to_phys = spapr_tce_iommu_iova_to_phys ,
1445+ .free = spapr_tce_domain_free ,
1446+ }
12701447};
12711448
12721449static struct attribute * spapr_tce_iommu_attrs [] = {
0 commit comments