All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christopher Clark <christopher.w.clark@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Wei Liu <wei.liu2@citrix.com>,
	Ross Philipson <ross.philipson@gmail.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	George Dunlap <George.Dunlap@eu.citrix.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Jason Andryuk <jandryuk@gmail.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Rich Persaud <persaur@gmail.com>, Tim Deegan <tim@xen.org>,
	Daniel Smith <dpsmith@apertussolutions.com>,
	Julien Grall <julien.grall@arm.com>,
	Paul Durrant <paul.durrant@citrix.com>,
	Jan Beulich <jbeulich@suse.com>,
	James McKenzie <james@bromium.com>,
	Eric Chanudet <eric.chanudet@gmail.com>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: [PATCH v5 08/15] argo: implement the unregister op
Date: Mon, 21 Jan 2019 01:59:48 -0800	[thread overview]
Message-ID: <1548064795-18160-9-git-send-email-christopher.w.clark@gmail.com> (raw)
In-Reply-To: <1548064795-18160-1-git-send-email-christopher.w.clark@gmail.com>

Takes a single argument: a handle to the ring unregistration struct,
which specifies the port and partner domain id or wildcard.

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.

If the ring had been registered to communicate with a single specified
domain (ie. a non-wildcard ring) then the partner domain state is removed
from the partner domain's argo send_info hash table.

Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
---
The logic in unregister_ring got pretty heavily reordered in this version
of the patch, to shrink the critical sections. I'm happy with the result.
I've added a couple of ASSERT_UNREACHABLEs where it seems appropriate.

v4 # Jan: shrink the critical sections in unregister
v4 : use standard data structures as per common code
v4 #08 Roger: skip send_info lookup for wildcard rings
v4: add ASSERT_UNREACHABLE for missing sender domain or send_info
v4: reduce indentation by using goto
v4: add unlikely to currd->argo check
v4 #08 Jan: move put_domain outside L2 critical section
v4: include ring data in debug output when ring not found

v3 #08 Jan: pull xfree out of exclusive critical sections in unregister_ring
v3 #08 Jan: rename send_find_info to find_send_info
v3 #07 Jan: rename ring_find_info to find_ring_info
v3 #08 Roger: use return and remove the out label in unregister_ring
v3 #08 Roger: better debug output in send_find_info
v3 #10 Roger: move find functions to top of file and drop prototypes
v3 #04 Jan: meld compat check for unregister_ring struct
v3 #04 Roger/Jan: make lock names clearer and assert their state
v3 #04 Jan: port -> aport with type; distinguish argo port from evtchn
v3 feedback Roger/Jan: ASSERT currd is current->domain or use 'd' variable name
v3 feedback #07 Roger: const the argo_ring_id structs in send_find_info
v2 feedback Jan: drop cookie, implement teardown
v2 feedback Jan: drop message from argo_message_op
v2 self: OVERHAUL
v2 self: reorder logic to shorten critical section
v1 #13 feedback Jan: revise use of guest_handle_okay vs __copy ops
v1 feedback Roger, Jan: drop argo prefix on static functions
v1,2 feedback Jan/Roger/Paul: drop errno returning guest access functions
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         | 126 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/common/compat/argo.c  |   1 +
 xen/include/public/argo.h |  19 +++++++
 xen/include/xlat.lst      |   1 +
 4 files changed, 147 insertions(+)

diff --git a/xen/common/argo.c b/xen/common/argo.c
index a7ec0e0..e4cd446 100644
--- a/xen/common/argo.c
+++ b/xen/common/argo.c
@@ -43,6 +43,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_argo_addr_t);
 DEFINE_XEN_GUEST_HANDLE(xen_argo_gfn_t);
 DEFINE_XEN_GUEST_HANDLE(xen_argo_register_ring_t);
 DEFINE_XEN_GUEST_HANDLE(xen_argo_ring_t);
+DEFINE_XEN_GUEST_HANDLE(xen_argo_unregister_ring_t);
 
 static bool __read_mostly opt_argo;
 static bool __read_mostly opt_argo_mac_permissive;
@@ -351,6 +352,37 @@ find_ring_info(const struct domain *d, const struct argo_ring_id *id)
     return NULL;
 }
 
