All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] xen, libxc: init msix addr/data with value from qemu via hypercall
@ 2013-05-08  8:17 Zhenzhong Duan
  2013-05-08  9:39 ` Jan Beulich
  0 siblings, 1 reply; 12+ messages in thread
From: Zhenzhong Duan @ 2013-05-08  8:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Chien Yen, Feng Jin, Yuval Shaia, Konrad Rzeszutek Wilk

Accelerated msix entry is initialized to zero when msixtbl_pt_register is
called. This doesn't match the value from qemu side, although pirq may already
be mapped and binded in qemu side. Kernel will get wrong value when reading
msix info.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
Tested-by: Yuval Shaia <yuval.shaia@oracle.com>
---
 tools/libxc/xc_domain.c      |    7 ++++++-
 tools/libxc/xenctrl.h        |    4 +++-
 xen/arch/x86/hvm/vmsi.c      |   13 ++++++++++++-
 xen/drivers/passthrough/io.c |    3 ++-
 xen/include/public/domctl.h  |    2 ++
 xen/include/xen/pci.h        |    3 ++-
 6 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index bb71cca..f6fc8e4 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1339,7 +1339,9 @@ int xc_domain_update_msi_irq(
     uint32_t gvec,
     uint32_t pirq,
     uint32_t gflags,
-    uint64_t gtable)
+    uint64_t gtable,
+    uint16_t entry_nr,
+    uint32_t msi_ad[3])
 {
     int rc;
     xen_domctl_bind_pt_irq_t *bind;
@@ -1356,6 +1358,9 @@ int xc_domain_update_msi_irq(
     bind->u.msi.gvec = gvec;
     bind->u.msi.gflags = gflags;
     bind->u.msi.gtable = gtable;
+    bind->u.msi.entry_nr = entry_nr;
+    if ( gtable )
+        memcpy(bind->u.msi.msi_ad, msi_ad, sizeof(uint32_t[3]));
 
     rc = do_domctl(xch, &domctl);
     return rc;
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 54a2d5a..f292443 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -1749,7 +1749,9 @@ int xc_domain_update_msi_irq(
     uint32_t gvec,
     uint32_t pirq,
     uint32_t gflags,
-    uint64_t gtable);
+    uint64_t gtable,
+    uint16_t entry_nr,
+    uint32_t msi_ad[3]);
 
 int xc_domain_unbind_msi_irq(xc_interface *xch,
                              uint32_t domid,
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index 36de312..06ea324 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -168,6 +168,7 @@ struct msixtbl_entry
     struct { 
         uint32_t msi_ad[3];	/* Shadow of address low, high and data */
     } gentries[MAX_MSIX_ACC_ENTRIES];
+    unsigned long table_shadow[BITS_TO_LONGS(MAX_MSIX_ACC_ENTRIES)];
     struct rcu_head rcu;
 };
 
@@ -229,6 +230,9 @@ static int msixtbl_read(
         nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
         if ( nr_entry >= MAX_MSIX_ACC_ENTRIES )
             goto out;
+        if( !test_bit(nr_entry, entry->table_shadow) )
+            goto out;
+
         index = offset / sizeof(uint32_t);
         *pval = entry->gentries[nr_entry].msi_ad[index];
     }
@@ -361,7 +365,8 @@ static void del_msixtbl_entry(struct msixtbl_entry *entry)
     call_rcu(&entry->rcu, free_msixtbl_entry);
 }
 
-int msixtbl_pt_register(struct domain *d, struct pirq *pirq, uint64_t gtable)
+int msixtbl_pt_register(struct domain *d, struct pirq *pirq, uint64_t gtable,
+                        uint16_t entry_nr, uint32_t msi_ad[3])
 {
     struct irq_desc *irq_desc;
     struct msi_desc *msi_desc;
@@ -408,6 +413,12 @@ int msixtbl_pt_register(struct domain *d, struct pirq *pirq, uint64_t gtable)
 
 found:
     atomic_inc(&entry->refcnt);
+
+    if( entry_nr < MAX_MSIX_ACC_ENTRIES ) {
+        memcpy(entry->gentries[entry_nr].msi_ad, msi_ad, sizeof(uint32_t[3]));
+        set_bit(entry_nr, entry->table_shadow);
+    }
+
     spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
     r = 0;
 
diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c
index 13002c0..17cb8c2 100644
--- a/xen/drivers/passthrough/io.c
+++ b/xen/drivers/passthrough/io.c
@@ -153,7 +153,8 @@ int pt_irq_create_bind(
             rc = pirq_guest_bind(d->vcpu[0], info, 0);
             if ( rc == 0 && pt_irq_bind->u.msi.gtable )
             {
-                rc = msixtbl_pt_register(d, info, pt_irq_bind->u.msi.gtable);
+                rc = msixtbl_pt_register(d, info, pt_irq_bind->u.msi.gtable,
+                                         pt_irq_bind->u.msi.entry_nr, pt_irq_bind->u.msi.msi_ad);
                 if ( unlikely(rc) )
                     pirq_guest_unbind(d, info);
             }
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 4c5b2bb..4b160a0 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -504,6 +504,8 @@ struct xen_domctl_bind_pt_irq {
             uint8_t gvec;
             uint32_t gflags;
             uint64_aligned_t gtable;
+            uint16_t entry_nr;
+            uint32_t msi_ad[3];
         } msi;
     } u;
 };
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index ca72a99..d8e22a8 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -151,7 +151,8 @@ int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap);
 int pci_find_ext_capability(int seg, int bus, int devfn, int cap);
 
 struct pirq;
-int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable);
+int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable,
+                        uint16_t entry_nr, uint32_t msi_ad[3]);
 void msixtbl_pt_unregister(struct domain *, struct pirq *);
 void msixtbl_pt_cleanup(struct domain *d);
 
-- 
1.7.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-05-10 19:03 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-08  8:17 [PATCH 1/2] xen, libxc: init msix addr/data with value from qemu via hypercall Zhenzhong Duan
2013-05-08  9:39 ` Jan Beulich
2013-05-08 10:00   ` Zhenzhong Duan
2013-05-08 12:03     ` Jan Beulich
2013-05-09  3:02       ` Zhenzhong Duan
2013-05-09 19:05         ` Jan Beulich
2013-05-10  2:49           ` Zhenzhong Duan
2013-05-10  6:37             ` Jan Beulich
2013-05-10  7:39               ` Zhenzhong Duan
2013-05-10  7:55                 ` Jan Beulich
2013-05-10  8:22                   ` Zhenzhong Duan
2013-05-10 19:03                   ` Is: Telling QEMU to re-use PIRQ value Was: " Konrad Rzeszutek Wilk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.