aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-02-07 09:51:33 +0000
committerKeir Fraser <keir@xen.org>2011-02-07 09:51:33 +0000
commit78f17e33f3ca8f6d509595165729a8f3a1210322 (patch)
tree3c32ef8450e523f927903357134e745a7388c752
parentcb6e62fc9962ed9f77dd6d9ed45a9f152a3a7b7b (diff)
downloadxen-78f17e33f3ca8f6d509595165729a8f3a1210322.tar.gz
xen-78f17e33f3ca8f6d509595165729a8f3a1210322.tar.bz2
xen-78f17e33f3ca8f6d509595165729a8f3a1210322.zip
Introduce rcu_lock_remote_target_domain_by_id().
Signed-off-by: Keir Fraser <keir@xen.org>
-rw-r--r--xen/common/domain.c14
-rw-r--r--xen/include/xen/sched.h7
2 files changed, 21 insertions, 0 deletions
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 02327d1e9f..b8c48a7ab0 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -438,6 +438,20 @@ int rcu_lock_target_domain_by_id(domid_t dom, struct domain **d)
return 0;
}
+int rcu_lock_remote_target_domain_by_id(domid_t dom, struct domain **d)
+{
+ if ( (*d = rcu_lock_domain_by_id(dom)) == NULL )
+ return -ESRCH;
+
+ if ( (*d == current->domain) || !IS_PRIV_FOR(current->domain, *d) )
+ {
+ rcu_unlock_domain(*d);
+ return -EPERM;
+ }
+
+ return 0;
+}
+
int domain_kill(struct domain *d)
{
int rc = 0;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index ce45800dbe..652a39c5b0 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -435,6 +435,13 @@ struct domain *rcu_lock_domain_by_id(domid_t dom);
*/
int rcu_lock_target_domain_by_id(domid_t dom, struct domain **d);
+/*
+ * As rcu_lock_target_domain_by_id(), but will fail EPERM rather than resolve
+ * to local domain. Successful return always resolves to a remote domain that
+ * the local domain is privileged to control.
+ */
+int rcu_lock_remote_target_domain_by_id(domid_t dom, struct domain **d);
+
/* Finish a RCU critical region started by rcu_lock_domain_by_id(). */
static inline void rcu_unlock_domain(struct domain *d)
{