do_poll takes sched_poll* as parameter, but that's actually in guest memory
(so it's more a guest handle). Split its copy from/to guest logic from
the main logic, so that we have a separate vcpu_poll which takes the sched_poll
parameters directly.

Signed-off-by: Teddy Astie <teddy.as...@vates.tech>
---
 xen/common/sched/core.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 13fdf57e57..b2c784c60e 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -1437,21 +1437,13 @@ static void vcpu_block_enable_events(void)
     vcpu_block();
 }
 
-static long do_poll(const struct sched_poll *sched_poll)
+static long vcpu_poll(unsigned int nr_ports, uint64_t timeout, evtchn_port_t 
*ports)
 {
     struct vcpu   *v = current;
     struct domain *d = v->domain;
-    evtchn_port_t  port = 0;
     long           rc;
     unsigned int   i;
 
-    /* Fairly arbitrary limit. */
-    if ( sched_poll->nr_ports > 128 )
-        return -EINVAL;
-
-    if ( !guest_handle_okay(sched_poll->ports, sched_poll->nr_ports) )
-        return -EFAULT;
-
     set_bit(_VPF_blocked, &v->pause_flags);
     v->poll_evtchn = -1;
     set_bit(v->vcpu_id, d->poll_mask);
@@ -1478,13 +1470,9 @@ static long do_poll(const struct sched_poll *sched_poll)
     if ( local_events_need_delivery() )
         goto out;
 
-    for ( i = 0; i < sched_poll->nr_ports; i++ )
+    for ( i = 0; i < nr_ports; i++ )
     {
-        rc = -EFAULT;
-        if ( __copy_from_guest_offset(&port, sched_poll->ports, i, 1) )
-            goto out;
-
-        rc = evtchn_port_poll(d, port);
+        rc = evtchn_port_poll(d, ports[i]);
         if ( rc )
         {
             if ( rc > 0 )
@@ -1493,11 +1481,11 @@ static long do_poll(const struct sched_poll *sched_poll)
         }
     }
 
-    if ( sched_poll->nr_ports == 1 )
-        v->poll_evtchn = port;
+    if ( nr_ports == 1 )
+        v->poll_evtchn = ports[0];
 
-    if ( sched_poll->timeout != 0 )
-        set_timer(&v->poll_timer, sched_poll->timeout);
+    if ( timeout != 0 )
+        set_timer(&v->poll_timer, timeout);
 
     TRACE_TIME(TRC_SCHED_BLOCK, d->domain_id, v->vcpu_id);
     raise_softirq(SCHEDULE_SOFTIRQ);
@@ -1511,6 +1499,20 @@ static long do_poll(const struct sched_poll *sched_poll)
     return rc;
 }
 
+static long do_poll(struct sched_poll *sched_poll)
+{
+    evtchn_port_t ports[128];
+
+    /* Fairly arbitrary limit */
+    if ( sched_poll->nr_ports > 128 )
+        return -EINVAL;
+
+    if ( copy_from_guest(ports, sched_poll->ports, sched_poll->nr_ports) )
+        return -EFAULT;
+
+    return vcpu_poll(sched_poll->nr_ports, sched_poll->timeout, ports);
+}
+
 /* Voluntarily yield the processor for this allocation. */
 long vcpu_yield(void)
 {
-- 
2.50.1



Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech


Reply via email to