iommu/amd: Restart loop if cmpxchg64 succeeded in alloc_pte()

This makes sure that __pte always contains the correct value
when the pointer to the next page-table level is derived.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
Joerg Roedel 2018-11-09 12:07:10 +01:00
parent 6d568ef9a6
commit 9db034d57a
1 changed files with 5 additions and 6 deletions

View File

@ -1474,13 +1474,12 @@ static u64 *alloc_pte(struct protection_domain *domain,
__npte = PM_LEVEL_PDE(level, iommu_virt_to_phys(page));
/* pte could have been changed somewhere. */
if (cmpxchg64(pte, __pte, __npte) != __pte) {
if (cmpxchg64(pte, __pte, __npte) != __pte)
free_page((unsigned long)page);
continue;
}
if (pte_level == PAGE_MODE_7_LEVEL)
else if (pte_level == PAGE_MODE_7_LEVEL)
domain->updated = true;
continue;
}
/* No level skipping support yet */
@ -1489,7 +1488,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
level -= 1;
pte = IOMMU_PTE_PAGE(*pte);
pte = IOMMU_PTE_PAGE(__pte);
if (pte_page && level == end_lvl)
*pte_page = pte;