mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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
1 changed files with 5 additions and 6 deletions
|
@ -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…
Add table
Reference in a new issue