[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 12/18] 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> --- Changes since v1: v1 #5 (#14) feedback Paul: use currd in do_argo_message_op v1 #5 (#14) feedback Paul: full use currd in argo_unregister_ring v1 #13 (#14) feedback Paul: replace do/while with goto; reindent v1 self: add blank lines in unregister case in do_argo_message_op v1: #13 feedback Jan: public namespace: prefix with xen v1: #13 feedback Jan: blank line after op case in do_argo_message_op v1: #14 feedback Jan: replace domain id override with validation v1: #18 feedback Jan: meld the ring count limit into the series v1: feedback #15 Jan: verify zero in unused hypercall args xen/common/argo.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ xen/include/public/argo.h | 12 ++++++++ 2 files changed, 88 insertions(+) diff --git a/xen/common/argo.c b/xen/common/argo.c index 81f8341..cbb17a3 100644 --- a/xen/common/argo.c +++ b/xen/common/argo.c @@ -565,6 +565,65 @@ argo_ring_find_info(const struct domain *d, const struct xen_argo_ring_id *id) return NULL; } +static long +argo_unregister_ring(struct domain *currd, + XEN_GUEST_HANDLE_PARAM(xen_argo_ring_t) ring_hnd) +{ + struct xen_argo_ring ring; + struct argo_ring_info *ring_info; + int ret = 0; + + read_lock(&argo_lock); + + if ( !currd->argo ) + { + ret = -ENODEV; + goto out; + } + + ret = copy_from_guest_errno(&ring, ring_hnd, 1); + if ( ret ) + goto out; + + if ( ring.magic != XEN_ARGO_RING_MAGIC ) + { + argo_dprintk( + "ring.magic(%"PRIx64") != XEN_ARGO_RING_MAGIC(%llx), EINVAL\n", + ring.magic, XEN_ARGO_RING_MAGIC); + ret = -EINVAL; + goto out; + } + + if ( unlikely(ring.id.addr.domain_id != currd->domain_id) ) + { + ret = -EPERM; + goto out; + } + + write_lock(&currd->argo->lock); + + ring_info = argo_ring_find_info(currd, &ring.id); + if ( ring_info ) + { + argo_ring_remove_info(currd, ring_info); + currd->argo->ring_count--; + } + + write_unlock(&currd->argo->lock); + + if ( !ring_info ) + { + argo_dprintk("ENOENT\n"); + ret = -ENOENT; + goto out; + } + + out: + read_unlock(&argo_lock); + + return ret; +} + static int argo_verify_ring_magic(struct argo_ring_info *ring_info) { @@ -882,6 +941,23 @@ do_argo_message_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) arg1, break; } + case XEN_ARGO_MESSAGE_OP_unregister_ring: + { + XEN_GUEST_HANDLE_PARAM(xen_argo_ring_t) ring_hnd = + guest_handle_cast(arg1, xen_argo_ring_t); + + if ( unlikely(!guest_handle_okay(ring_hnd, 1)) ) + break; + if ( unlikely((!guest_handle_is_null(arg2)) || arg3 || arg4) ) + { + rc = -EINVAL; + break; + } + + rc = argo_unregister_ring(currd, ring_hnd); + break; + } + default: rc = -EOPNOTSUPP; break; diff --git a/xen/include/public/argo.h b/xen/include/public/argo.h index e73faea..24696e2 100644 --- a/xen/include/public/argo.h +++ b/xen/include/public/argo.h @@ -138,4 +138,16 @@ struct xen_argo_ring_message_header /* Mask for all defined flags. unsigned long type so ok for both 32/64-bit */ #define XEN_ARGO_REGISTER_FLAG_MASK 0x1UL +/* + * XEN_ARGO_MESSAGE_OP_unregister_ring + * + * Unregister a previously-registered ring, ending communication. + * + * arg1: XEN_GUEST_HANDLE(xen_argo_ring_t) + * arg2: NULL + * arg3: 0 (ZERO) + * arg4: 0 (ZERO) + */ +#define XEN_ARGO_MESSAGE_OP_unregister_ring 2 + #endif -- 2.7.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 |