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

[Xen-devel] [PATCH 02/10] vpci/msix: add lock to protect the list of MSIX regions



This is required in order to allow run-time removal of MSI-X regions.

No functional change.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Cc: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Julien Grall <julien.grall@xxxxxxx>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
Cc: Tim Deegan <tim@xxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c           |  1 +
 xen/drivers/vpci/msix.c          | 17 +++++++++++------
 xen/include/asm-x86/hvm/domain.h |  1 +
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 93092d2bb8..d29c824353 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -587,6 +587,7 @@ int hvm_domain_initialise(struct domain *d)
     spin_lock_init(&d->arch.hvm_domain.uc_lock);
     spin_lock_init(&d->arch.hvm_domain.write_map.lock);
     rwlock_init(&d->arch.hvm_domain.mmcfg_lock);
+    rwlock_init(&d->arch.hvm_domain.msix_lock);
     INIT_LIST_HEAD(&d->arch.hvm_domain.write_map.list);
     INIT_LIST_HEAD(&d->arch.hvm_domain.g2m_ioport_list);
     INIT_LIST_HEAD(&d->arch.hvm_domain.mmcfg_regions);
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index e28096329d..0b43f5eab9 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -148,10 +148,11 @@ static void control_write(const struct pci_dev *pdev, 
unsigned int reg,
         pci_conf_write16(pdev->seg, pdev->bus, slot, func, reg, val);
 }
 
-static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
+static struct vpci_msix *msix_find(struct domain *d, unsigned long addr)
 {
     struct vpci_msix *msix;
 
+    read_lock(&d->arch.hvm_domain.msix_lock);
     list_for_each_entry ( msix, &d->arch.hvm_domain.msix_tables, next )
     {
         const struct vpci_bar *bars = msix->pdev->vpci->header.bars;
@@ -160,8 +161,12 @@ static struct vpci_msix *msix_find(const struct domain *d, 
unsigned long addr)
         for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ )
             if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled &&
                  VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) )
+            {
+                read_unlock(&d->arch.hvm_domain.msix_lock);
                 return msix;
+            }
     }
+    read_unlock(&d->arch.hvm_domain.msix_lock);
 
     return NULL;
 }
@@ -196,8 +201,7 @@ static struct vpci_msix_entry *get_entry(struct vpci_msix 
*msix,
 static int msix_read(struct vcpu *v, unsigned long addr, unsigned int len,
                      unsigned long *data)
 {
-    const struct domain *d = v->domain;
-    struct vpci_msix *msix = msix_find(d, addr);
+    struct vpci_msix *msix = msix_find(v->domain, addr);
     const struct vpci_msix_entry *entry;
     unsigned int offset;
 
@@ -273,8 +277,7 @@ static int msix_read(struct vcpu *v, unsigned long addr, 
unsigned int len,
 static int msix_write(struct vcpu *v, unsigned long addr, unsigned int len,
                       unsigned long data)
 {
-    const struct domain *d = v->domain;
-    struct vpci_msix *msix = msix_find(d, addr);
+    struct vpci_msix *msix = msix_find(v->domain, addr);
     struct vpci_msix_entry *entry;
     unsigned int offset;
 
@@ -287,7 +290,7 @@ static int msix_write(struct vcpu *v, unsigned long addr, 
unsigned int len,
     if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) )
     {
         /* Ignore writes to PBA for DomUs, it's behavior is undefined. */
-        if ( is_hardware_domain(d) )
+        if ( is_hardware_domain(v->domain) )
         {
             switch ( len )
             {
@@ -441,7 +444,9 @@ static int init_msix(struct pci_dev *pdev)
     if ( list_empty(&d->arch.hvm_domain.msix_tables) )
         register_mmio_handler(d, &vpci_msix_table_ops);
 
+    write_lock(&d->arch.hvm_domain.msix_lock);
     list_add(&pdev->vpci->msix->next, &d->arch.hvm_domain.msix_tables);
+    write_unlock(&d->arch.hvm_domain.msix_lock);
 
     return 0;
 }
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 588595059d..181f6a2704 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -187,6 +187,7 @@ struct hvm_domain {
 
     /* List of MSI-X tables. */
     struct list_head msix_tables;
+    rwlock_t msix_lock;
 
     /* List of permanently write-mapped pages. */
     struct {
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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