All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Dom0-kernel: Fix buggy mask_base in saving/restoring MSI-X table during S3
@ 2008-11-28  4:21 Shan, Haitao
  2008-11-28  4:37 ` Shan, Haitao
  0 siblings, 1 reply; 7+ messages in thread
From: Shan, Haitao @ 2008-11-28  4:21 UTC (permalink / raw)
  To: 'Keir Fraser', 'Jan Beulich'
  Cc: 'xen-devel@lists.xensource.com'

[-- Attachment #1: Type: text/plain, Size: 423 bytes --]

Hi, Keir, Jan,

This patch is a bugfix pointed by Jan. 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.

Jan, the error message you saw is wrong output from kernel's MSI code. Really sorry for my dirty code there.

Could you please review the patch and give me feedback?

Best Regards
Haitao Shan

[-- Attachment #2: fix_msix_table_base.patch --]
[-- Type: application/octet-stream, Size: 4296 bytes --]

diff -r 0b859c9516ba drivers/pci/msi-xen.c
--- a/drivers/pci/msi-xen.c	Wed Nov 26 11:13:49 2008 +0000
+++ b/drivers/pci/msi-xen.c	Thu Nov 27 11:38:25 2008 +0800
@@ -42,6 +42,8 @@
 	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 @@
 	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 @@
 	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 @@
 		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,6 +379,7 @@
 	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)
@@ -401,14 +400,13 @@
 	*((u16 *)&save_state->data[0]) = control;
 
 	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) {
 		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);
@@ -454,11 +452,11 @@
 		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",
@@ -523,7 +521,8 @@
 				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 +533,12 @@
 	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 +559,7 @@
 		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 +744,7 @@
 			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 +862,15 @@
 
 	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;
 }
 

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

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

end of thread, other threads:[~2008-11-28 15:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-28  4:21 [PATCH] Dom0-kernel: Fix buggy mask_base in saving/restoring MSI-X table during S3 Shan, Haitao
2008-11-28  4:37 ` Shan, Haitao
2008-11-28  7:56   ` [PATCH] Dom0-kernel: Fix buggy mask_base insaving/restoring " Jan Beulich
2008-11-28  8:14     ` Shan, Haitao
2008-11-28  8:50       ` Jan Beulich
2008-11-28 12:22         ` Shan, Haitao
2008-11-28 15:47           ` [PATCH] Dom0-kernel: Fix buggy mask_base in saving/restoring MSI-X table during S3 - Version 3 Shan, Haitao

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.