@@ -1458,10 +1458,11 @@ static void free_pagetable(struct protection_domain *domain)
1458
1458
* another level increases the size of the address space by 9 bits to a size up
1459
1459
* to 64 bits.
1460
1460
*/
1461
- static void increase_address_space (struct protection_domain * domain ,
1461
+ static bool increase_address_space (struct protection_domain * domain ,
1462
1462
gfp_t gfp )
1463
1463
{
1464
1464
unsigned long flags ;
1465
+ bool ret = false;
1465
1466
u64 * pte ;
1466
1467
1467
1468
spin_lock_irqsave (& domain -> lock , flags );
@@ -1478,27 +1479,29 @@ static void increase_address_space(struct protection_domain *domain,
1478
1479
iommu_virt_to_phys (domain -> pt_root ));
1479
1480
domain -> pt_root = pte ;
1480
1481
domain -> mode += 1 ;
1481
- domain -> updated = true;
1482
+
1483
+ ret = true;
1482
1484
1483
1485
out :
1484
1486
spin_unlock_irqrestore (& domain -> lock , flags );
1485
1487
1486
- return ;
1488
+ return ret ;
1487
1489
}
1488
1490
1489
1491
static u64 * alloc_pte (struct protection_domain * domain ,
1490
1492
unsigned long address ,
1491
1493
unsigned long page_size ,
1492
1494
u64 * * pte_page ,
1493
- gfp_t gfp )
1495
+ gfp_t gfp ,
1496
+ bool * updated )
1494
1497
{
1495
1498
int level , end_lvl ;
1496
1499
u64 * pte , * page ;
1497
1500
1498
1501
BUG_ON (!is_power_of_2 (page_size ));
1499
1502
1500
1503
while (address > PM_LEVEL_SIZE (domain -> mode ))
1501
- increase_address_space (domain , gfp );
1504
+ * updated = increase_address_space (domain , gfp ) || * updated ;
1502
1505
1503
1506
level = domain -> mode - 1 ;
1504
1507
pte = & domain -> pt_root [PM_LEVEL_INDEX (level , address )];
@@ -1530,7 +1533,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
1530
1533
for (i = 0 ; i < count ; ++ i )
1531
1534
cmpxchg64 (& lpte [i ], __pte , 0ULL );
1532
1535
1533
- domain -> updated = true;
1536
+ * updated = true;
1534
1537
continue ;
1535
1538
}
1536
1539
@@ -1547,7 +1550,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
1547
1550
if (cmpxchg64 (pte , __pte , __npte ) != __pte )
1548
1551
free_page ((unsigned long )page );
1549
1552
else if (IOMMU_PTE_PRESENT (__pte ))
1550
- domain -> updated = true;
1553
+ * updated = true;
1551
1554
1552
1555
continue ;
1553
1556
}
@@ -1656,28 +1659,29 @@ static int iommu_map_page(struct protection_domain *dom,
1656
1659
gfp_t gfp )
1657
1660
{
1658
1661
struct page * freelist = NULL ;
1662
+ bool updated = false;
1659
1663
u64 __pte , * pte ;
1660
- int i , count ;
1664
+ int ret , i , count ;
1661
1665
1662
1666
BUG_ON (!IS_ALIGNED (bus_addr , page_size ));
1663
1667
BUG_ON (!IS_ALIGNED (phys_addr , page_size ));
1664
1668
1669
+ ret = - EINVAL ;
1665
1670
if (!(prot & IOMMU_PROT_MASK ))
1666
- return - EINVAL ;
1671
+ goto out ;
1667
1672
1668
1673
count = PAGE_SIZE_PTE_COUNT (page_size );
1669
- pte = alloc_pte (dom , bus_addr , page_size , NULL , gfp );
1674
+ pte = alloc_pte (dom , bus_addr , page_size , NULL , gfp , & updated );
1670
1675
1671
- if (!pte ) {
1672
- update_domain (dom );
1673
- return - ENOMEM ;
1674
- }
1676
+ ret = - ENOMEM ;
1677
+ if (!pte )
1678
+ goto out ;
1675
1679
1676
1680
for (i = 0 ; i < count ; ++ i )
1677
1681
freelist = free_clear_pte (& pte [i ], pte [i ], freelist );
1678
1682
1679
1683
if (freelist != NULL )
1680
- dom -> updated = true;
1684
+ updated = true;
1681
1685
1682
1686
if (count > 1 ) {
1683
1687
__pte = PAGE_SIZE_PTE (__sme_set (phys_addr ), page_size );
@@ -1693,12 +1697,16 @@ static int iommu_map_page(struct protection_domain *dom,
1693
1697
for (i = 0 ; i < count ; ++ i )
1694
1698
pte [i ] = __pte ;
1695
1699
1696
- update_domain (dom );
1700
+ ret = 0 ;
1701
+
1702
+ out :
1703
+ if (updated )
1704
+ update_domain (dom );
1697
1705
1698
1706
/* Everything flushed out, free pages now */
1699
1707
free_page_list (freelist );
1700
1708
1701
- return 0 ;
1709
+ return ret ;
1702
1710
}
1703
1711
1704
1712
static unsigned long iommu_unmap_page (struct protection_domain * dom ,
@@ -2399,15 +2407,10 @@ static void update_device_table(struct protection_domain *domain)
2399
2407
2400
2408
static void update_domain (struct protection_domain * domain )
2401
2409
{
2402
- if (!domain -> updated )
2403
- return ;
2404
-
2405
2410
update_device_table (domain );
2406
2411
2407
2412
domain_flush_devices (domain );
2408
2413
domain_flush_tlb_pde (domain );
2409
-
2410
- domain -> updated = false;
2411
2414
}
2412
2415
2413
2416
static int dir2prot (enum dma_data_direction direction )
@@ -3333,7 +3336,6 @@ void amd_iommu_domain_direct_map(struct iommu_domain *dom)
3333
3336
3334
3337
/* Update data structure */
3335
3338
domain -> mode = PAGE_MODE_NONE ;
3336
- domain -> updated = true;
3337
3339
3338
3340
/* Make changes visible to IOMMUs */
3339
3341
update_domain (domain );
@@ -3379,7 +3381,6 @@ int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
3379
3381
3380
3382
domain -> glx = levels ;
3381
3383
domain -> flags |= PD_IOMMUV2_MASK ;
3382
- domain -> updated = true;
3383
3384
3384
3385
update_domain (domain );
3385
3386
0 commit comments