Commit 119b2b2c authored by Joerg Roedel's avatar Joerg Roedel

iommu/amd: Do not flush Device Table in iommu_map_page()

The flush of the Device Table Entries for the domain has already
happened in increase_address_space(), if necessary. Do no flush them
again in iommu_map_page().
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
Tested-by: default avatarQian Cai <cai@lca.pw>
Link: https://lore.kernel.org/r/20200504125413.16798-6-joro@8bytes.orgSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 19c6978f
...@@ -1446,15 +1446,18 @@ static bool increase_address_space(struct protection_domain *domain, ...@@ -1446,15 +1446,18 @@ static bool increase_address_space(struct protection_domain *domain,
{ {
struct domain_pgtable pgtable; struct domain_pgtable pgtable;
unsigned long flags; unsigned long flags;
bool ret = false; bool ret = true;
u64 *pte, root; u64 *pte, root;
spin_lock_irqsave(&domain->lock, flags); spin_lock_irqsave(&domain->lock, flags);
amd_iommu_domain_get_pgtable(domain, &pgtable); amd_iommu_domain_get_pgtable(domain, &pgtable);
if (address <= PM_LEVEL_SIZE(pgtable.mode) || if (address <= PM_LEVEL_SIZE(pgtable.mode))
WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) goto out;
ret = false;
if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL))
goto out; goto out;
pte = (void *)get_zeroed_page(gfp); pte = (void *)get_zeroed_page(gfp);
...@@ -1499,19 +1502,15 @@ static u64 *alloc_pte(struct protection_domain *domain, ...@@ -1499,19 +1502,15 @@ static u64 *alloc_pte(struct protection_domain *domain,
amd_iommu_domain_get_pgtable(domain, &pgtable); amd_iommu_domain_get_pgtable(domain, &pgtable);
while (address > PM_LEVEL_SIZE(pgtable.mode)) { while (address > PM_LEVEL_SIZE(pgtable.mode)) {
bool upd = increase_address_space(domain, address, gfp);
/* Read new values to check if update was successful */
amd_iommu_domain_get_pgtable(domain, &pgtable);
/* /*
* Return an error if there is no memory to update the * Return an error if there is no memory to update the
* page-table. * page-table.
*/ */
if (!upd && (address > PM_LEVEL_SIZE(pgtable.mode))) if (!increase_address_space(domain, address, gfp))
return NULL; return NULL;
*updated = *updated || upd; /* Read new values to check if update was successful */
amd_iommu_domain_get_pgtable(domain, &pgtable);
} }
...@@ -1719,7 +1718,13 @@ static int iommu_map_page(struct protection_domain *dom, ...@@ -1719,7 +1718,13 @@ static int iommu_map_page(struct protection_domain *dom,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&dom->lock, flags); spin_lock_irqsave(&dom->lock, flags);
update_domain(dom); /*
* Flush domain TLB(s) and wait for completion. Any Device-Table
* Updates and flushing already happened in
* increase_address_space().
*/
domain_flush_tlb_pde(dom);
domain_flush_complete(dom);
spin_unlock_irqrestore(&dom->lock, flags); spin_unlock_irqrestore(&dom->lock, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment