# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1207930747 -3600
# Node ID 9e4c5b7e5aa6dd209d932a215e6321ef6cb91aa4
# Parent d2010614d9f1cfa8b7accc9c324cb1ef49edf1e2
hvm: Add HVM_PARAM_DM_DOMAIN to let ioreq events go to a stub domain
instead of dom0.
Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
tools/ioemu/hw/xen_machine_fv.c | 1
xen/arch/ia64/vmx/vmx_hypercall.c | 5 +++
xen/arch/x86/hvm/hvm.c | 55 +++++++++++++++++++++++++++++++-------
xen/common/event_channel.c | 12 ++++++--
xen/include/public/hvm/params.h | 7 ++++
5 files changed, 67 insertions(+), 13 deletions(-)
diff -r d2010614d9f1 -r 9e4c5b7e5aa6 tools/ioemu/hw/xen_machine_fv.c
--- a/tools/ioemu/hw/xen_machine_fv.c Fri Apr 11 15:55:42 2008 +0100
+++ b/tools/ioemu/hw/xen_machine_fv.c Fri Apr 11 17:19:07 2008 +0100
@@ -205,6 +205,7 @@ static void xen_init_fv(uint64_t ram_siz
}
#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,
diff -r d2010614d9f1 -r 9e4c5b7e5aa6 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Fri Apr 11 15:55:42 2008 +0100
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Fri Apr 11 17:19:07 2008 +0100
@@ -165,6 +165,11 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
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;
diff -r d2010614d9f1 -r 9e4c5b7e5aa6 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Apr 11 15:55:42 2008 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri Apr 11 17:19:07 2008 +0100
@@ -2187,13 +2187,16 @@ long do_hvm_op(unsigned long op, XEN_GUE
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_GUE
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;
@@ -2239,9 +2242,41 @@ long do_hvm_op(unsigned long op, XEN_GUE
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
{
diff -r d2010614d9f1 -r 9e4c5b7e5aa6 xen/common/event_channel.c
--- a/xen/common/event_channel.c Fri Apr 11 15:55:42 2008 +0100
+++ b/xen/common/event_channel.c Fri Apr 11 17:19:07 2008 +0100
@@ -109,9 +109,7 @@ static int get_free_port(struct domain *
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);
}
diff -r d2010614d9f1 -r 9e4c5b7e5aa6 xen/include/public/hvm/params.h
--- a/xen/include/public/hvm/params.h Fri Apr 11 15:55:42 2008 +0100
+++ b/xen/include/public/hvm/params.h Fri Apr 11 17:19:07 2008 +0100
@@ -83,8 +83,13 @@
/* 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__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|