[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC 1/4] xen: evtchn: make evtchn_reset() ready for soft reset
At 15:35 +0200 on 03 Jun (1433345719), Vitaly Kuznetsov wrote: > We need to close all event channel so the domain performing soft reset > will be able to open them back. Interdomain channels are, however, > special. We need to keep track of who opened it as in (the most common) > case it was opened by the control domain we won't be able (and allowed) to > re-establish it. I'm not sure I understand -- can you give an example of what this is avoiding? I would have thought that the kexec'ing VM needs to tear down _all_ its connections and then restart the ones it wantrs in the new OS. Cheers, Tim. > Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> > --- > xen/common/event_channel.c | 52 > +++++++++++++++++++++++++++------------------- > xen/include/xen/event.h | 3 +++ > xen/include/xen/sched.h | 1 + > 3 files changed, 35 insertions(+), 21 deletions(-) > > diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c > index fae242d..3204c74 100644 > --- a/xen/common/event_channel.c > +++ b/xen/common/event_channel.c > @@ -274,11 +274,13 @@ static long > evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) > > lchn->u.interdomain.remote_dom = rd; > lchn->u.interdomain.remote_port = rport; > + lchn->u.interdomain.opened_by = current->domain; > lchn->state = ECS_INTERDOMAIN; > evtchn_port_init(ld, lchn); > > rchn->u.interdomain.remote_dom = ld; > rchn->u.interdomain.remote_port = lport; > + rchn->u.interdomain.opened_by = current->domain; > rchn->state = ECS_INTERDOMAIN; > > /* > @@ -933,26 +935,30 @@ int evtchn_unmask(unsigned int port) > } > > > -static long evtchn_reset(evtchn_reset_t *r) > +void evtchn_reset(struct domain *d, bool_t soft_reset) > { > - domid_t dom = r->dom; > - struct domain *d; > - int i, rc; > - > - d = rcu_lock_domain_by_any_id(dom); > - if ( d == NULL ) > - return -ESRCH; > - > - rc = xsm_evtchn_reset(XSM_TARGET, current->domain, d); > - if ( rc ) > - goto out; > + int i; > + struct evtchn *chn; > > + /* > + * ECS_INTERDOMAIN channels with port number suitable for the 2-level ABI > + * opened by other domains should remain opened as the domain doing soft > + * reset won't be able to reopen them. > + * __evtchn_close() also leaves consumer_is_xen() channels open. > + */ > for ( i = 0; port_is_valid(d, i); i++ ) > + { > + chn = evtchn_from_port(d, i); > + if ( !soft_reset || > + i >= (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d)) || > + chn->state != ECS_INTERDOMAIN || > + chn->u.interdomain.opened_by == d ) > (void)__evtchn_close(d, i); > + } > > spin_lock(&d->event_lock); > > - if ( (dom == DOMID_SELF) && d->evtchn_fifo ) > + if ( (d == current->domain) && d->evtchn_fifo ) > { > /* > * Guest domain called EVTCHNOP_reset with DOMID_SELF, destroying > @@ -964,13 +970,6 @@ static long evtchn_reset(evtchn_reset_t *r) > } > > spin_unlock(&d->event_lock); > - > - rc = 0; > - > -out: > - rcu_unlock_domain(d); > - > - return rc; > } > > static long evtchn_set_priority(const struct evtchn_set_priority > *set_priority) > @@ -1097,9 +1096,20 @@ long do_event_channel_op(int cmd, > XEN_GUEST_HANDLE_PARAM(void) arg) > > case EVTCHNOP_reset: { > struct evtchn_reset reset; > + struct domain *d; > + > if ( copy_from_guest(&reset, arg, 1) != 0 ) > return -EFAULT; > - rc = evtchn_reset(&reset); > + > + d = rcu_lock_domain_by_any_id(reset.dom); > + if ( d == NULL ) > + return -ESRCH; > + > + rc = xsm_evtchn_reset(XSM_TARGET, current->domain, d); > + if ( !rc ) > + evtchn_reset(d, 0); > + > + rcu_unlock_domain(d); > break; > } > > diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h > index 690f865..d0479a6 100644 > --- a/xen/include/xen/event.h > +++ b/xen/include/xen/event.h > @@ -130,6 +130,9 @@ void evtchn_check_pollers(struct domain *d, unsigned int > port); > > void evtchn_2l_init(struct domain *d); > > +/* Close all event channels and reset to 2-level ABI */ > +void evtchn_reset(struct domain *d, bool_t soft_reset); > + > /* > * Low-level event channel port ops. > */ > diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h > index 80c6f62..13b6b86 100644 > --- a/xen/include/xen/sched.h > +++ b/xen/include/xen/sched.h > @@ -98,6 +98,7 @@ struct evtchn > struct { > evtchn_port_t remote_port; > struct domain *remote_dom; > + struct domain *opened_by; > } interdomain; /* state == ECS_INTERDOMAIN */ > struct { > u32 irq; > -- > 1.9.3 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |