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

[Xen-changelog] [xen stable-4.3] x86: properly handle MSI-X unmask operation from guests



commit 3014b79dcd8d6c9e75bf4918fb916bf89954c779
Author:     Feng Wu <feng.wu@xxxxxxxxx>
AuthorDate: Mon Dec 9 14:29:39 2013 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Dec 9 14:29:39 2013 +0100

    x86: properly handle MSI-X unmask operation from guests
    
    For a pass-through device with MSI-x capability, when guest tries
    to unmask the MSI-x interrupt for the passed through device, xen
    doesn't clear the mask bit for MSI-x in hardware in the following
    scenario, which will cause network disconnection:
    
    1. Guest masks the MSI-x interrupt
    2. Guest updates the address and data for it
    3. Guest unmasks the MSI-x interrupt (This is the problematic step)
    
    In the step #3 above, Xen doesn't handle it well. When guest tries
    to unmask MSI-X interrupt, it traps to Xen, Xen just returns to Qemu
    if it notices that address or data has been modified by guest before,
    then Qemu will update Xen with the latest value of address/data by
    hypercall. However, in this whole process, the MSI-X interrupt unmask
    operation is missing, which means Xen doesn't clear the mask bit in
    hardware for the MSI-X interrupt, so it remains disabled, that is why
    it loses the network connection.
    
    This patch fixes this issue.
    
    Signed-off-by: Feng Wu <feng.wu@xxxxxxxxx>
    
    Only latch the address if the guest really is unmasking the entry.
    
    Clean up the entire change.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    master commit: 74fd0036deb585a139b63b26db025805ecedc37a
    master date: 2013-11-27 15:15:43 +0100
---
 xen/arch/x86/hvm/io.c          |    3 +++
 xen/arch/x86/hvm/vmsi.c        |   16 ++++++++++++++++
 xen/include/asm-x86/hvm/io.h   |    1 +
 xen/include/asm-x86/hvm/vcpu.h |    2 ++
 4 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 53acd01..95458ea 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -298,7 +298,10 @@ void hvm_io_assist(void)
     }
 
     if ( p->state == STATE_IOREQ_NONE )
+    {
+        msix_write_completion(curr);
         vcpu_end_shutdown_deferral(curr);
+    }
 }
 
 static int dpci_ioport_read(uint32_t mport, ioreq_t *p)
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index e8aa61c..2bda25c 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -293,7 +293,11 @@ static int msixtbl_write(struct vcpu *v, unsigned long 
address,
 
     /* exit to device model if address/data has been modified */
     if ( test_and_clear_bit(nr_entry, &entry->table_flags) )
+    {
+        if ( !(val & PCI_MSIX_VECTOR_BITMASK) )
+            v->arch.hvm_vcpu.hvm_io.msix_unmask_address = address;
         goto out;
+    }
 
     virt = msixtbl_addr_to_virt(entry, address);
     if ( !virt )
@@ -528,3 +532,15 @@ void msixtbl_pt_cleanup(struct domain *d)
     spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
     local_irq_restore(flags);
 }
+
+void msix_write_completion(struct vcpu *v)
+{
+    unsigned long ctrl_address = v->arch.hvm_vcpu.hvm_io.msix_unmask_address;
+
+    if ( !ctrl_address )
+        return;
+
+    v->arch.hvm_vcpu.hvm_io.msix_unmask_address = 0;
+    if ( msixtbl_write(v, ctrl_address, 4, 0) != X86EMUL_OKAY )
+        gdprintk(XENLOG_WARNING, "MSI-X write completion failure\n");
+}
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index b0718b8..62aa2f6 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -124,6 +124,7 @@ void hvm_interrupt_post(struct vcpu *v, int vector, int 
type);
 void hvm_io_assist(void);
 void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
                   union vioapic_redir_entry *ent);
+void msix_write_completion(struct vcpu *);
 
 struct hvm_hw_stdvga {
     uint8_t sr_index;
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index e8b8cd7..caf5f9a 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -66,6 +66,8 @@ struct hvm_vcpu_io {
     /* We may write up to m256 as a number of device-model transactions. */
     unsigned int mmio_large_write_bytes;
     paddr_t mmio_large_write_pa;
+
+    unsigned long msix_unmask_address;
 };
 
 #define VMCX_EADDR    (~0ULL)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.3

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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