[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 2/2] gnttab: consolidate pin-to-status syncing
Forever since the fix for XSA-230 the 2nd of the comments ahead of fixup_status_for_copy_pin() has been stale - there's nothing specific to transitive grants there anymore. Move the function up, drop the "copy" part from its name again, add a "readonly" parameter, and use it also on other paths having decremented one (or not having got to increment any) of the pin counts. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- v2: Rename helper to reduce_status_for_pin() and adjust its comment accordingly. --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -920,6 +920,25 @@ static int _set_status(const grant_entry return _set_status_v2(shah, status, rd, act, readonly, mapflag, ldomid); } +/* + * The status for a grant may indicate that we're taking more access than + * the pin requires. Reduce the status to match the pin. Called with the + * domain's grant table lock held at least in read mode and with the active + * entry lock held (iow act->pin can't change behind our backs). + */ +static void reduce_status_for_pin(struct domain *rd, + const struct active_grant_entry *act, + uint16_t *status, bool readonly) +{ + unsigned int clear_flags = act->pin ? 0 : GTF_reading; + + if ( !readonly && !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) + clear_flags |= GTF_writing; + + if ( clear_flags ) + gnttab_clear_flags(rd, clear_flags, status); +} + static struct active_grant_entry *grant_map_exists(const struct domain *ld, struct grant_table *rgt, mfn_t mfn, @@ -1003,8 +1022,7 @@ map_grant_ref( mfn_t mfn; struct page_info *pg = NULL; int rc = GNTST_okay; - unsigned int cache_flags, clear_flags = 0, refcnt = 0, typecnt = 0, - pin_incr = 0; + unsigned int cache_flags, refcnt = 0, typecnt = 0, pin_incr = 0; bool host_map_created = false; struct active_grant_entry *act = NULL; struct grant_mapping *mt; @@ -1296,15 +1314,7 @@ map_grant_ref( act->pin -= pin_incr; unlock_out_clear: - if ( !(op->flags & GNTMAP_readonly) && - !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) ) - clear_flags |= GTF_writing; - - if ( !act->pin ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); + reduce_status_for_pin(rd, act, status, op->flags & GNTMAP_readonly); act_release_out: active_entry_release(act); @@ -1519,7 +1529,6 @@ unmap_common_complete(struct gnttab_unma grant_entry_header_t *sha; struct page_info *pg; uint16_t *status; - unsigned int clear_flags = 0; if ( evaluate_nospec(!op->done) ) { @@ -1578,15 +1587,7 @@ unmap_common_complete(struct gnttab_unma act->pin -= GNTPIN_hstw_inc; } - if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) && - !(op->done & GNTMAP_readonly) ) - clear_flags |= GTF_writing; - - if ( act->pin == 0 ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); + reduce_status_for_pin(rd, act, status, op->done & GNTMAP_readonly); active_entry_release(act); grant_read_unlock(rgt); @@ -2426,7 +2427,6 @@ release_grant_for_copy( uint16_t *status; grant_ref_t trans_gref; struct domain *td; - unsigned int clear_flags = 0; grant_read_lock(rgt); @@ -2456,15 +2456,9 @@ release_grant_for_copy( gnttab_mark_dirty(rd, mfn); act->pin -= GNTPIN_hstw_inc; - if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) ) - clear_flags |= GTF_writing; } - if ( !act->pin ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); + reduce_status_for_pin(rd, act, status, readonly); active_entry_release(act); grant_read_unlock(rgt); @@ -2481,27 +2475,6 @@ release_grant_for_copy( } } -/* The status for a grant indicates that we're taking more access than - the pin requires. Fix up the status to match the pin. Called - under the domain's grant table lock. */ -/* Only safe on transitive grants. Even then, note that we don't - attempt to drop any pin on the referent grant. */ -static void fixup_status_for_copy_pin(struct domain *rd, - const struct active_grant_entry *act, - uint16_t *status) -{ - unsigned int clear_flags = 0; - - if ( !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) - clear_flags |= GTF_writing; - - if ( !act->pin ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); -} - /* * Grab a machine frame number from a grant entry and update the flags * and pin count as appropriate. If rc == GNTST_okay, note that this *does* @@ -2529,7 +2502,6 @@ acquire_grant_for_copy( bool is_sub_page; s16 rc = GNTST_okay; unsigned int pin_incr = readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; - unsigned int clear_flags = 0; *page = NULL; @@ -2616,8 +2588,8 @@ acquire_grant_for_copy( if ( rc != GNTST_okay ) { - fixup_status_for_copy_pin(rd, act, status); rcu_unlock_domain(td); + reduce_status_for_pin(rd, act, status, readonly); active_entry_release(act); grant_read_unlock(rgt); return rc; @@ -2639,8 +2611,8 @@ acquire_grant_for_copy( !act->is_sub_page)) ) { release_grant_for_copy(td, trans_gref, readonly); - fixup_status_for_copy_pin(rd, act, status); rcu_unlock_domain(td); + reduce_status_for_pin(rd, act, status, readonly); active_entry_release(act); grant_read_unlock(rgt); put_page(*page); @@ -2754,15 +2726,7 @@ acquire_grant_for_copy( return rc; unlock_out_clear: - if ( !(readonly) && - !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) - clear_flags |= GTF_writing; - - if ( !act->pin ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); + reduce_status_for_pin(rd, act, status, readonly); unlock_out: active_entry_release(act); @@ -3732,8 +3696,6 @@ gnttab_release_mappings( for ( handle = 0; handle < gt->maptrack_limit; handle++ ) { - unsigned int clear_flags = 0; - map = &maptrack_entry(gt, handle); if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ) continue; @@ -3806,16 +3768,9 @@ gnttab_release_mappings( put_page(pg); } } - - if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 ) - clear_flags |= GTF_writing; } - if ( act->pin == 0 ) - clear_flags |= GTF_reading; - - if ( clear_flags ) - gnttab_clear_flags(rd, clear_flags, status); + reduce_status_for_pin(rd, act, status, map->flags & GNTMAP_readonly); active_entry_release(act); grant_read_unlock(rgt);
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |