Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
xen.25148
xsa380-0.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa380-0.patch of Package xen.25148
# Commit 921f1f42260c7967bf18f8a143d39511d163c421 # Date 2019-12-03 14:13:40 +0100 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> gnttab: make sure grant map operations don't skip their IOMMU part Two almost simultaneous mapping requests need to make sure that at the completion of the earlier one IOMMU mappings (established explicitly here in the PV case) have been put in place. Forever since the splitting of the grant table lock a violation of this has been possible (using simplified pin counts, as it doesn't matter whether we talk about read or write mappings here): initial state: act->pin = 0 vCPU A: progress the operation past the dropping of the locks after the act->pin updates (act->pin = 1, old_pin = 0, act_pin = 1) vCPU B: progress the operation past the dropping of the locks after the act->pin updates (act->pin = 2, old_pin = 1, act_pin = 2) vCPU B: (re-)acquire both gt locks, mapkind() returns 0, but both iommu_legacy_map() invocations get skipped due to non-zero old_pin vCPU B: return to caller without IOMMU mapping vCPU A: (re-)acquire both gt locks, mapkind() returns 0, iommu_legacy_map() gets invoked With the locks dropped intermediately, whether to invoke iommu_legacy_map() must depend on only the return value of mapkind() and of course the kind of mapping request being processed, just like is already the case in unmap_common(). Also fix the style of the adjacent comment, and correct a nearby one still referring to a prior name of what is now mapkind(). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -918,8 +918,6 @@ map_grant_ref( unsigned long frame = 0; struct page_info *pg = NULL; int rc = GNTST_okay; - u32 old_pin; - u32 act_pin; unsigned int cache_flags, refcnt = 0, typecnt = 0; bool host_map_created = false; struct active_grant_entry *act = NULL; @@ -1023,7 +1021,6 @@ map_grant_ref( } } - old_pin = act->pin; if ( op->flags & GNTMAP_device_map ) act->pin += (op->flags & GNTMAP_readonly) ? GNTPIN_devr_inc : GNTPIN_devw_inc; @@ -1032,7 +1029,6 @@ map_grant_ref( GNTPIN_hstr_inc : GNTPIN_hstw_inc; frame = act->frame; - act_pin = act->pin; cache_flags = (shah->flags & (GTF_PAT | GTF_PWT | GTF_PCD) ); @@ -1140,26 +1136,22 @@ map_grant_ref( if ( need_iommu ) { unsigned int kind; - int err = 0; double_gt_lock(lgt, rgt); - /* We're not translated, so we know that gmfns and mfns are - the same things, so the IOMMU entry is always 1-to-1. */ + /* + * We're not translated, so we know that dfns and mfns are + * the same things, so the IOMMU entry is always 1-to-1. + */ kind = mapkind(lgt, rd, frame); - if ( (act_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) && - !(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) ) - { - if ( !(kind & MAPKIND_WRITE) ) - err = iommu_map_page(ld, frame, frame, - IOMMUF_readable|IOMMUF_writable); - } - else if ( act_pin && !old_pin ) - { - if ( !kind ) - err = iommu_map_page(ld, frame, frame, IOMMUF_readable); - } - if ( err ) + if ( !(op->flags & GNTMAP_readonly) && + !(kind & MAPKIND_WRITE) ) + kind = IOMMUF_readable | IOMMUF_writable; + else if ( !kind ) + kind = IOMMUF_readable; + else + kind = 0; + if ( kind && iommu_map_page(ld, frame, frame, kind) ) { double_gt_unlock(lgt, rgt); rc = GNTST_general_error; @@ -1174,7 +1166,7 @@ map_grant_ref( * other fields so just ensure the flags field is stored last. * * However, if gnttab_need_iommu_mapping() then this would race - * with a concurrent mapcount() call (on an unmap, for example) + * with a concurrent mapkind() call (on an unmap, for example) * and a lock is required. */ mt = &maptrack_entry(lgt, handle);
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