diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 5f97d9d181..89195b042c 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -3171,7 +3171,7 @@ static int __init alloc_xenstore_evtchn(struct domain *d)
 
     alloc.dom = d->domain_id;
     alloc.remote_dom = hardware_domain->domain_id;
-    rc = evtchn_alloc_unbound(&alloc, 0);
+    rc = evtchn_alloc_unbound(&alloc, 0, false);
     if ( rc )
     {
         printk("Failed allocating event channel for domain\n");
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 84f0055a5a..cedc98ccaf 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -294,7 +294,8 @@ void evtchn_free(struct domain *d, struct evtchn *chn)
  * If port is zero get the next free port and allocate. If port is non-zero
  * allocate the specified port.
  */
-int evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc, evtchn_port_t port)
+int evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc, evtchn_port_t port,
+                         bool is_static)
 {
     struct evtchn *chn;
     struct domain *d;
@@ -330,6 +331,7 @@ int evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc, evtchn_port_t port)
     evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
+    chn->is_static = is_static;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
@@ -368,7 +370,7 @@ static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
  * allocate the specified lport.
  */
 int evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind, struct domain *ld,
-                            evtchn_port_t lport)
+                            evtchn_port_t lport, bool is_static)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
@@ -423,6 +425,7 @@ int evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind, struct domain *ld,
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
     lchn->state                     = ECS_INTERDOMAIN;
+    lchn->is_static                 = is_static;
     evtchn_port_init(ld, lchn);
     
     rchn->u.interdomain.remote_dom  = ld;
@@ -659,6 +662,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         rc = -EINVAL;
         goto out;
     }
+    /* Guest cannot close a static event channel. */
+    if ( chn1->is_static && guest )
+        goto out;
 
     switch ( chn1->state )
     {
@@ -1238,7 +1244,7 @@ long cf_check do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         struct evtchn_alloc_unbound alloc_unbound;
         if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
             return -EFAULT;
-        rc = evtchn_alloc_unbound(&alloc_unbound, 0);
+        rc = evtchn_alloc_unbound(&alloc_unbound, 0, false);
         if ( !rc && __copy_to_guest(arg, &alloc_unbound, 1) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
@@ -1248,7 +1254,8 @@ long cf_check do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         struct evtchn_bind_interdomain bind_interdomain;
         if ( copy_from_guest(&bind_interdomain, arg, 1) != 0 )
             return -EFAULT;
-        rc = evtchn_bind_interdomain(&bind_interdomain, current->domain, 0);
+        rc = evtchn_bind_interdomain(&bind_interdomain, current->domain,
+                                     0, false);
         if ( !rc && __copy_to_guest(arg, &bind_interdomain, 1) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 8eae9984a9..71ad4c5bfd 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -73,12 +73,12 @@ int evtchn_allocate_port(struct domain *d, unsigned int port);
 
 /* Allocate a new event channel */
 int __must_check evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc,
-                                      evtchn_port_t port);
+                                      evtchn_port_t port, bool is_static);
 
 /* Bind an event channel port to interdomain */
 int __must_check evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind,
                                          struct domain *ld,
-                                         evtchn_port_t port);
+                                         evtchn_port_t port, bool is_static);
 
 /* Unmask a local event-channel port. */
 int evtchn_unmask(unsigned int port);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 463d41ffb6..da823c8091 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -119,6 +119,7 @@ struct evtchn
     unsigned char priority;        /* FIFO event channels only. */
     unsigned short notify_vcpu_id; /* VCPU for local delivery notification */
     uint32_t fifo_lastq;           /* Data for identifying last queue. */
+    bool is_static;                /* Static event channels. */
 
 #ifdef CONFIG_XSM
     union {
