[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] evtchn/sched: reject poll requests for unusable ports
commit d4bfa0c78f48e6562667f8e9c898a548be633d77 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Sep 30 09:10:46 2020 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Sep 30 09:10:46 2020 +0200 evtchn/sched: reject poll requests for unusable ports Before and after XSA-342 there has been an asymmetry in how not really usable ports get treated in do_poll(): Ones beyond a certain boundary (max_evtchns originally, valid_evtchns subsequently) did get refused with -EINVAL, while lower ones were accepted despite there potentially being no way to wake the vCPU again from its polling state. Arrange to also honor evtchn_usable() output in the decision. Requested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx> Reviewed-by: Dario Faggioli <dfaggioli@xxxxxxxx> Reviewed-by: Paul Durrant <paul@xxxxxxx> --- xen/common/sched/core.c | 12 ++++++------ xen/include/xen/event.h | 32 +++++++++++++++++++------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c index ab94d2ec3a..ed973e90ec 100644 --- a/xen/common/sched/core.c +++ b/xen/common/sched/core.c @@ -1427,13 +1427,13 @@ static long do_poll(struct sched_poll *sched_poll) if ( __copy_from_guest_offset(&port, sched_poll->ports, i, 1) ) goto out; - rc = -EINVAL; - if ( !port_is_valid(d, port) ) - goto out; - - rc = 0; - if ( evtchn_port_is_pending(d, port) ) + rc = evtchn_port_poll(d, port); + if ( rc ) + { + if ( rc > 0 ) + rc = 0; goto out; + } } if ( sched_poll->nr_ports == 1 ) diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index fa93a3684a..509d3ae861 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -240,19 +240,6 @@ static inline bool evtchn_is_pending(const struct domain *d, return evtchn_usable(evtchn) && d->evtchn_port_ops->is_pending(d, evtchn); } -static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port) -{ - struct evtchn *evtchn = evtchn_from_port(d, port); - bool rc; - unsigned long flags; - - spin_lock_irqsave(&evtchn->lock, flags); - rc = evtchn_is_pending(d, evtchn); - spin_unlock_irqrestore(&evtchn->lock, flags); - - return rc; -} - static inline bool evtchn_is_masked(const struct domain *d, const struct evtchn *evtchn) { @@ -279,6 +266,25 @@ static inline bool evtchn_is_busy(const struct domain *d, d->evtchn_port_ops->is_busy(d, evtchn); } +/* Returns negative errno, zero for not pending, or positive for pending. */ +static inline int evtchn_port_poll(struct domain *d, evtchn_port_t port) +{ + int rc = -EINVAL; + + if ( port_is_valid(d, port) ) + { + struct evtchn *evtchn = evtchn_from_port(d, port); + unsigned long flags; + + spin_lock_irqsave(&evtchn->lock, flags); + if ( evtchn_usable(evtchn) ) + rc = evtchn_is_pending(d, evtchn); + spin_unlock_irqrestore(&evtchn->lock, flags); + } + + return rc; +} + static inline int evtchn_port_set_priority(struct domain *d, struct evtchn *evtchn, unsigned int priority) -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |