diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-09-07 17:58:12 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-09-07 17:58:12 +0200 |
commit | 79e6ef8c0cf1dd0820c950bb653985a8beb04203 (patch) | |
tree | 39960fa3732cea2ee65b769523951b9b240a7729 /xen/common/grant_table.c | |
parent | 42599de39a98fd826b6b6bac0738a8a0d9df18fe (diff) | |
download | xen-79e6ef8c0cf1dd0820c950bb653985a8beb04203.tar.gz xen-79e6ef8c0cf1dd0820c950bb653985a8beb04203.tar.bz2 xen-79e6ef8c0cf1dd0820c950bb653985a8beb04203.zip |
adjust a few RCU domain locking calls
x86's do_physdev_op() had a case where the locking was entirely
superfluous. Its physdev_map_pirq() further had a case where the lock
was being obtained too early, needlessly complicating early exit paths.
Grant table code had two open coded instances of
rcu_lock_target_domain_by_id(), and a third code section could be
consolidated by using the newly introduced helper function.
The memory hypercall code had two more instances of open coding
rcu_lock_target_domain_by_id(), but note that here this is not just
cleanup, but also fixes an error return path in memory_exchange() to
actually return an error.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common/grant_table.c')
-rw-r--r-- | xen/common/grant_table.c | 83 |
1 files changed, 36 insertions, 47 deletions
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index a9864d7db7..b81dcff353 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -24,7 +24,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <xen/config.h> +#include <xen/err.h> #include <xen/iocap.h> #include <xen/lib.h> #include <xen/sched.h> @@ -195,6 +195,30 @@ double_gt_unlock(struct grant_table *lgt, struct grant_table *rgt) spin_unlock(&rgt->lock); } +static struct domain *gt_lock_target_domain_by_id(domid_t dom) +{ + struct domain *d; + int rc = GNTST_general_error; + + switch ( rcu_lock_target_domain_by_id(dom, &d) ) + { + case 0: + return d; + + case -ESRCH: + gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); + rc = GNTST_bad_domain; + break; + + case -EPERM: + rc = GNTST_permission_denied; + break; + } + + ASSERT(rc < 0 && -rc <= MAX_ERRNO); + return ERR_PTR(rc); +} + static inline int __get_maptrack_handle( struct grant_table *t) @@ -1261,7 +1285,6 @@ gnttab_setup_table( struct grant_table *gt; int i; unsigned long gmfn; - domid_t dom; if ( count != 1 ) return -EINVAL; @@ -1281,25 +1304,11 @@ gnttab_setup_table( goto out1; } - dom = op.dom; - if ( dom == DOMID_SELF ) + d = gt_lock_target_domain_by_id(op.dom); + if ( IS_ERR(d) ) { - d = rcu_lock_current_domain(); - } - else - { - if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) ) - { - gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); - op.status = GNTST_bad_domain; - goto out1; - } - - if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) - { - op.status = GNTST_permission_denied; - goto out2; - } + op.status = PTR_ERR(d); + goto out1; } if ( xsm_grant_setup(current->domain, d) ) @@ -1352,7 +1361,6 @@ gnttab_query_size( { struct gnttab_query_size op; struct domain *d; - domid_t dom; int rc; if ( count != 1 ) @@ -1364,25 +1372,11 @@ gnttab_query_size( return -EFAULT; } - dom = op.dom; - if ( dom == DOMID_SELF ) - { - d = rcu_lock_current_domain(); - } - else + d = gt_lock_target_domain_by_id(op.dom); + if ( IS_ERR(d) ) { - if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) ) - { - gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); - op.status = GNTST_bad_domain; - goto query_out; - } - - if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) - { - op.status = GNTST_permission_denied; - goto query_out_unlock; - } + op.status = PTR_ERR(d); + goto query_out; } rc = xsm_grant_query_size(current->domain, d); @@ -2251,15 +2245,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE(gnttab_get_status_frames_t) uop, return -EFAULT; } - rc = rcu_lock_target_domain_by_id(op.dom, &d); - if ( rc < 0 ) + d = gt_lock_target_domain_by_id(op.dom); + if ( IS_ERR(d) ) { - if ( rc == -ESRCH ) - op.status = GNTST_bad_domain; - else if ( rc == -EPERM ) - op.status = GNTST_permission_denied; - else - op.status = GNTST_general_error; + op.status = PTR_ERR(d); goto out1; } rc = xsm_grant_setup(current->domain, d); |