| From 89dd2e1e7d9988be2793b491259faed2b5892237 Mon Sep 17 00:00:00 2001 |
| From: Andrei Dulea <adulea@amazon.de> |
| Date: Fri, 13 Sep 2019 16:42:29 +0200 |
| Subject: [PATCH] iommu/amd: Fix downgrading default page-sizes in alloc_pte() |
| |
| commit 6ccb72f8374e17d60b58a7bfd5570496332c54e2 upstream. |
| |
| Downgrading an existing large mapping to a mapping using smaller |
| page-sizes works only for the mappings created with page-mode 7 (i.e. |
| non-default page size). |
| |
| Treat large mappings created with page-mode 0 (i.e. default page size) |
| like a non-present mapping and allow to overwrite it in alloc_pte(). |
| |
| While around, make sure that we flush the TLB only if we change an |
| existing mapping, otherwise we might end up acting on garbage PTEs. |
| |
| Fixes: 6d568ef9a622 ("iommu/amd: Allow downgrading page-sizes in alloc_pte()") |
| Signed-off-by: Andrei Dulea <adulea@amazon.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c |
| index a0b64c43257a..909a97da6595 100644 |
| --- a/drivers/iommu/amd_iommu.c |
| +++ b/drivers/iommu/amd_iommu.c |
| @@ -1480,6 +1480,7 @@ static u64 *alloc_pte(struct protection_domain *domain, |
| pte_level = PM_PTE_LEVEL(__pte); |
| |
| if (!IOMMU_PTE_PRESENT(__pte) || |
| + pte_level == PAGE_MODE_NONE || |
| pte_level == PAGE_MODE_7_LEVEL) { |
| page = (u64 *)get_zeroed_page(gfp); |
| if (!page) |
| @@ -1490,7 +1491,7 @@ static u64 *alloc_pte(struct protection_domain *domain, |
| /* pte could have been changed somewhere. */ |
| if (cmpxchg64(pte, __pte, __npte) != __pte) |
| free_page((unsigned long)page); |
| - else if (pte_level == PAGE_MODE_7_LEVEL) |
| + else if (IOMMU_PTE_PRESENT(__pte)) |
| domain->updated = true; |
| |
| continue; |
| -- |
| 2.7.4 |
| |