xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: David Vrabel <david.vrabel@citrix.com>
To: xen-devel@lists.xen.org
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>,
	Keir Fraser <keir@xen.org>,
	David Vrabel <david.vrabel@citrix.com>,
	Jan Beulich <jbeulich@suse.com>
Subject: [PATCH 09/11] evtchn: implement EVTCHNOP_set_limit
Date: Fri, 13 Sep 2013 17:56:11 +0100	[thread overview]
Message-ID: <1379091373-30293-10-git-send-email-david.vrabel@citrix.com> (raw)
In-Reply-To: <1379091373-30293-1-git-send-email-david.vrabel@citrix.com>

From: David Vrabel <david.vrabel@citrix.com>

Add max_evtchn_port to struct domain as the maximum port number that a
domain may bind.  Allow a suitably privileged domain to set this limit
so it may restrict the other domain's usage of Xen resources for event
channels (primarily global mapping entries for the shared data
structures).

The default values for this limit is unlimited for control domains or
NR_EVENT_CHANNELS - 1 for other domains.  These defaults ensure that no
domain will regress in the number of event channels they may use.

If a domain is expected to use the FIFO-based event channel ABI, a
toolstack may wish to set the limit to 1023 or lower to ensure a
minimum number of global mapping entries is used.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 xen/common/event_channel.c         |   47 +++++++++++++++++++++++++++++++++++-
 xen/include/public/event_channel.h |    3 ++
 xen/include/xen/sched.h            |    1 +
 xen/include/xsm/dummy.h            |    6 ++++
 xen/include/xsm/xsm.h              |    6 ++++
 5 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index d583d54..45ff115 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -132,10 +132,14 @@ static int get_free_port(struct domain *d)
         return -EINVAL;
 
     for ( port = 0; port_is_valid(d, port); port++ )
+    {
+        if (port > d->max_evtchn_port )
+            return -ENOSPC;
         if ( evtchn_from_port(d, port)->state == ECS_FREE )
             return port;
+    }
 
-    if ( port == d->max_evtchns )
+    if ( port == d->max_evtchns || port > d->max_evtchn_port )
         return -ENOSPC;
 
     if ( unlikely(group_from_port(d, port)  == NULL ) )
@@ -956,6 +960,34 @@ static long evtchn_set_priority(const struct evtchn_set_priority *set_priority)
     return ret;
 }
 
+static long evtchn_set_limit(const struct evtchn_set_limit *set_limit)
+{
+    struct domain *d;
+    unsigned max_port = set_limit->max_port;
+    long ret;
+
+    if ( max_port > EVTCHN_MAX_PORT_UNLIMITED )
+        return -EINVAL;
+
+    d = rcu_lock_domain_by_id(set_limit->domid);
+    if ( !d )
+        return -ESRCH;
+
+    ret = xsm_evtchn_set_limit(XSM_DM_PRIV, d);
+    if ( ret )
+        goto out;
+
+    spin_lock(&d->event_lock);
+
+    d->max_evtchn_port = max_port;
+
+    spin_unlock(&d->event_lock);
+
+out:
+    rcu_unlock_domain(d);
+    return ret;
+}
+
 long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
     long rc;
@@ -1072,6 +1104,14 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         break;
     }
 
