aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-11 10:07:19 +0000
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-11 10:07:19 +0000
commitd018d6b4fb36f04086783d6883b25641ae166034 (patch)
tree76e1ec67fc56504d319969f86e94bf5671196511 /xen/common
parent698f86a15a06ebd07ab15c11ad97b7a8fb2d3998 (diff)
downloadxen-d018d6b4fb36f04086783d6883b25641ae166034.tar.gz
xen-d018d6b4fb36f04086783d6883b25641ae166034.tar.bz2
xen-d018d6b4fb36f04086783d6883b25641ae166034.zip
xen: avoid calling rcu_lock_*target_domain when an XSM hook exists
The rcu_lock_{,remote_}target_domain_by_id functions are wrappers around an IS_PRIV_FOR check for the current domain. This is now redundant with XSM hooks, so replace these calls with rcu_lock_domain_by_any_id or rcu_lock_remote_domain_by_id to remove the duplicate permission checks. When XSM_ENABLE is not defined or when the dummy XSM module is used, this patch should not change any functionality. Because the locations of privilege checks have sometimes moved below argument validation, error returns of some functions may change from EPERM to EINVAL when called with invalid arguments and from a domain without permission to perform the operation. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common')
-rw-r--r--xen/common/event_channel.c18
-rw-r--r--xen/common/grant_table.c57
-rw-r--r--xen/common/memory.c15
3 files changed, 35 insertions, 55 deletions
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 89f0ca7620..f620966ce2 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -165,9 +165,9 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
domid_t dom = alloc->dom;
long rc;
- rc = rcu_lock_target_domain_by_id(dom, &d);
- if ( rc )
- return rc;
+ d = rcu_lock_domain_by_any_id(dom);
+ if ( d == NULL )
+ return -ESRCH;
spin_lock(&d->event_lock);
@@ -798,9 +798,9 @@ static long evtchn_status(evtchn_status_t *status)
struct evtchn *chn;
long rc = 0;
- rc = rcu_lock_target_domain_by_id(dom, &d);
- if ( rc )
- return rc;
+ d = rcu_lock_domain_by_any_id(dom);
+ if ( d == NULL )
+ return -ESRCH;
spin_lock(&d->event_lock);
@@ -950,9 +950,9 @@ static long evtchn_reset(evtchn_reset_t *r)
struct domain *d;
int i, rc;
- rc = rcu_lock_target_domain_by_id(dom, &d);
- if ( rc )
- return rc;
+ d = rcu_lock_domain_by_any_id(dom);
+ if ( d == NULL )
+ return -ESRCH;
rc = xsm_evtchn_reset(current->domain, d);
if ( rc )
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index ce66d7598f..59708c33e4 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -230,30 +230,6 @@ 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)
@@ -1352,11 +1328,12 @@ gnttab_setup_table(
if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
return -EFAULT;
- d = gt_lock_target_domain_by_id(op.dom);
- if ( IS_ERR(d) )
+ d = rcu_lock_domain_by_any_id(op.dom);
+ if ( d == NULL )
{
- op.status = PTR_ERR(d);
- goto out1;
+ gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom);
+ op.status = GNTST_bad_domain;
+ goto out2;
}
if ( xsm_grant_setup(current->domain, d) )
@@ -1421,10 +1398,11 @@ gnttab_query_size(
return -EFAULT;
}
- d = gt_lock_target_domain_by_id(op.dom);
- if ( IS_ERR(d) )
+ d = rcu_lock_domain_by_any_id(op.dom);
+ if ( d == NULL )
{
- op.status = PTR_ERR(d);
+ gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom);
+ op.status = GNTST_bad_domain;
goto query_out;
}
@@ -2296,10 +2274,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
return -EFAULT;
}
- d = gt_lock_target_domain_by_id(op.dom);
- if ( IS_ERR(d) )
+ d = rcu_lock_domain_by_any_id(op.dom);
+ if ( d == NULL )
{
- op.status = PTR_ERR(d);
+ op.status = GNTST_bad_domain;
goto out1;
}
rc = xsm_grant_setup(current->domain, d);
@@ -2349,14 +2327,15 @@ gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop)
if ( copy_from_guest(&op, uop, 1) )
return -EFAULT;
- rc = rcu_lock_target_domain_by_id(op.dom, &d);
- if ( rc < 0 )
- return rc;
+ d = rcu_lock_domain_by_any_id(op.dom);
+ if ( d == NULL )
+ return -ESRCH;
- if ( xsm_grant_query_size(current->domain, d) )
+ rc = xsm_grant_query_size(current->domain, d);
+ if ( rc )
{
rcu_unlock_domain(d);
- return -EPERM;
+ return rc;
}
op.version = d->grant_table->gt_version;
diff --git a/xen/common/memory.c b/xen/common/memory.c
index c8c1ef2896..35acf1cb88 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -585,7 +585,8 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
&& (reservation.mem_flags & XENMEMF_populate_on_demand) )
args.memflags |= MEMF_populate_on_demand;
- if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) )
+ d = rcu_lock_domain_by_any_id(reservation.domid);
+ if ( d == NULL )
return start_extent;
args.domain = d;
@@ -634,9 +635,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( copy_from_guest(&domid, arg, 1) )
return -EFAULT;
- rc = rcu_lock_target_domain_by_id(domid, &d);
- if ( rc )
- return rc;
+ d = rcu_lock_domain_by_any_id(domid);
+ if ( d == NULL )
+ return -ESRCH;
rc = xsm_memory_stat_reservation(current->domain, d);
if ( rc )
@@ -672,9 +673,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( copy_from_guest(&xrfp, arg, 1) )
return -EFAULT;
- rc = rcu_lock_target_domain_by_id(xrfp.domid, &d);
- if ( rc != 0 )
- return rc;
+ d = rcu_lock_domain_by_any_id(xrfp.domid);
+ if ( d == NULL )
+ return -ESRCH;
if ( xsm_remove_from_physmap(current->domain, d) )
{