|
[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 |