+static struct argo_send_info *
+find_send_info(const struct domain *d, const struct argo_ring_id *id)
+{
+    struct list_head *cursor, *bucket;
+
+    ASSERT(LOCKING_send_L2(d));
+
+    /* List is not modified here. Search and return the match if found. */
+    bucket = &d->argo->send_hash[hash_index(id)];
+
+    for ( cursor = bucket->next; cursor != bucket; cursor = cursor->next )
+    {
+        struct argo_send_info *send_info =
+            list_entry(cursor, struct argo_send_info, node);
+        const struct argo_ring_id *cmpid = &send_info->id;
+
+        if ( cmpid->aport == id->aport &&
+             cmpid->domain_id == id->domain_id &&
+             cmpid->partner_id == id->partner_id )
+        {
+            argo_dprintk("found send_info for ring(%u:%x %u)\n",
+                         id->domain_id, id->aport, id->partner_id);
+            return send_info;
+        }
+    }
+    argo_dprintk("no send_info for ring(%u:%x %u)\n",
+                 id->domain_id, id->aport, id->partner_id);
+
+    return NULL;
+}
+
 static void
 ring_unmap(const struct domain *d, struct argo_ring_info *ring_info)
 {
@@ -735,6 +767,85 @@ find_ring_mfns(struct domain *d, struct argo_ring_info *ring_info,
 }
 
 static long
+unregister_ring(struct domain *currd,
+                XEN_GUEST_HANDLE_PARAM(xen_argo_unregister_ring_t) unreg_hnd)
+{
+    xen_argo_unregister_ring_t unreg;
+    struct argo_ring_id ring_id;
+    struct argo_ring_info *ring_info = NULL;
+    struct argo_send_info *send_info = NULL;
+    struct domain *dst_d = NULL;
+
+    ASSERT(currd == current->domain);
+
+    if ( copy_from_guest(&unreg, unreg_hnd, 1) )
+        return -EFAULT;
+
+    if ( unreg.pad )
+        return -EINVAL;
+
+    ring_id.partner_id = unreg.partner_id;
+    ring_id.aport = unreg.aport;
+    ring_id.domain_id = currd->domain_id;
+
+    read_lock(&L1_global_argo_rwlock);
+
+    if ( unlikely(!currd->argo) )
+    {
+        read_unlock(&L1_global_argo_rwlock);
+        return -ENODEV;
+    }
+
+    write_lock(&currd->argo->rings_L2_rwlock);
+
+    ring_info = find_ring_info(currd, &ring_id);
+    if ( !ring_info )
+        goto out;
+
+    ring_remove_info(currd, ring_info);
+    currd->argo->ring_count--;
+
+    if ( ring_id.partner_id == XEN_ARGO_DOMID_ANY )
+        goto out;
+
+    dst_d = get_domain_by_id(ring_id.partner_id);
+    if ( !dst_d || !dst_d->argo )
+    {
+        ASSERT_UNREACHABLE();
+        goto out;
+    }
+
+    spin_lock(&dst_d->argo->send_L2_lock);
+
+    send_info = find_send_info(dst_d, &ring_id);
+    if ( send_info )
+        list_del(&send_info->node);
+    else
+        ASSERT_UNREACHABLE();
+
+    spin_unlock(&dst_d->argo->send_L2_lock);
+
+ out:
+    write_unlock(&currd->argo->rings_L2_rwlock);
+
+    read_unlock(&L1_global_argo_rwlock);
+
+    if ( dst_d )
+        put_domain(dst_d);
+
+    xfree(send_info);
+
+    if ( !ring_info )
+    {
+        argo_dprintk("unregister_ring: no ring_info found for ring(%u:%x %u)\n",
+                     ring_id.domain_id, ring_id.aport, ring_id.partner_id);
+        return -ENOENT;
+    }
+
+    return 0;
+}
+
+static long
 register_ring(struct domain *currd,
               XEN_GUEST_HANDLE_PARAM(xen_argo_register_ring_t) reg_hnd,
               XEN_GUEST_HANDLE_PARAM(xen_argo_gfn_t) gfn_hnd,
@@ -1019,6 +1130,21 @@ do_argo_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) arg1,
         break;
     }
 
+    case XEN_ARGO_OP_unregister_ring:
+    {
+        XEN_GUEST_HANDLE_PARAM(xen_argo_unregister_ring_t) unreg_hnd =
+            guest_handle_cast(arg1, xen_argo_unregister_ring_t);
+
+        if ( unlikely((!guest_handle_is_null(arg2)) || arg3 || arg4) )
+        {
+            rc = -EINVAL;
+            break;
+        }
+
+        rc = unregister_ring(currd, unreg_hnd);
+        break;
+    }
+
     default:
         rc = -EOPNOTSUPP;
         break;
diff --git a/xen/common/compat/argo.c b/xen/common/compat/argo.c
index 9437a7a..6a1671c 100644
--- a/xen/common/compat/argo.c
+++ b/xen/common/compat/argo.c
@@ -22,3 +22,4 @@
 CHECK_argo_addr;
 CHECK_argo_register_ring;
 CHECK_argo_ring;
+CHECK_argo_unregister_ring;
diff --git a/xen/include/public/argo.h b/xen/include/public/argo.h
index f822756..2371510 100644
--- a/xen/include/public/argo.h
+++ b/xen/include/public/argo.h
@@ -79,6 +79,13 @@ typedef struct xen_argo_register_ring
     uint32_t len;
 } xen_argo_register_ring_t;
 
+typedef struct xen_argo_unregister_ring
+{
+    xen_argo_port_t aport;
+    domid_t partner_id;
+    uint16_t pad;
+} xen_argo_unregister_ring_t;
+
 /* Messages on the ring are padded to a multiple of this size. */
 #define XEN_ARGO_MSG_SLOT_SIZE 0x10
 
