Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:GA
xen.22546
xsa378-0a.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa378-0a.patch of Package xen.22546
# Commit 50a498c8baed284455eca283d3852ccaa1d4ce2e # Date 2017-02-09 11:01:35 +0100 # Author Roger Pau Monné <roger.pau@citrix.com> # Committer Jan Beulich <jbeulich@suse.com> x86/iommu: add IOMMU entries for p2m_mmio_direct pages There's nothing wrong with allowing the domain to perform DMA transfers to MMIO areas that it already can access from the CPU, and this allows us to remove the hack in set_identity_p2m_entry for PVH Dom0. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Acked-by: George Dunlap <george.dunlap@citrix.com> --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -693,7 +693,7 @@ ept_set_entry(struct p2m_domain *p2m, un uint8_t ipat = 0; bool_t need_modify_vtd_table = 1; bool_t vtd_pte_present = 0; - unsigned int iommu_flags = p2m_get_iommu_flags(p2mt); + unsigned int iommu_flags = p2m_get_iommu_flags(p2mt, mfn); bool_t needs_sync = 1; ept_entry_t old_entry = { .epte = 0 }; ept_entry_t new_entry = { .epte = 0 }; @@ -819,7 +819,8 @@ ept_set_entry(struct p2m_domain *p2m, un /* Safe to read-then-write because we hold the p2m lock */ if ( ept_entry->mfn == new_entry.mfn && - p2m_get_iommu_flags(ept_entry->sa_p2mt) == iommu_flags ) + p2m_get_iommu_flags(ept_entry->sa_p2mt, _mfn(ept_entry->mfn)) == + iommu_flags ) need_modify_vtd_table = 0; ept_p2m_type_to_flags(p2m, &new_entry, p2mt, p2ma); --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -506,7 +506,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, l2_pgentry_t l2e_content; l3_pgentry_t l3e_content; int rc; - unsigned int iommu_pte_flags = p2m_get_iommu_flags(p2mt); + unsigned int iommu_pte_flags = p2m_get_iommu_flags(p2mt, mfn); /* * old_mfn and iommu_old_flags control possible flush/update needs on the * IOMMU: We need to flush when MFN or flags (i.e. permissions) change. @@ -572,9 +572,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, { if ( flags & _PAGE_PSE ) { - iommu_old_flags = - p2m_get_iommu_flags(p2m_flags_to_type(flags)); old_mfn = l1e_get_pfn(*p2m_entry); + iommu_old_flags = + p2m_get_iommu_flags(p2m_flags_to_type(flags), + _mfn(old_mfn)); } else { @@ -615,9 +616,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, 0, L1_PAGETABLE_ENTRIES); ASSERT(p2m_entry); - iommu_old_flags = - p2m_get_iommu_flags(p2m_flags_to_type(l1e_get_flags(*p2m_entry))); old_mfn = l1e_get_pfn(*p2m_entry); + iommu_old_flags = + p2m_get_iommu_flags(p2m_flags_to_type(l1e_get_flags(*p2m_entry)), + _mfn(old_mfn)); if ( mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt) ) entry_content = p2m_l1e_from_pfn(mfn_x(mfn), @@ -643,9 +645,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, { if ( flags & _PAGE_PSE ) { - iommu_old_flags = - p2m_get_iommu_flags(p2m_flags_to_type(flags)); old_mfn = l1e_get_pfn(*p2m_entry); + iommu_old_flags = + p2m_get_iommu_flags(p2m_flags_to_type(flags), + _mfn(old_mfn)); } else { --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1048,16 +1048,7 @@ int set_identity_p2m_entry(struct domain ret = p2m_set_entry(p2m, gfn, _mfn(gfn), PAGE_ORDER_4K, p2m_mmio_direct, p2ma); else if ( mfn_x(mfn) == gfn && p2mt == p2m_mmio_direct && a == p2ma ) - { ret = 0; - /* - * PVH fixme: during Dom0 PVH construction, p2m entries are being set - * but iomem regions are not mapped with IOMMU. This makes sure that - * RMRRs are correctly mapped with IOMMU. - */ - if ( is_hardware_domain(d) && !iommu_use_hap_pt(d) ) - ret = iommu_map_page(d, gfn, gfn, IOMMUF_readable|IOMMUF_writable); - } else { if ( flag & XEN_DOMCTL_DEV_RDM_RELAXED ) --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -814,7 +814,7 @@ void p2m_altp2m_propagate_change(struct /* * p2m type to IOMMU flags */ -static inline unsigned int p2m_get_iommu_flags(p2m_type_t p2mt) +static inline unsigned int p2m_get_iommu_flags(p2m_type_t p2mt, mfn_t mfn) { unsigned int flags; @@ -830,6 +830,11 @@ static inline unsigned int p2m_get_iommu case p2m_grant_map_ro: flags = IOMMUF_readable; break; + case p2m_mmio_direct: + flags = IOMMUF_readable; + if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn_x(mfn)) ) + flags |= IOMMUF_writable; + break; default: flags = 0; break;
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