[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.5] x86/p2m-pt: delay freeing of intermediate page tables
commit e4e18ecf958364c4fa3392355b7a67dff91704e8 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Thu Oct 8 11:36:52 2015 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Oct 8 11:36:52 2015 +0200 x86/p2m-pt: delay freeing of intermediate page tables Old intermediate page tables must be freed only after IOMMU side updates/flushes have got carried out. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx> master commit: 960265fbd878cdc9841473b755e4ccc9eb1942d2 master date: 2015-09-29 13:55:34 +0200 --- xen/arch/x86/mm/p2m-pt.c | 27 +++++++++++++-------------- 1 files changed, 13 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c index e48b63a..45a2752 100644 --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -486,8 +486,9 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, /* XXX -- this might be able to be faster iff current->domain == d */ void *table; unsigned long i, gfn_remainder = gfn; - l1_pgentry_t *p2m_entry; - l1_pgentry_t entry_content; + l1_pgentry_t *p2m_entry, entry_content; + /* Intermediate table to free if we're replacing it with a superpage. */ + l1_pgentry_t intermediate_entry = l1e_empty(); l2_pgentry_t l2e_content; l3_pgentry_t l3e_content; int rc; @@ -535,7 +536,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, */ if ( page_order == PAGE_ORDER_1G ) { - l1_pgentry_t old_entry = l1e_empty(); p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, L3_PAGETABLE_SHIFT - PAGE_SHIFT, L3_PAGETABLE_ENTRIES); @@ -545,7 +545,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, { /* We're replacing a non-SP page with a superpage. Make sure to * handle freeing the table properly. */ - old_entry = *p2m_entry; + intermediate_entry = *p2m_entry; } ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct); @@ -563,10 +563,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 3); /* NB: paging_write_p2m_entry() handles tlb flushes properly */ - - /* Free old intermediate tables if necessary */ - if ( l1e_get_flags(old_entry) & _PAGE_PRESENT ) - p2m_free_entry(p2m, &old_entry, page_order); } else { @@ -607,7 +603,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, } else if ( page_order == PAGE_ORDER_2M ) { - l1_pgentry_t old_entry = l1e_empty(); p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, L2_PAGETABLE_SHIFT - PAGE_SHIFT, L2_PAGETABLE_ENTRIES); @@ -619,7 +614,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, { /* We're replacing a non-SP page with a superpage. Make sure to * handle freeing the table properly. */ - old_entry = *p2m_entry; + intermediate_entry = *p2m_entry; } ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct); @@ -640,10 +635,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 2); /* NB: paging_write_p2m_entry() handles tlb flushes properly */ - - /* Free old intermediate tables if necessary */ - if ( l1e_get_flags(old_entry) & _PAGE_PRESENT ) - p2m_free_entry(p2m, &old_entry, page_order); } /* Track the highest gfn for which we have ever had a valid mapping */ @@ -671,6 +662,14 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, } } + /* + * Free old intermediate tables if necessary. This has to be the + * last thing we do, after removal from the IOMMU tables, so as to + * avoid a potential use-after-free. + */ + if ( l1e_get_flags(intermediate_entry) & _PAGE_PRESENT ) + p2m_free_entry(p2m, &intermediate_entry, page_order); + out: unmap_domain_page(table); return rc; -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.5 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |