Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
xen.1589
560e6d34-x86-p2m-pt-tighten-conditions-of-IOMMU...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 560e6d34-x86-p2m-pt-tighten-conditions-of-IOMMU-mapping-updates.patch of Package xen.1589
# Commit 660fd65d5578a95ec5eac522128bba23325179eb # Date 2015-10-02 13:40:36 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/p2m-pt: correct condition of IOMMU mapping updates Whether the MFN changes does not depend on the new entry being valid (but solely on the old one). Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.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 @@ -293,7 +293,8 @@ p2m_set_entry(struct p2m_domain *p2m, un unsigned int iommu_pte_flags = (p2mt == p2m_ram_rw) ? IOMMUF_readable|IOMMUF_writable: 0; - unsigned long old_mfn = 0; + unsigned int flags; + unsigned long old_mfn = INVALID_MFN; if ( tb_init_done ) { @@ -326,12 +327,13 @@ p2m_set_entry(struct p2m_domain *p2m, un L3_PAGETABLE_SHIFT - PAGE_SHIFT, L3_PAGETABLE_ENTRIES); ASSERT(p2m_entry); - if ( (l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) && - !(l1e_get_flags(*p2m_entry) & _PAGE_PSE) ) + flags = l1e_get_flags(*p2m_entry); + if ( flags & _PAGE_PRESENT ) { - /* We're replacing a non-SP page with a superpage. Make sure to - * handle freeing the table properly. */ - intermediate_entry = *p2m_entry; + if ( flags & _PAGE_PSE ) + old_mfn = l1e_get_pfn(*p2m_entry); + else + intermediate_entry = *p2m_entry; } ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct); @@ -342,10 +344,7 @@ p2m_set_entry(struct p2m_domain *p2m, un entry_content.l1 = l3e_content.l3; if ( entry_content.l1 != 0 ) - { p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags); - old_mfn = l1e_get_pfn(*p2m_entry); - } p2m->write_p2m_entry(p2m, gfn, p2m_entry, table_mfn, entry_content, 3); /* NB: paging_write_p2m_entry() handles tlb flushes properly */ @@ -366,7 +365,8 @@ p2m_set_entry(struct p2m_domain *p2m, un p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, 0, L1_PAGETABLE_ENTRIES); ASSERT(p2m_entry); - + old_mfn = l1e_get_pfn(*p2m_entry); + if ( mfn_valid(mfn) || (p2mt == p2m_mmio_direct) || p2m_is_paging(p2mt) ) entry_content = p2m_l1e_from_pfn(mfn_x(mfn), @@ -375,10 +375,8 @@ p2m_set_entry(struct p2m_domain *p2m, un entry_content = l1e_empty(); if ( entry_content.l1 != 0 ) - { p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags); - old_mfn = l1e_get_pfn(*p2m_entry); - } + /* level 1 entry */ p2m->write_p2m_entry(p2m, gfn, p2m_entry, table_mfn, entry_content, 1); /* NB: paging_write_p2m_entry() handles tlb flushes properly */ @@ -389,14 +387,13 @@ p2m_set_entry(struct p2m_domain *p2m, un L2_PAGETABLE_SHIFT - PAGE_SHIFT, L2_PAGETABLE_ENTRIES); ASSERT(p2m_entry); - - /* FIXME: Deal with 4k replaced by 2meg pages */ - if ( (l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) && - !(l1e_get_flags(*p2m_entry) & _PAGE_PSE) ) - { - /* We're replacing a non-SP page with a superpage. Make sure to - * handle freeing the table properly. */ - intermediate_entry = *p2m_entry; + flags = l1e_get_flags(*p2m_entry); + if ( flags & _PAGE_PRESENT ) + { + if ( flags & _PAGE_PSE ) + old_mfn = l1e_get_pfn(*p2m_entry); + else + intermediate_entry = *p2m_entry; } ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct); @@ -410,10 +407,7 @@ p2m_set_entry(struct p2m_domain *p2m, un entry_content.l1 = l2e_content.l2; if ( entry_content.l1 != 0 ) - { p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags); - old_mfn = l1e_get_pfn(*p2m_entry); - } p2m->write_p2m_entry(p2m, gfn, p2m_entry, table_mfn, entry_content, 2); /* NB: paging_write_p2m_entry() handles tlb flushes properly */ @@ -424,11 +418,11 @@ p2m_set_entry(struct p2m_domain *p2m, un && (gfn + (1UL << page_order) - 1 > p2m->max_mapped_pfn) ) p2m->max_mapped_pfn = gfn + (1UL << page_order) - 1; - if ( iommu_enabled && need_iommu(p2m->domain) ) + if ( iommu_enabled && need_iommu(p2m->domain) && old_mfn != mfn_x(mfn) ) { if ( iommu_use_hap_pt(p2m->domain) ) { - if ( old_mfn && (old_mfn != mfn_x(mfn)) ) + if ( old_mfn != INVALID_MFN ) amd_iommu_flush_pages(p2m->domain, gfn, page_order); } else
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