diff options
author | Joerg Roedel <jroedel@suse.de> | 2018-11-09 12:07:09 +0100 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2018-11-15 16:40:54 +0100 |
commit | 6d568ef9a622eaaea549b305b7af9c4d91566c84 (patch) | |
tree | a2ccaf91e9c8dc469280694a5b6cf1e1e993b7d1 /drivers/iommu | |
parent | iommu/amd: Ignore page-mode 7 in free_sub_pt() (diff) | |
download | linux-6d568ef9a622eaaea549b305b7af9c4d91566c84.tar.xz linux-6d568ef9a622eaaea549b305b7af9c4d91566c84.zip |
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 <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 12 |
1 files changed, 9 insertions, 3 deletions
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; |