+    case EVTCHNOP_set_limit: {
+        struct evtchn_set_limit set_limit;
+        if ( copy_from_guest(&set_limit, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_set_limit(&set_limit);
+        break;
+    }
+
     default:
         rc = -ENOSYS;
         break;
@@ -1189,6 +1229,11 @@ void evtchn_check_pollers(struct domain *d, unsigned port)
 
 int evtchn_init(struct domain *d)
 {
+    if ( is_control_domain(d) )
+        d->max_evtchn_port = EVTCHN_MAX_PORT_UNLIMITED;
+    else
+        d->max_evtchn_port = EVTCHN_MAX_PORT_DEFAULT;
+
     /* Default to N-level ABI. */
     evtchn_2l_init(d);
 
diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h
index 031366a..30a233c 100644
--- a/xen/include/public/event_channel.h
+++ b/xen/include/public/event_channel.h
@@ -308,6 +308,9 @@ struct evtchn_set_limit {
 };
 typedef struct evtchn_set_limit evtchn_set_limit_t;
 
+#define EVTCHN_MAX_PORT_UNLIMITED ((1u << 31) - 1)
+#define EVTCHN_MAX_PORT_DEFAULT   (NR_EVENT_CHANNELS - 1)
+
 /*
  * ` enum neg_errnoval
  * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index b348232..ba3714d 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -287,6 +287,7 @@ struct domain
     /* Event channel information. */
     struct evtchn ***evtchn;
     unsigned         max_evtchns;
+    unsigned         max_evtchn_port;
     spinlock_t       event_lock;
     const struct evtchn_port_ops *evtchn_port_ops;
 
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index cc0a5a8..3f1f3c1 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -296,6 +296,12 @@ static XSM_INLINE int xsm_evtchn_reset(XSM_DEFAULT_ARG struct domain *d1, struct
     return xsm_default_action(action, d1, d2);
 }
 
+static XSM_INLINE int xsm_evtchn_set_limit(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_alloc_security_evtchn(struct evtchn *chn)
 {
     return 0;
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 1939453..ae79ca9 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -70,6 +70,7 @@ struct xsm_operations {
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
+    int (*evtchn_set_limit) (struct domain *d);
 
     int (*grant_mapref) (struct domain *d1, struct domain *d2, uint32_t flags);
     int (*grant_unmapref) (struct domain *d1, struct domain *d2);
@@ -255,6 +256,11 @@ static inline int xsm_evtchn_reset (xsm_default_t def, struct domain *d1, struct
     return xsm_ops->evtchn_reset(d1, d2);
 }
 
+static inline int xsm_evtchn_set_limit (xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->evtchn_set_limit(d);
+}
+
 static inline int xsm_grant_mapref (xsm_default_t def, struct domain *d1, struct domain *d2,
                                                                 uint32_t flags)
 {
-- 
1.7.2.5

  parent reply	other threads:[~2013-09-13 16:56 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-13 16:56 [PATCHv3 0/11] Xen: FIFO-based event channel ABI David Vrabel
2013-09-13 16:56 ` [PATCH 01/11] debug: remove some event channel info from the 'i' and 'q' debug keys David Vrabel
2013-09-13 16:56 ` [PATCH 02/11] evtchn: refactor low-level event channel port ops David Vrabel
2013-09-15 13:06   ` Stefano Stabellini
2013-09-15 13:11     ` Stefano Stabellini
2013-09-16 10:08       ` David Vrabel
2013-09-15 13:20     ` Ian Campbell
2013-09-13 16:56 ` [PATCH 03/11] evtchn: print ABI specific state with the 'e' debug key David Vrabel
2013-09-13 16:56 ` [PATCH 04/11] evtchn: use a per-domain variable for the max number of event channels David Vrabel
2013-09-13 16:56 ` [PATCH 05/11] evtchn: dynamically allocate d->evtchn David Vrabel
2013-09-13 16:56 ` [PATCH 06/11] evtchn: alter internal object handling scheme David Vrabel
2013-09-13 16:56 ` [PATCH 07/11] evtchn: add FIFO-based event channel ABI David Vrabel
2013-09-16  6:59   ` Jan Beulich
2013-09-13 16:56 ` [PATCH 08/11] evtchn: implement EVTCHNOP_set_priority and add the set_priority hook David Vrabel
2013-09-13 16:56 ` David Vrabel [this message]
2013-09-13 18:32   ` [PATCH 09/11] evtchn: implement EVTCHNOP_set_limit Daniel De Graaf
2013-09-16  7:07   ` Jan Beulich
2013-09-16 10:00     ` David Vrabel
2013-09-16 10:33       ` Jan Beulich
2013-09-16 10:57         ` David Vrabel
2013-09-13 16:56 ` [PATCH 10/11] libxc: add xc_evtchn_set_limit() David Vrabel
2013-09-13 16:56 ` [PATCH 11/11] evtchn: add FIFO-based event channel hypercalls and port ops David Vrabel

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=1379091373-30293-10-git-send-email-david.vrabel@citrix.com \
    --to=david.vrabel@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).