]> xenbits.xensource.com Git - xen.git/commitdiff
hvm: Add HVM_PARAM_DM_DOMAIN to let ioreq events go to a stub domain
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 11 Apr 2008 16:19:07 +0000 (17:19 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 11 Apr 2008 16:19:07 +0000 (17:19 +0100)
instead of dom0.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/ioemu/hw/xen_machine_fv.c
xen/arch/ia64/vmx/vmx_hypercall.c
xen/arch/x86/hvm/hvm.c
xen/common/event_channel.c
xen/include/public/hvm/params.h

index 5fc9dda42f1c7f1de74b67f4745e5b67046e7b04..448a8fecf6b379e280957020b8f9774639dabaa6 100644 (file)
@@ -205,6 +205,7 @@ static void xen_init_fv(uint64_t ram_size, int vga_ram_size, char *boot_device,
     }
 #endif
 
+    xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN, DOMID_SELF);
     xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
     fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
     shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
index 97c8d5f990ed16d7c0560a0c249d39f502033481..84510d7b78d38e55f967f71483d457452f5a97da 100644 (file)
@@ -165,6 +165,11 @@ do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
                 iorp = &d->arch.hvm_domain.buf_pioreq;
                 rc = vmx_set_ioreq_page(d, iorp, a.value);
                 break;
+            case HVM_PARAM_DM_DOMAIN:
+                if (a.value == DOMID_SELF)
+                    a.value = current->domain->domain_id;
+                rc = a.value ? -EINVAL : 0; /* no stub domain support */
+                break;
             default:
                 /* nothing */
                 break;
index b0c674c67cbaa562904bd4cc42ebaeb9bb02ca1e..10f9f9e71e36a0f856ebf63333aa554274496306 100644 (file)
@@ -2187,13 +2187,16 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
 
         if ( op == HVMOP_set_param )
         {
+            rc = 0;
+
             switch ( a.index )
             {
             case HVM_PARAM_IOREQ_PFN:
                 iorp = &d->arch.hvm_domain.ioreq;
-                rc = hvm_set_ioreq_page(d, iorp, a.value);
+                if ( (rc = hvm_set_ioreq_page(d, iorp, a.value)) != 0 )
+                    break;
                 spin_lock(&iorp->lock);
-                if ( (rc == 0) && (iorp->va != NULL) )
+                if ( iorp->va != NULL )
                     /* Initialise evtchn port info if VCPUs already created. */
                     for_each_vcpu ( d, v )
                         get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
@@ -2208,19 +2211,19 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
                 hvm_latch_shinfo_size(d);
                 break;
             case HVM_PARAM_TIMER_MODE:
-                rc = -EINVAL;
                 if ( a.value > HVMPTM_one_missed_tick_pending )
-                    goto param_fail;
+                    rc = -EINVAL;
                 break;
             case HVM_PARAM_IDENT_PT:
                 rc = -EPERM;
-                if ( current->domain->domain_id != 0 )
-                    goto param_fail;
+                if ( !IS_PRIV(current->domain) )
+                    break;
 
                 rc = -EINVAL;
                 if ( d->arch.hvm_domain.params[a.index] != 0 )
-                    goto param_fail;
+                    break;
 
+                rc = 0;
                 if ( !paging_mode_hap(d) )
                     break;
 
@@ -2237,11 +2240,43 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
                     paging_update_cr3(v);
                 spin_unlock(&domctl_lock);
 
+                domain_unpause(d);
+                break;
+            case HVM_PARAM_DM_DOMAIN:
+                /* Privileged domains only, as we must domain_pause(d). */
+                rc = -EPERM;
+                if ( !IS_PRIV_FOR(current->domain, d) )
+                    break;
+
+                if ( a.value == DOMID_SELF )
+                    a.value = current->domain->domain_id;
+
+                rc = 0;
+                domain_pause(d); /* safe to change per-vcpu xen_port */
+                iorp = &d->arch.hvm_domain.ioreq;
+                for_each_vcpu ( d, v )
+                {
+                    int old_port, new_port;
+                    new_port = alloc_unbound_xen_event_channel(v, a.value);
+                    if ( new_port < 0 )
+                    {
+                        rc = new_port;
+                        break;
+                    }
+                    /* xchg() ensures that only we free_xen_event_channel() */
+                    old_port = xchg(&v->arch.hvm_vcpu.xen_port, new_port);
+                    free_xen_event_channel(v, old_port);
+                    spin_lock(&iorp->lock);
+                    if ( iorp->va != NULL )
+                        get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
+                    spin_unlock(&iorp->lock);
+                }
                 domain_unpause(d);
                 break;
             }
-            d->arch.hvm_domain.params[a.index] = a.value;
-            rc = 0;
+
+            if ( rc == 0 )
+                d->arch.hvm_domain.params[a.index] = a.value;
         }
         else
         {
index b385b54738cc0326a98c66fc9139ce4136fa0f5f..70b34fbd2f13ee32ab01c4ed9abf0711ef24bb3c 100644 (file)
@@ -109,9 +109,7 @@ static int get_free_port(struct domain *d)
         if ( xsm_alloc_security_evtchn(&chn[i]) )
         {
             for ( j = 0; j < i; j++ )
-            {
                 xsm_free_security_evtchn(&chn[j]);
-            }        
             xfree(chn);
             return -ENOMEM;
         }
@@ -971,9 +969,18 @@ void free_xen_event_channel(
     struct domain *d = local_vcpu->domain;
 
     spin_lock(&d->evtchn_lock);
+
+    if ( unlikely(d->is_dying) )
+    {
+        spin_unlock(&d->evtchn_lock);
+        return;
+    }
+
+    BUG_ON(!port_is_valid(d, port));
     chn = evtchn_from_port(d, port);
     BUG_ON(!chn->consumer_is_xen);
     chn->consumer_is_xen = 0;
+
     spin_unlock(&d->evtchn_lock);
 
     (void)__evtchn_close(d, port);
@@ -1035,6 +1042,7 @@ void evtchn_destroy(struct domain *d)
     {
         xsm_free_security_evtchn(d->evtchn[i]);
         xfree(d->evtchn[i]);
+        d->evtchn[i] = NULL;
     }
     spin_unlock(&d->evtchn_lock);
 }
index 554309f49b6e23225d5c8eb257413e438a5fba36..f222cbac1707dca383f5901f4c84fccc490e1580 100644 (file)
 
 /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
 #define HVM_PARAM_HPET_ENABLED 11
+
+/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
 #define HVM_PARAM_IDENT_PT     12
 
-#define HVM_NR_PARAMS          13
+/* Device Model domain, defaults to 0. */
+#define HVM_PARAM_DM_DOMAIN    13
+
+#define HVM_NR_PARAMS          14
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */