[kernel] r15287 - in dists/lenny/linux-2.6/debian: . patches/features/all/xen patches/series

Ian Campbell ijc-guest at alioth.debian.org
Sat Feb 27 20:49:22 UTC 2010


Author: ijc-guest
Date: Sat Feb 27 20:49:18 2010
New Revision: 15287

Log:
Use correct form of PHYSDEVOP_map_pirq hypercall to prevent crash when trying
to use MSI in domain 0 (Closes: #571603)

Added:
   dists/lenny/linux-2.6/debian/patches/features/all/xen/xen-fix-msi-hypercall.patch
Modified:
   dists/lenny/linux-2.6/debian/changelog
   dists/lenny/linux-2.6/debian/patches/series/22-extra

Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog	Sat Feb 27 20:49:03 2010	(r15286)
+++ dists/lenny/linux-2.6/debian/changelog	Sat Feb 27 20:49:18 2010	(r15287)
@@ -38,6 +38,10 @@
   [ dann frazier ]
   * Add be2net driver (Closes: #570428)
 
+  [ Ian Campbell ]
+  * [xen/x86] Use correct form of PHYSDEVOP_map_pirq hypercall to prevent crash
+    when trying to use MSI in domain 0 (Closes: #571603)
+
  -- maximilian attems <maks at debian.org>  Mon, 28 Dec 2009 23:44:19 +0100
 
 linux-2.6 (2.6.26-21lenny3) stable-security; urgency=high

Added: dists/lenny/linux-2.6/debian/patches/features/all/xen/xen-fix-msi-hypercall.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/features/all/xen/xen-fix-msi-hypercall.patch	Sat Feb 27 20:49:18 2010	(r15287)
@@ -0,0 +1,165 @@
+diff -u -r build_i386_xen_686/drivers/pci/msi-xen.c build_i386_xen_686-fix/drivers/pci/msi-xen.c
+--- build_i386_xen_686/drivers/pci/msi-xen.c	2010-02-25 12:23:43.000000000 +0000
++++ build_i386_xen_686-fix/drivers/pci/msi-xen.c	2010-02-25 13:08:16.000000000 +0000
+@@ -238,11 +238,27 @@
+ 	return 0;
+ }
+ 
++static u64 find_table_base(struct pci_dev *dev, int pos)
++{
++	u8 bar;
++	u32 reg;
++	unsigned long flags;
++
++ 	pci_read_config_dword(dev, msix_table_offset_reg(pos), &reg);
++	bar = reg & PCI_MSIX_FLAGS_BIRMASK;
++
++	flags = pci_resource_flags(dev, bar);
++	if (flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET | IORESOURCE_BUSY))
++		return 0;
++
++	return pci_resource_start(dev, bar);
++}
++
+ /*
+  * Protected by msi_lock
+  */
+ static int msi_map_pirq_to_vector(struct pci_dev *dev, int pirq,
+-                                  int entry_nr, int msi)
++				  int entry_nr, u64 table_base)
+ {
+ 	struct physdev_map_pirq map_irq;
+ 	int rc;
+@@ -254,10 +270,10 @@
+ 	map_irq.type = MAP_PIRQ_TYPE_MSI;
+ 	map_irq.index = -1;
+ 	map_irq.pirq = pirq;
+-    map_irq.msi_info.bus = dev->bus->number;
+-    map_irq.msi_info.devfn = dev->devfn;
+-	map_irq.msi_info.entry_nr = entry_nr;
+-    map_irq.msi_info.msi = msi;
++	map_irq.bus = dev->bus->number;
++	map_irq.devfn = dev->devfn;
++	map_irq.entry_nr = entry_nr;
++	map_irq.table_base = table_base;
+ 
+ 	if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq)))
+ 		printk(KERN_WARNING "map irq failed\n");
+@@ -268,9 +284,9 @@
+ 	return map_irq.pirq;
+ }
+ 
+-static int msi_map_vector(struct pci_dev *dev, int entry_nr, int msi)
++static int msi_map_vector(struct pci_dev *dev, int entry_nr, u64 table_base)
+ {
+-	return msi_map_pirq_to_vector(dev, -1, entry_nr, msi);
++	return msi_map_pirq_to_vector(dev, -1, entry_nr, table_base);
+ }
+ 
+ static void pci_intx_for_msi(struct pci_dev *dev, int enable)
+@@ -286,7 +302,7 @@
+ 	if (!dev->msi_enabled)
+ 		return;
+ 
+-	pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 1);
++	pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 0);
+ 	if (pirq < 0)
+ 		return;
+ 
+@@ -296,19 +312,29 @@
+ 
+ static void __pci_restore_msix_state(struct pci_dev *dev)
+ {
++        int pos;
+ 	unsigned long flags;
++	u64 table_base;
+ 	struct msi_dev_list *msi_dev_entry;
+ 	struct msi_pirq_entry *pirq_entry, *tmp;
+ 
++	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++	if (pos <= 0)
++	  return;
++
+ 	if (!dev->msix_enabled)
+ 		return;
+ 
+ 	msi_dev_entry = get_msi_dev_pirq_list(dev);
++	table_base = find_table_base(dev, pos);
++	if (!table_base)
++		return;
+ 
+ 	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+ 	list_for_each_entry_safe(pirq_entry, tmp,
+-							 &msi_dev_entry->pirq_list_head, list)
+-		msi_map_pirq_to_vector(dev, pirq_entry->pirq, pirq_entry->entry_nr, 0);
++				 &msi_dev_entry->pirq_list_head, list)
++		msi_map_pirq_to_vector(dev, pirq_entry->pirq,
++				       pirq_entry->entry_nr, table_base);
+ 	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+ 
+ 	pci_intx_for_msi(dev, 0);
+@@ -338,10 +364,10 @@
+ 
+ 	msi_set_enable(dev, 0);	/* Ensure msi is disabled as I set it up */
+ 
+-   	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
++	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+ 	pci_read_config_word(dev, msi_control_reg(pos), &control);
+ 
+-	pirq = msi_map_vector(dev, 0, 1);
++	pirq = msi_map_vector(dev, 0, 0);
+ 	if (pirq < 0)
+ 		return -EBUSY;
+ 
+@@ -367,7 +393,8 @@
+ static int msix_capability_init(struct pci_dev *dev,
+ 				struct msix_entry *entries, int nvec)
+ {
+-	int pirq, i, j, mapped;
++        u64 table_base;
++	int pirq, i, j, mapped, pos;
+ 	struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
+ 	struct msi_pirq_entry *pirq_entry;
+ 
+@@ -376,6 +403,11 @@
+ 
+ 	msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
+ 
++	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++	table_base = find_table_base(dev, pos);
++	if (!table_base)
++		return -ENODEV;
++
+ 	/* MSI-X Table Initialization */
+ 	for (i = 0; i < nvec; i++) {
+ 		mapped = 0;
+@@ -392,7 +424,7 @@
+ 		}
+ 		if (mapped)
+ 			continue;
+-		pirq = msi_map_vector(dev, entries[i].entry, 0);
++		pirq = msi_map_vector(dev, entries[i].entry, table_base);
+ 		if (pirq < 0)
+ 			break;
+ 		attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
+diff -u -r build_i386_xen_686/include/xen/interface/physdev.h build_i386_xen_686-fix/include/xen/interface/physdev.h
+--- build_i386_xen_686/include/xen/interface/physdev.h	2010-02-25 12:23:43.000000000 +0000
++++ build_i386_xen_686-fix/include/xen/interface/physdev.h	2010-02-25 12:38:42.000000000 +0000
+@@ -136,10 +136,13 @@
+     /* IN or OUT */
+     int pirq;
+     /* IN */
+-    struct {
+-        int bus, devfn, entry_nr;
+-		int msi;  /* 0 - MSIX    1 - MSI */
+-    } msi_info;
++    int bus;
++    /* IN */
++    int devfn;
++    /* IN */
++    int entry_nr;
++    /* IN */
++    uint64_t table_base;
+ };
+ typedef struct physdev_map_pirq physdev_map_pirq_t;
+ DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);

Modified: dists/lenny/linux-2.6/debian/patches/series/22-extra
==============================================================================
--- dists/lenny/linux-2.6/debian/patches/series/22-extra	Sat Feb 27 20:49:03 2010	(r15286)
+++ dists/lenny/linux-2.6/debian/patches/series/22-extra	Sat Feb 27 20:49:18 2010	(r15287)
@@ -2,3 +2,4 @@
 + features/all/openvz/0088-cfq-unlink-queues-at-bc-destroy.patch featureset=openvz
 + features/all/openvz/0089-inotify-unblock-umounting.patch featureset=openvz
 + features/all/xen/printk-robustify-printk-xen.patch featureset=xen
++ features/all/xen/xen-fix-msi-hypercall.patch featureset=xen



More information about the Kernel-svn-changes mailing list