Eliminate code duplication with rcu_lock_domain_by_id().
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 2 Oct 2008 10:39:36 +0000 (11:39 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 2 Oct 2008 10:39:36 +0000 (11:39 +0100)
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/mm.c
xen/common/domain.c
xen/common/event_channel.c
xen/common/memory.c
xen/include/xen/sched.h

index 5d9428ca396f692081a8269056eca5026c462747..6c6b0db13bea226e5998c3c4052bf4e0fb21baa0 100644 (file)
@@ -2339,21 +2339,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
         if ( a.index >= HVM_NR_PARAMS )
             return -EINVAL;
 
-        if ( a.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rc = -EPERM;
-                goto param_fail;
-            }
-        }
-
+        rc = rcu_lock_target_domain_by_id(a.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
@@ -2521,20 +2509,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&a, arg, 1) )
             return -EFAULT;
 
-        if ( a.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rc = -EPERM;
-                goto param_fail2;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(a.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
@@ -2570,20 +2547,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&a, arg, 1) )
             return -EFAULT;
 
-        if ( a.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rc = -EPERM;
-                goto param_fail3;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(a.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
@@ -2637,20 +2603,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&a, arg, 1) )
             return -EFAULT;
 
-        if ( a.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rc = -EPERM;
-                goto param_fail4;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(a.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
index b198355f0f0d418463f7000a67d23503099f3d87..51b3537ea4c348dd3b839476e9f97ad3e8a8707c 100644 (file)
@@ -3550,6 +3550,8 @@ DEFINE_XEN_GUEST_HANDLE(e820entry_t);
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 {
     struct page_info *page = NULL;
+    int rc;
+
     switch ( op )
     {
     case XENMEM_add_to_physmap:
@@ -3561,20 +3563,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&xatp, arg, 1) )
             return -EFAULT;
 
-        if ( xatp.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rcu_unlock_domain(d);
-                return -EPERM;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(xatp.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         if ( xsm_add_to_physmap(current->domain, d) )
         {
@@ -3661,20 +3652,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&xrfp, arg, 1) )
             return -EFAULT;
 
-        if ( xrfp.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(xrfp.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rcu_unlock_domain(d);
-                return -EPERM;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(xrfp.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         if ( xsm_remove_from_physmap(current->domain, d) )
         {
@@ -3708,20 +3688,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
         if ( fmap.map.nr_entries > ARRAY_SIZE(d->arch.e820) )
             return -EINVAL;
 
-        if ( fmap.domid == DOMID_SELF )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rcu_unlock_domain(d);
-                return -EPERM;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(fmap.domid, &d);
+        if ( rc != 0 )
+            return rc;
 
         rc = xsm_domain_memory_map(d);
         if ( rc )
index 353242dc2c53299be2bb5d2db386a419854b619a..7e1f0ebe28a860df86e32cff36c36742e63d2718 100644 (file)
@@ -332,6 +332,25 @@ struct domain *rcu_lock_domain_by_id(domid_t dom)
     return NULL;
 }
 
+int rcu_lock_target_domain_by_id(domid_t dom, struct domain **d)
+{
+    if ( dom == DOMID_SELF )
+    {
+        *d = rcu_lock_current_domain();
+        return 0;
+    }
+
+    if ( (*d = rcu_lock_domain_by_id(dom)) == NULL )
+        return -ESRCH;
+
+    if ( !IS_PRIV_FOR(current->domain, *d) )
+    {
+        rcu_unlock_domain(*d);
+        return -EPERM;
+    }
+
+    return 0;
+}
 
 int domain_kill(struct domain *d)
 {
index 006d5eca3a9cfe47103b1f1919f08ba987dbbecf..53dad7acc9446af49a1e7818462c9efed619fa00 100644 (file)
@@ -129,20 +129,9 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     domid_t        dom = alloc->dom;
     long           rc;
 
-    if ( dom == DOMID_SELF )
-    {
-        d = rcu_lock_current_domain();
-    }
-    else
-    {
-        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-            return -ESRCH;
-        if ( !IS_PRIV_FOR(current->domain, d) )
-        {
-            rcu_unlock_domain(d);
-            return -EPERM;
-        }
-    }
+    rc = rcu_lock_target_domain_by_id(dom, &d);
+    if ( rc )
+        return rc;
 
     spin_lock(&d->evtchn_lock);
 
@@ -663,20 +652,9 @@ static long evtchn_status(evtchn_status_t *status)
     struct evtchn   *chn;
     long             rc = 0;
 
-    if ( dom == DOMID_SELF )
-    {
-        d = rcu_lock_current_domain();
-    }
-    else
-    {
-        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-            return -ESRCH;
-        if ( !IS_PRIV_FOR(current->domain, d) )
-        {
-            rcu_unlock_domain(d);
-            return -EPERM;
-        }
-    }
+    rc = rcu_lock_target_domain_by_id(dom, &d);
+    if ( rc )
+        return rc;
 
     spin_lock(&d->evtchn_lock);
 
@@ -824,20 +802,9 @@ static long evtchn_reset(evtchn_reset_t *r)
     struct domain *d;
     int i, rc;
 
-    if ( dom == DOMID_SELF )
-    {
-        d = rcu_lock_current_domain();
-    }
-    else
-    {
-        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-            return -ESRCH;
-        if ( !IS_PRIV_FOR(current->domain, d) )
-        {
-            rc = -EPERM;
-            goto out;
-        }
-    }
+    rc = rcu_lock_target_domain_by_id(dom, &d);
+    if ( rc )
+        return rc;
 
     rc = xsm_evtchn_reset(current->domain, d);
     if ( rc )
index e4d1a59f87992521c4c0daf0818d1efe13c6a1e1..d39c2f59c0204d070f4ed76f078faba25cafc9b2 100644 (file)
@@ -222,21 +222,9 @@ static long translate_gpfn_list(
          !guest_handle_subrange_okay(op.mfn_list, *progress, op.nr_gpfns-1) )
         return -EFAULT;
 
-    if ( op.domid == DOMID_SELF )
-    {
-        d = rcu_lock_current_domain();
-    }
-    else
-    {
-        if ( (d = rcu_lock_domain_by_id(op.domid)) == NULL )
-            return -ESRCH;
-        if ( !IS_PRIV_FOR(current->domain, d) )
-        {
-            rcu_unlock_domain(d);
-            return -EPERM;
-        }
-    }
-
+    rc = rcu_lock_target_domain_by_id(op.domid, &d);
+    if ( rc )
+        return rc;
 
     if ( !paging_mode_translate(d) )
     {
@@ -595,20 +583,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg)
         if ( copy_from_guest(&domid, arg, 1) )
             return -EFAULT;
 
-        if ( likely(domid == DOMID_SELF) )
-        {
-            d = rcu_lock_current_domain();
-        }
-        else
-        {
-            if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
-                return -ESRCH;
-            if ( !IS_PRIV_FOR(current->domain, d) )
-            {
-                rcu_unlock_domain(d);
-                return -EPERM;
-            }
-        }
+        rc = rcu_lock_target_domain_by_id(domid, &d);
+        if ( rc )
+            return rc;
 
         rc = xsm_memory_stat_reservation(current->domain, d);
         if ( rc )
index 273126a949a0d0db9497da86aa7b4e7a6a44b01c..b8bdc1e9a1c5473e254f77732c9cbdd646f9ba7d 100644 (file)
@@ -364,6 +364,13 @@ int construct_dom0(
  */
 struct domain *rcu_lock_domain_by_id(domid_t dom);
 
+/*
+ * As above function, but accounts for current domain context:
+ *  - Translates target DOMID_SELF into caller's domain id; and
+ *  - Checks that caller has permission to act on the target domain.
+ */
+int rcu_lock_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)
 {