WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] Fix buggy mask_base in saving/restori

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Fix buggy mask_base in saving/restoring MSI-X table during S3
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 02 Dec 2008 10:40:09 -0800
Delivery-date: Tue, 02 Dec 2008 10:39:52 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1228218887 0
# Node ID 63a878f8851b3b15c21e83ddda4aa36fe3bd9a80
# Parent  cdc6729dc7025594b902ef01795bfafd4c14ea3c
Fix buggy mask_base in saving/restoring MSI-X table during S3

Fix mask_base (actually MSI-X table base, copy name from native) to be
a virtual address rather than a physical address. And remove wrong
printk in pci_disable_msix.

Signed-off-by: Shan Haitao <haitao.shan@xxxxxxxxx>
---
 drivers/pci/msi-xen.c |   52 ++++++++++++++++++++++++--------------------------
 1 files changed, 25 insertions(+), 27 deletions(-)

diff -r cdc6729dc702 -r 63a878f8851b drivers/pci/msi-xen.c
--- a/drivers/pci/msi-xen.c     Fri Nov 28 13:41:38 2008 +0000
+++ b/drivers/pci/msi-xen.c     Tue Dec 02 11:54:47 2008 +0000
@@ -42,6 +42,8 @@ struct msi_dev_list {
        struct list_head list;
        spinlock_t pirq_list_lock;
        struct list_head pirq_list_head;
+       /* Used for saving/restoring MSI-X tables */
+       void __iomem *mask_base;
 };
 
 struct msi_pirq_entry {
@@ -50,7 +52,6 @@ struct msi_pirq_entry {
        int entry_nr;
 #ifdef CONFIG_PM
        /* PM save area for MSIX address/data */
-       void __iomem *mask_base;
        u32     address_hi_save;
        u32     address_lo_save;
        u32     data_save;
@@ -90,7 +91,7 @@ static struct msi_dev_list *get_msi_dev_
        return ret;
 }
 
-static int attach_pirq_entry(int pirq, int entry_nr, u64 table_base,
+static int attach_pirq_entry(int pirq, int entry_nr,
                              struct msi_dev_list *msi_dev_entry)
 {
        struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
@@ -100,9 +101,6 @@ static int attach_pirq_entry(int pirq, i
                return -ENOMEM;
        entry->pirq = pirq;
        entry->entry_nr = entry_nr;
-#ifdef COMFIG_PM
-       entry->mask_base = table_base;
-#endif
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
@@ -381,17 +379,24 @@ int pci_save_msix_state(struct pci_dev *
        unsigned long flags;
        struct msi_dev_list *msi_dev_entry;
        struct msi_pirq_entry *pirq_entry;
+       void __iomem *base;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
        if (pos <= 0 || dev->no_msi)
                return 0;
-
-       printk(KERN_CRIT "Saving MSIX cap\n");
 
        /* save the capability */
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        if (!(control & PCI_MSIX_FLAGS_ENABLE))
                return 0;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+       /* If we failed to map the MSI-X table at pci_enable_msix,
+        * We could not support saving them here.
+        */
+       if (!(base = msi_dev_entry->mask_base))
+               return -ENOMEM;
+
        save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
                GFP_KERNEL);
        if (!save_state) {
@@ -400,19 +405,12 @@ int pci_save_msix_state(struct pci_dev *
        }
        *((u16 *)&save_state->data[0]) = control;
 
-       msi_dev_entry = get_msi_dev_pirq_list(dev);
-
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                int j;
-               void __iomem *base;
 
                /* save the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-               printk(KERN_CRIT "Save msix table entry %d pirq %x base %p\n",
-                      j, pirq_entry->pirq, base);
-
                pirq_entry->address_lo_save =
                        readl(base + j * PCI_MSIX_ENTRY_SIZE +
                              PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -443,7 +441,6 @@ void pci_restore_msix_state(struct pci_d
        save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
        if (!save_state)
                return;
-       printk(KERN_CRIT "Restoring MSIX cap\n");
 
        save = *((u16 *)&save_state->data[0]);
        pci_remove_saved_cap(save_state);
@@ -454,15 +451,12 @@ void pci_restore_msix_state(struct pci_d
                return;
 
        msi_dev_entry = get_msi_dev_pirq_list(dev);
+       base = msi_dev_entry->mask_base;
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                /* route the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-
-               printk(KERN_CRIT "Restore msix table entry %d pirq %x base 
%p\n",
-                      j, pirq_entry->pirq, base);
                writel(pirq_entry->address_lo_save,
                        base + j * PCI_MSIX_ENTRY_SIZE +
                        PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -523,7 +517,8 @@ static int msix_capability_init(struct p
                                struct msix_entry *entries, int nvec)
 {
        u64 table_base;
-       int pirq, i, j, mapped, pos;
+       u16 control;
+       int pirq, i, j, mapped, pos, nr_entries;
        struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
        struct msi_pirq_entry *pirq_entry;
 
@@ -534,6 +529,12 @@ static int msix_capability_init(struct p
        table_base = find_table_base(dev, pos);
        if (!table_base)
                return -ENODEV;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       nr_entries = multi_msix_capable(control);
+       if (!msi_dev_entry->mask_base)
+               msi_dev_entry->mask_base = 
+                       ioremap_nocache(table_base, nr_entries * 
PCI_MSIX_ENTRY_SIZE);
 
        /* MSI-X Table Initialization */
        for (i = 0; i < nvec; i++) {
@@ -554,7 +555,7 @@ static int msix_capability_init(struct p
                pirq = msi_map_vector(dev, entries[i].entry, table_base);
                if (pirq < 0)
                        break;
-               attach_pirq_entry(pirq, entries[i].entry, table_base, 
msi_dev_entry);
+               attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
                (entries + i)->vector = pirq;
        }
 
@@ -739,7 +740,7 @@ int pci_enable_msix(struct pci_dev* dev,
                        if (mapped)
                                continue;
                        irq = evtchn_map_pirq(-1, entries[i].vector);
-                       attach_pirq_entry(irq, entries[i].entry, 0, 
msi_dev_entry);
+                       attach_pirq_entry(irq, entries[i].entry, msi_dev_entry);
                        entries[i].vector = irq;
                }
         return 0;
@@ -857,18 +858,15 @@ void msi_remove_pci_irq_vectors(struct p
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        if (!list_empty(&msi_dev_entry->pirq_list_head))
-       {
-               printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not 
freed \
-                      before acquire again.\n", dev->bus->number, 
PCI_SLOT(dev->devfn),
-                          PCI_FUNC(dev->devfn));
                list_for_each_entry_safe(pirq_entry, tmp,
                                         &msi_dev_entry->pirq_list_head, list) {
                        msi_unmap_pirq(dev, pirq_entry->pirq);
                        list_del(&pirq_entry->list);
                        kfree(pirq_entry);
                }
-       }
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+       iounmap(msi_dev_entry->mask_base);
+       msi_dev_entry->mask_base = NULL;
        dev->irq = dev->irq_old;
 }
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Fix buggy mask_base in saving/restoring MSI-X table during S3, Xen patchbot-linux-2.6.18-xen <=