Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
SUSE:SLE-12:Update
xen.1589
560a7c36-x86-p2m-pt-delay-freeing-of-intermedia...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 560a7c36-x86-p2m-pt-delay-freeing-of-intermediate-page-tables.patch of Package xen.1589
# Commit 960265fbd878cdc9841473b755e4ccc9eb1942d2 # Date 2015-09-29 13:55:34 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> 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@suse.com> Reviewed-by: George Dunlap <george.dunlap@citrix.com> --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -284,8 +284,9 @@ p2m_set_entry(struct p2m_domain *p2m, un mfn_t table_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m)); void *table =map_domain_page(mfn_x(table_mfn)); 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 rv=0; @@ -321,7 +322,6 @@ p2m_set_entry(struct p2m_domain *p2m, un */ 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); @@ -331,7 +331,7 @@ p2m_set_entry(struct p2m_domain *p2m, un { /* 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); @@ -349,10 +349,6 @@ p2m_set_entry(struct p2m_domain *p2m, un p2m->write_p2m_entry(p2m, gfn, p2m_entry, table_mfn, 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 if ( !p2m_next_level(p2m, &table_mfn, &table, &gfn_remainder, gfn, L3_PAGETABLE_SHIFT - PAGE_SHIFT, @@ -389,7 +385,6 @@ p2m_set_entry(struct p2m_domain *p2m, un } 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); @@ -401,7 +396,7 @@ p2m_set_entry(struct p2m_domain *p2m, un { /* 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); @@ -422,10 +417,6 @@ p2m_set_entry(struct p2m_domain *p2m, un p2m->write_p2m_entry(p2m, gfn, p2m_entry, table_mfn, 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 */ @@ -452,6 +443,14 @@ p2m_set_entry(struct p2m_domain *p2m, un } } + /* + * 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); + /* Success */ rv = 1;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor