diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c index 254c5dfd19..1eb22bd06e 100644 --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -206,7 +206,10 @@ p2m_next_level(struct p2m_domain *p2m, void **table, p2m_add_iommu_flags(&new_entry, level, IOMMUF_readable|IOMMUF_writable); rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, level + 1); if ( rc ) + { ASSERT_UNREACHABLE(); + goto free_ptp; + } } else if ( flags & _PAGE_PSE ) { @@ -257,39 +260,37 @@ p2m_next_level(struct p2m_domain *p2m, void **table, if ( rc ) { ASSERT_UNREACHABLE(); - break; + unmap_domain_page(l1_entry); + goto free_ptp; } } unmap_domain_page(l1_entry); - if ( !rc ) - { - new_entry = l1e_from_mfn(mfn, P2M_BASE_FLAGS | _PAGE_RW); - p2m_add_iommu_flags(&new_entry, level, - IOMMUF_readable|IOMMUF_writable); - rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, - level + 1); - if ( rc ) - ASSERT_UNREACHABLE(); + new_entry = l1e_from_mfn(mfn, P2M_BASE_FLAGS | _PAGE_RW); + p2m_add_iommu_flags(&new_entry, level, + IOMMUF_readable|IOMMUF_writable); + rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, + level + 1); + if ( rc ) { + ASSERT_UNREACHABLE(); + goto free_ptp; } } else ASSERT(flags & _PAGE_PRESENT); - if ( rc ) - { - ASSERT(mfn_valid(mfn)); - p2m_free_ptp(p2m, mfn_to_page(mfn)); - return rc; - } - next = map_domain_page(l1e_get_mfn(*p2m_entry)); if ( unmap ) unmap_domain_page(*table); *table = next; return 0; + + free_ptp: + ASSERT(mfn_valid(mfn)); + p2m_free_ptp(p2m, mfn_to_page(mfn)); + return rc; } /*