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:
parent
6d568ef9a6
commit
9db034d57a
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue