[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] ioreq: handle pending emulation racing with ioreq server destruction



commit f7039ee41b3d3448775a1623f230037fd0455104
Author:     Paul Durrant <pdurrant@xxxxxxxxxx>
AuthorDate: Tue Jun 9 12:56:24 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jun 9 12:56:24 2020 +0200

    ioreq: handle pending emulation racing with ioreq server destruction
    
    When an emulation request is initiated in hvm_send_ioreq() the guest vcpu is
    blocked on an event channel until that request is completed. If, however,
    the emulator is killed whilst that emulation is pending then the ioreq
    server may be destroyed. Thus when the vcpu is awoken the code in
    handle_hvm_io_completion() will find no pending request to wait for, but 
will
    leave the internal vcpu io_req.state set to IOREQ_READY and the vcpu 
shutdown
    deferall flag in place (because hvm_io_assist() will never be called). The
    emulation request is then completed anyway. This means that any subsequent 
call
    to hvmemul_do_io() will find an unexpected value in io_req.state and will
    return X86EMUL_UNHANDLEABLE, which in some cases will result in continuous
    re-tries.
    
    This patch fixes the issue by moving the setting of io_req.state and 
clearing
    of shutdown deferral (as will as MSI-X write completion) out of 
hvm_io_assist()
    and directly into handle_hvm_io_completion().
    
    Reported-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Release-acked-by: Paul Durrant <paul@xxxxxxx>
---
 xen/arch/x86/hvm/ioreq.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index c55c4bc4bc..724007016d 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -109,15 +109,7 @@ static void hvm_io_assist(struct hvm_ioreq_vcpu *sv, 
uint64_t data)
     ioreq_t *ioreq = &v->arch.hvm.hvm_io.io_req;
 
     if ( hvm_ioreq_needs_completion(ioreq) )
-    {
-        ioreq->state = STATE_IORESP_READY;
         ioreq->data = data;
-    }
-    else
-        ioreq->state = STATE_IOREQ_NONE;
-
-    msix_write_completion(v);
-    vcpu_end_shutdown_deferral(v);
 
     sv->pending = false;
 }
@@ -209,6 +201,12 @@ bool handle_hvm_io_completion(struct vcpu *v)
         }
     }
 
+    vio->io_req.state = hvm_ioreq_needs_completion(&vio->io_req) ?
+        STATE_IORESP_READY : STATE_IOREQ_NONE;
+
+    msix_write_completion(v);
+    vcpu_end_shutdown_deferral(v);
+
     io_completion = vio->io_completion;
     vio->io_completion = HVMIO_no_completion;
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.