[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH V1 07/12] A collection of tweaks to be able to run emulator in driver domain



From: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>

Trying to run emulator in driver domain I ran into various issues
mostly policy-related. So this patch tries to resolve all them
plobably in a hackish way. I would like to get feedback how
to implement them properly as having an emulator in driver domain
is a completely valid use-case.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
---
 xen/common/domain.c        | 15 +++++++++++++++
 xen/common/domctl.c        |  8 +++++++-
 xen/common/event_channel.c | 14 ++++++++++++--
 xen/common/memory.c        |  6 ++++++
 xen/include/xsm/dummy.h    | 16 +++++++++++++---
 5 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index e9be05f..5c9fef2 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -695,6 +695,7 @@ int domain_kill(struct domain *d)
 {
     int rc = 0;
     struct vcpu *v;
+    struct domain *td;
 
     if ( d == current->domain )
         return -EINVAL;
@@ -733,6 +734,20 @@ int domain_kill(struct domain *d)
          * have to be put before we call put_domain. */
         vm_event_cleanup(d);
         put_domain(d);
+        /*
+         * XEN_DOMCTL_set_target implementation holds reference on
+         * target domain which doesn't allow to completely destroy it.
+         * Check if the reference are hold by someone and drop it
+         * when destroying target domain.
+         */
+        for_each_domain ( td ) {
+            if ( td->target == d ) {
+                td->target = NULL;
+                put_domain(d);
+                break;
+            }
+        }
+
         send_global_virq(VIRQ_DOM_EXC);
         /* fallthrough */
     case DOMDYING_dead:
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index a69b3b5..079c7b0 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -871,6 +871,12 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
         if ( (d == e) || (d->target != NULL) )
         {
             put_domain(e);
+            /*
+             * Be a little bit more polite here, looks like the emulator
+             * has just been restarted.
+             */
+            if ( d->target == e )
+                ret = 0;
             break;
         }
 
@@ -883,7 +889,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
             break;
         }
 
-        /* Hold reference on @e until we destroy @d. */
+        /* Hold reference on @e until we destroy either @d or @e */
         d->target = e;
         break;
     }
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index a8d182b5..2aa497a 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -235,7 +235,12 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t 
*alloc)
         ERROR_EXIT_DOM(port, d);
     chn = evtchn_from_port(d, port);
 
-    rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, alloc->remote_dom);
+    /*
+     * XXX: XSM_TARGET is not functional for emulator running in driver domain.
+     * See xsm_default_action for details. Probably XSM_DM_PRIV could work,
+     * but there is a risk to break other users.
+     */
+    rc = xsm_evtchn_unbound(XSM_HOOK, d, chn, alloc->remote_dom);
     if ( rc )
         goto out;
 
@@ -1218,7 +1223,12 @@ int alloc_unbound_xen_event_channel(
     port = rc;
     chn = evtchn_from_port(ld, port);
 
-    rc = xsm_evtchn_unbound(XSM_TARGET, ld, chn, remote_domid);
+    /*
+     * XXX: XSM_TARGET is not functional for emulator running in driver domain.
+     * See xsm_default_action for details. Probably XSM_DM_PRIV could work,
+     * but there is a risk to break other users.
+     */
+    rc = xsm_evtchn_unbound(XSM_HOOK, ld, chn, remote_domid);
     if ( rc )
         goto out;
 
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 0000477..8b306f6 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -1153,12 +1153,18 @@ static int acquire_resource(
         unsigned int i;
 
         /*
+         * XXX: Ugly hack for now to let emulator running in driver domain
+         * to succeeded in acquiring resource.
+         */
+#if 0
+        /*
          * FIXME: Until foreign pages inserted into the P2M are properly
          *        reference counted, it is unsafe to allow mapping of
          *        resource pages unless the caller is the hardware domain.
          */
         if ( !is_hardware_domain(currd) )
             return -EACCES;
+#endif
 
         if ( copy_from_guest(gfn_list, xmar.frame_list, xmar.nr_frames) )
             rc = -EFAULT;
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 317455a..c0813c0 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -139,13 +139,23 @@ static XSM_INLINE int xsm_domctl(XSM_DEFAULT_ARG struct 
domain *d, int cmd)
     XSM_ASSERT_ACTION(XSM_OTHER);
     switch ( cmd )
     {
+    /*
+     * XXX: Emulator running in driver domain tries to get vcpus num.
+     * Probably we could avoid that change by modifying emulator to not use
+     * domctl for getting vcpus num.
+     */
+    case XEN_DOMCTL_getdomaininfo:
+    /*
+     * XXX: XSM_DM_PRIV is not functional for emulator running in driver domain
+     * without setting a target in advance. See xsm_default_action for details.
+     */
+    case XEN_DOMCTL_set_target:
+        return xsm_default_action(XSM_HOOK, current->domain, d);
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_memory_mapping:
     case XEN_DOMCTL_bind_pt_irq:
     case XEN_DOMCTL_unbind_pt_irq:
         return xsm_default_action(XSM_DM_PRIV, current->domain, d);
-    case XEN_DOMCTL_getdomaininfo:
-        return xsm_default_action(XSM_XS_PRIV, current->domain, d);
     default:
         return xsm_default_action(XSM_PRIV, current->domain, d);
     }
@@ -275,7 +285,7 @@ static XSM_INLINE int xsm_claim_pages(XSM_DEFAULT_ARG 
struct domain *d)
 static XSM_INLINE int xsm_evtchn_unbound(XSM_DEFAULT_ARG struct domain *d, 
struct evtchn *chn,
                                          domid_t id2)
 {
-    XSM_ASSERT_ACTION(XSM_TARGET);
+    XSM_ASSERT_ACTION(XSM_HOOK);
     return xsm_default_action(action, current->domain, d);
 }
 
-- 
2.7.4




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.