[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 14/25] argo: implement the unregister op



Takes a single argument: a handle to the registered ring.

The ring's entry is removed from the hashtable of registered rings;
any entries for pending notifications are removed; and the ring is
unmapped from Xen's address space.

Signed-off-by: Christopher Clark <christopher.clark6@xxxxxxxxxxxxxx>
---
 xen/common/argo.c         | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/public/argo.h |  9 +++++++
 2 files changed, 71 insertions(+)

diff --git a/xen/common/argo.c b/xen/common/argo.c
index f4e82cf..387e650 100644
--- a/xen/common/argo.c
+++ b/xen/common/argo.c
@@ -510,6 +510,59 @@ argo_ring_find_info(const struct domain *d, const struct 
argo_ring_id *id)
 }
 
 static long
+argo_unregister_ring(struct domain *d,
+                     XEN_GUEST_HANDLE_PARAM(argo_ring_t) ring_hnd)
+{
+    struct argo_ring ring;
+    struct argo_ring_info *ring_info;
+    int ret = 0;
+
+    read_lock(&argo_lock);
+
+    do {
+        if ( !d->argo )
+        {
+            ret = -ENODEV;
+            break;
+        }
+
+        ret = copy_from_guest_errno(&ring, ring_hnd, 1);
+        if ( ret )
+            break;
+
+        if ( ring.magic != ARGO_RING_MAGIC )
+        {
+            argo_dprintk(
+                "ring.magic(%"PRIx64") != ARGO_RING_MAGIC(%llx), EINVAL\n",
+                ring.magic, ARGO_RING_MAGIC);
+            ret = -EINVAL;
+            break;
+        }
+
+        ring.id.addr.domain_id = d->domain_id;
+
+        write_lock(&d->argo->lock);
+
+        ring_info = argo_ring_find_info(d, &ring.id);
+        if ( ring_info )
+            argo_ring_remove_info(d, ring_info);
+
+        write_unlock(&d->argo->lock);
+
+        if ( !ring_info )
+        {
+            argo_dprintk("ENOENT\n");
+            ret = -ENOENT;
+            break;
+        }
+
+    } while ( 0 );
+
+    read_unlock(&argo_lock);
+    return ret;
+}
+
+static long
 argo_register_ring(struct domain *d,
                    XEN_GUEST_HANDLE_PARAM(argo_ring_t) ring_hnd,
                    XEN_GUEST_HANDLE_PARAM(argo_pfn_t) pfn_hnd, uint32_t npage,
@@ -751,6 +804,15 @@ do_argo_message_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg1,
         rc = argo_register_ring(d, ring_hnd, pfn_hnd, npage, fail_exist);
         break;
     }
+    case ARGO_MESSAGE_OP_unregister_ring:
+    {
+        XEN_GUEST_HANDLE_PARAM(argo_ring_t) ring_hnd =
+            guest_handle_cast(arg1, argo_ring_t);
+        if ( unlikely(!guest_handle_okay(ring_hnd, 1)) )
+            break;
+        rc = argo_unregister_ring(d, ring_hnd);
+        break;
+    }
     default:
         rc = -ENOSYS;
         break;
diff --git a/xen/include/public/argo.h b/xen/include/public/argo.h
index 5ad8e2b..6cf10a8 100644
--- a/xen/include/public/argo.h
+++ b/xen/include/public/argo.h
@@ -116,4 +116,13 @@ struct argo_ring_message_header
 /* Mask for all defined flags */
 #define ARGO_REGISTER_FLAG_MASK ARGO_REGISTER_FLAG_FAIL_EXIST
 
+/*
+ * ARGO_MESSAGE_OP_unregister_ring
+ *
+ * Unregister a previously-registered ring, ending communication.
+ *
+ * arg1: XEN_GUEST_HANDLE(argo_ring_t)
+ */
+#define ARGO_MESSAGE_OP_unregister_ring     2
+
 #endif
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.