@@ -21,6 +21,7 @@
#include <xen/hypercall.h>
#include <xen/init.h>
#include <xen/iocap.h>
+#include <xen/ioreq.h>
#include <xen/irq.h>
#include <xen/lib.h>
#include <xen/mem_access.h>
@@ -2269,12 +2270,23 @@ static void check_for_pcpu_work(void)
* Process pending work for the vCPU. Any call should be fast or
* implement preemption.
*/
-static void check_for_vcpu_work(void)
+static bool check_for_vcpu_work(void)
{
struct vcpu *v = current;
+#ifdef CONFIG_IOREQ_SERVER
+ bool handled;
+
+ local_irq_enable();
+ handled = vcpu_ioreq_handle_completion(v);
+ local_irq_disable();
+
+ if ( !handled )
+ return true;
+#endif
+
if ( likely(!v->arch.need_flush_to_ram) )
- return;
+ return false;
/*
* Give a chance for the pCPU to process work before handling the vCPU
@@ -2285,6 +2297,8 @@ static void check_for_vcpu_work(void)
local_irq_enable();
p2m_flush_vm(v);
local_irq_disable();
+
+ return false;
}
/*
@@ -2297,7 +2311,13 @@ void leave_hypervisor_to_guest(void)
{
local_irq_disable();
- check_for_vcpu_work();
+ /*
+ * check_for_vcpu_work() may return true if there are more work to before
+ * the vCPU can safely resume. This gives us an opportunity to deschedule
+ * the vCPU if needed.
+ */
+ while ( check_for_vcpu_work() )
+ check_for_pcpu_work();
check_for_pcpu_work();
vgic_sync_to_lrs();