From: Joerg Roedel Date: Fri, 9 Nov 2018 11:07:09 +0000 (+0100) Subject: iommu/amd: Allow downgrading page-sizes in alloc_pte() X-Git-Tag: rel_imx_5.10.35_2.0.0-somdevices.0~5602^2^8~7 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=6d568ef9a622eaaea549b305b7af9c4d91566c84;p=linux.git iommu/amd: Allow downgrading page-sizes in alloc_pte() Before this patch it was not possible the downgrade a mapping established with page-mode 7 to a mapping using smaller page-sizes, because the pte_level != level check prevented that. Treat page-mode 7 like a non-present mapping and allow to overwrite it in alloc_pte(). Signed-off-by: Joerg Roedel --- diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 49b5d3115e56..6a88ba9321d1 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1460,10 +1460,13 @@ static u64 *alloc_pte(struct protection_domain *domain, while (level > end_lvl) { u64 __pte, __npte; + int pte_level; - __pte = *pte; + __pte = *pte; + pte_level = PM_PTE_LEVEL(__pte); - if (!IOMMU_PTE_PRESENT(__pte)) { + if (!IOMMU_PTE_PRESENT(__pte) || + pte_level == PAGE_MODE_7_LEVEL) { page = (u64 *)get_zeroed_page(gfp); if (!page) return NULL; @@ -1475,10 +1478,13 @@ static u64 *alloc_pte(struct protection_domain *domain, free_page((unsigned long)page); continue; } + + if (pte_level == PAGE_MODE_7_LEVEL) + domain->updated = true; } /* No level skipping support yet */ - if (PM_PTE_LEVEL(*pte) != level) + if (pte_level != level) return NULL; level -= 1;