|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |