From: Joerg Roedel jroedel@suse.de
[ Upstream commit 5b8a9a047b6cad361405c7900c1e1cdd378c4589 ]
When increase_address_space() fails to allocate memory, alloc_pte() will call it again until it succeeds. Do not loop forever while trying to increase the address space and just return an error instead.
Signed-off-by: Joerg Roedel jroedel@suse.de Tested-by: Qian Cai cai@lca.pw Link: https://lore.kernel.org/r/20200504125413.16798-3-joro@8bytes.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd_iommu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 1d8634250afc..18c995a16d80 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1500,8 +1500,19 @@ static u64 *alloc_pte(struct protection_domain *domain, amd_iommu_domain_get_pgtable(domain, &pgtable);
while (address > PM_LEVEL_SIZE(pgtable.mode)) { - *updated = increase_address_space(domain, address, gfp) || *updated; + bool upd = increase_address_space(domain, address, gfp); + + /* Read new values to check if update was successful */ amd_iommu_domain_get_pgtable(domain, &pgtable); + + /* + * Return an error if there is no memory to update the + * page-table. + */ + if (!upd && (address > PM_LEVEL_SIZE(pgtable.mode))) + return NULL; + + *updated = *updated || upd; }