@@ -134,4 +141,16 @@ struct xen_argo_ring_message_header
 #define XEN_ARGO_REGISTER_FLAG_MASK XEN_ARGO_REGISTER_FLAG_FAIL_EXIST
 #endif
 
+/*
+ * XEN_ARGO_OP_unregister_ring
+ *
+ * Unregister a previously-registered ring, ending communication.
+ *
+ * arg1: XEN_GUEST_HANDLE(xen_argo_unregister_ring_t)
+ * arg2: NULL
+ * arg3: 0 (ZERO)
+ * arg4: 0 (ZERO)
+ */
+#define XEN_ARGO_OP_unregister_ring     2
+
 #endif
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 9c9d33f..411c661 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -151,3 +151,4 @@
 ?	argo_addr			argo.h
 ?	argo_ring			argo.h
 ?	argo_register_ring		argo.h
+?	argo_unregister_ring		argo.h
-- 
2.7.4


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

  parent reply	other threads:[~2019-01-21 10:00 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-21  9:59 [PATCH v5 00/15] Argo: hypervisor-mediated interdomain communication Christopher Clark
2019-01-21  9:59 ` [PATCH v5 01/15] argo: Introduce the Kconfig option to govern inclusion of Argo Christopher Clark
2019-01-21  9:59 ` [PATCH v5 02/15] argo: introduce the argo_op hypercall boilerplate Christopher Clark
2019-01-21  9:59 ` [PATCH v5 03/15] argo: define argo_dprintk for subsystem debugging Christopher Clark
2019-01-21  9:59 ` [PATCH v5 04/15] argo: init, destroy and soft-reset, with enable command line opt Christopher Clark
2019-01-21 17:55   ` Roger Pau Monné
2019-01-31  4:06     ` Christopher Clark
2019-01-31 10:28       ` Jan Beulich
2019-01-21  9:59 ` [PATCH v5 05/15] errno: add POSIX error codes EMSGSIZE, ECONNREFUSED to the ABI Christopher Clark
2019-01-21  9:59 ` [PATCH v5 06/15] xen/arm: introduce guest_handle_for_field() Christopher Clark
2019-01-21  9:59 ` [PATCH v5 07/15] argo: implement the register op Christopher Clark
2019-01-22  9:59   ` Roger Pau Monné
2019-01-31  4:08     ` Christopher Clark
2019-01-21  9:59 ` Christopher Clark [this message]
2019-01-22 11:02   ` [PATCH v5 08/15] argo: implement the unregister op Roger Pau Monné
2019-01-21  9:59 ` [PATCH v5 09/15] argo: implement the sendv op; evtchn: expose send_guest_global_virq Christopher Clark
2019-01-22 12:08   ` Roger Pau Monné
2019-01-31  4:10     ` Christopher Clark
2019-01-31 10:18       ` Roger Pau Monné
2019-01-31 10:35         ` Jan Beulich
2019-01-31 11:00           ` Roger Pau Monné
2019-02-03 17:56             ` Christopher Clark
2019-02-04  9:30               ` Roger Pau Monné
2019-01-21  9:59 ` [PATCH v5 10/15] argo: implement the notify op Christopher Clark
2019-01-22 14:09   ` Roger Pau Monné
2019-01-31  4:12     ` Christopher Clark
2019-01-21  9:59 ` [PATCH v5 11/15] xsm, argo: XSM control for argo register Christopher Clark
2019-01-21  9:59 ` [PATCH v5 12/15] xsm, argo: XSM control for argo message send operation Christopher Clark
2019-01-21  9:59 ` [PATCH v5 13/15] xsm, argo: XSM control for any access to argo by a domain Christopher Clark
2019-01-21  9:59 ` [PATCH v5 14/15] xsm, argo: notify: don't describe rings that cannot be sent to Christopher Clark
2019-01-21  9:59 ` [PATCH v5 15/15] MAINTAINERS: add new section for Argo and self as maintainer Christopher Clark
2019-01-21 10:58   ` Wei Liu
2019-01-21 11:07   ` Jan Beulich
2019-01-22 14:17 ` [PATCH v5 00/15] Argo: hypervisor-mediated interdomain communication Roger Pau Monné
2019-01-31  4:05   ` Christopher Clark
2019-01-31 13:39     ` Roger Pau Monné
2019-02-03 18:04       ` Christopher Clark
2019-02-04 10:07         ` Roger Pau Monné
2019-02-04 18:22           ` Stefano Stabellini
2019-02-13 10:31             ` Rich Persaud
2019-02-13 22:19               ` Stefano Stabellini
2019-02-06 10:31           ` Roger Pau Monné
2019-02-06 10:36           ` Roger Pau Monné
2019-02-13 10:43           ` Rich Persaud

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1548064795-18160-9-git-send-email-christopher.w.clark@gmail.com \
    --to=christopher.w.clark@gmail.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dpsmith@apertussolutions.com \
    --cc=eric.chanudet@gmail.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=james@bromium.com \
    --cc=jandryuk@gmail.com \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=paul.durrant@citrix.com \
    --cc=persaur@gmail.com \
    --cc=roger.pau@citrix.com \
    --cc=ross.philipson@gmail.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.