All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Ivan Kokshaysky <ink@jurassic.park.msu.ru>,
	Jesse Barnes <jbarnes@virtuousgeek.org>,
	Ingo Molnar <mingo@elte.hu>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	linux-pci@vger.kernel.org, yannick.roehlly@free.fr
Subject: [PATCH 1/4] pci/x86: don't assume pref memio are 64bit -v4
Date: Thu, 23 Apr 2009 20:48:32 -0700	[thread overview]
Message-ID: <49F13690.3080902@kernel.org> (raw)
In-Reply-To: <20090423221936.GA24171@jurassic.park.msu.ru>


we should not assign 64bit range to pci device that only take 32bit pref

try to set IORESOURCE_MEM_64 in 64bit resource of pci_device/pci_bridge
and make the bus resource only have that bit set when all device under that do support
64bit pref mem then use that flag to allocate resource in wanted area

v2: fix b_res->flags and logic and passing result.
v3: split iomem to iomem32, iomem64, and iomem64 will take IORESOURCE_MEM_64
V4: according to Ivan
    make it support x86 only, by PCIBIOS_MAX_MEM_32
    double check if the bridge does support pref mem64 with write/read UPPER32

[Impact: do assign wrong range to device that doesn't support it]

Reported-by: Yannick <yannick.roehlly@free.fr>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/include/asm/pci.h |    1 
 drivers/pci/bus.c          |    7 +++++-
 drivers/pci/probe.c        |    9 ++++++-
 drivers/pci/setup-bus.c    |   52 ++++++++++++++++++++++++++++++++++++---------
 include/linux/ioport.h     |    2 +
 include/linux/pci.h        |    4 +++
 6 files changed, 62 insertions(+), 13 deletions(-)

Index: linux-2.6/drivers/pci/probe.c
===================================================================
--- linux-2.6.orig/drivers/pci/probe.c
+++ linux-2.6/drivers/pci/probe.c
@@ -193,7 +193,7 @@ int __pci_read_base(struct pci_dev *dev,
 		res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
 		if (type == pci_bar_io) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
-			mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
+			mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
@@ -237,6 +237,8 @@ int __pci_read_base(struct pci_dev *dev,
 			dev_printk(KERN_DEBUG, &dev->dev,
 				"reg %x 64bit mmio: %pR\n", pos, res);
 		}
+
+		res->flags |= IORESOURCE_MEM_64;
 	} else {
 		sz = pci_size(l, sz, mask);
 
@@ -362,7 +364,10 @@ void __devinit pci_read_bridge_bases(str
 		}
 	}
 	if (base <= limit) {
-		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
+					 IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		if (res->flags & PCI_PREF_RANGE_TYPE_64)
+			res->flags |= IORESOURCE_MEM_64;
 		res->start = base;
 		res->end = limit + 0xfffff;
 		dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
Index: linux-2.6/drivers/pci/setup-bus.c
===================================================================
--- linux-2.6.orig/drivers/pci/setup-bus.c
+++ linux-2.6/drivers/pci/setup-bus.c
@@ -143,6 +143,7 @@ static void pci_setup_bridge(struct pci_
 	struct pci_dev *bridge = bus->self;
 	struct pci_bus_region region;
 	u32 l, bu, lu, io_upper16;
+	int pref_mem64;
 
 	if (pci_is_enabled(bridge))
 		return;
@@ -198,16 +199,22 @@ static void pci_setup_bridge(struct pci_
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 	/* Set up PREF base/limit. */
+	pref_mem64 = 0;
 	bu = lu = 0;
 	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
 	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+		int width = 8;
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		bu = upper_32_bits(region.start);
-		lu = upper_32_bits(region.end);
-		dev_info(&bridge->dev, "  PREFETCH window: %#016llx-%#016llx\n",
-		    (unsigned long long)region.start,
-		    (unsigned long long)region.end);
+		if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
+			pref_mem64 = 1;
+			bu = upper_32_bits(region.start);
+			lu = upper_32_bits(region.end);
+			width = 16;
+		}
+		dev_info(&bridge->dev, "  PREFETCH window: %#0*llx-%#0*llx\n",
+				width, (unsigned long long)region.start,
+				width, (unsigned long long)region.end);
 	}
 	else {
 		l = 0x0000fff0;
@@ -215,9 +222,11 @@ static void pci_setup_bridge(struct pci_
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 
-	/* Set the upper 32 bits of PREF base & limit. */
-	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
-	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+	if (pref_mem64) {
+		/* Set the upper 32 bits of PREF base & limit. */
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+		pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+	}
 
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 }
@@ -255,8 +264,25 @@ static void pci_bridge_check_ranges(stru
 		pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
 		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
 	}
-	if (pmem)
+	if (pmem) {
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
+			b_res[2].flags |= IORESOURCE_MEM_64;
+	}
+
+	/* double check if bridge does support 64 bit pref */
+	if (b_res[2].flags & IORESOURCE_MEM_64) {
+		u32 mem_base_hi, tmp;
+		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+					 &mem_base_hi);
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+					       0xffffffff);
+		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
+		if (!tmp)
+			b_res[2].flags &= ~IORESOURCE_MEM_64;
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+				       mem_base_hi);
+	}
 }
 
 /* Helper function for sizing routines: find first available
@@ -336,6 +362,7 @@ static int pbus_size_mem(struct pci_bus
 	resource_size_t aligns[12];	/* Alignments from 1Mb to 2Gb */
 	int order, max_order;
 	struct resource *b_res = find_free_bus_resource(bus, type);
+	unsigned int mem64_mask = 0;
 
 	if (!b_res)
 		return 0;
@@ -344,9 +371,12 @@ static int pbus_size_mem(struct pci_bus
 	max_order = 0;
 	size = 0;
 
+	mem64_mask = b_res->flags & IORESOURCE_MEM_64;
+	b_res->flags &= ~IORESOURCE_MEM_64;
+
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
-		
+
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *r = &dev->resource[i];
 			resource_size_t r_size;
@@ -372,6 +402,7 @@ static int pbus_size_mem(struct pci_bus
 				aligns[order] += align;
 			if (order > max_order)
 				max_order = order;
+			mem64_mask &= r->flags & IORESOURCE_MEM_64;
 		}
 	}
 
@@ -396,6 +427,7 @@ static int pbus_size_mem(struct pci_bus
 	b_res->start = min_align;
 	b_res->end = size + min_align - 1;
 	b_res->flags |= IORESOURCE_STARTALIGN;
+	b_res->flags |= mem64_mask;
 	return 1;
 }
 
Index: linux-2.6/include/linux/ioport.h
===================================================================
--- linux-2.6.orig/include/linux/ioport.h
+++ linux-2.6/include/linux/ioport.h
@@ -49,6 +49,8 @@ struct resource_list {
 #define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
 #define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
 
+#define IORESOURCE_MEM_64	0x00100000
+
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
 #define IORESOURCE_UNSET	0x20000000
Index: linux-2.6/drivers/pci/bus.c
===================================================================
--- linux-2.6.orig/drivers/pci/bus.c
+++ linux-2.6/drivers/pci/bus.c
@@ -41,9 +41,14 @@ pci_bus_alloc_resource(struct pci_bus *b
 		void *alignf_data)
 {
 	int i, ret = -ENOMEM;
+	resource_size_t max = -1;
 
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 
+	/* don't allocate too high if the pref mem doesn't support 64bit*/
+	if (!(res->flags & IORESOURCE_MEM_64))
+		max = PCIBIOS_MAX_MEM_32;
+
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		struct resource *r = bus->resource[i];
 		if (!r)
@@ -62,7 +67,7 @@ pci_bus_alloc_resource(struct pci_bus *b
 		/* Ok, try it out.. */
 		ret = allocate_resource(r, res, size,
 					r->start ? : min,
-					-1, align,
+					max, align,
 					alignf, alignf_data);
 		if (ret == 0)
 			break;
Index: linux-2.6/arch/x86/include/asm/pci.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/pci.h
+++ linux-2.6/arch/x86/include/asm/pci.h
@@ -130,6 +130,7 @@ extern void pci_iommu_alloc(void);
 
 /* generic pci stuff */
 #include <asm-generic/pci.h>
+#define PCIBIOS_MAX_MEM_32 0xffffffff
 
 #ifdef CONFIG_NUMA
 /* Returns the node based on pci bus */
Index: linux-2.6/include/linux/pci.h
===================================================================
--- linux-2.6.orig/include/linux/pci.h
+++ linux-2.6/include/linux/pci.h
@@ -1100,6 +1100,10 @@ static inline struct pci_dev *pci_get_bu
 
 #include <asm/pci.h>
 
+#ifndef PCIBIOS_MAX_MEM_32
+#define PCIBIOS_MAX_MEM_32 (-1)
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)

  reply	other threads:[~2009-04-24  3:51 UTC|newest]

Thread overview: 117+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <bug-11103-13546@http.bugzilla.kernel.org/>
     [not found] ` <200904101913.n3AJDhMm018684@demeter.kernel.org>
2009-04-10 20:27   ` [Bug 11103] Can't use framebuffer or vesa Xorg with two memory modules Yinghai Lu
2009-04-11  3:29     ` Yinghai Lu
2009-04-14 20:49       ` [PATCH] pci: don't assume pref memio are 64bit -v2 Yinghai Lu
2009-04-14 20:50         ` [PATCH] x86/pci: make pci_mem_start to be aligned only Yinghai Lu
2009-04-14 21:10           ` Linus Torvalds
2009-04-14 21:27             ` H. Peter Anvin
2009-04-14 21:27             ` Yinghai Lu
2009-04-14 22:35             ` Yannick Roehlly
2009-04-15  0:29             ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v2 Yinghai Lu
2009-04-15  0:41               ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v3 Yinghai Lu
2009-04-15  0:42                 ` [PATCH] x86/pci: fix -1 calling to e820_all_mapped with mmconfig Yinghai Lu
2009-04-16 16:31                 ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v3 Jesse Barnes
2009-04-16 16:44                   ` Linus Torvalds
2009-04-16 16:56                     ` Ingo Molnar
2009-04-16 17:18                       ` Yinghai Lu
2009-04-16 17:27                         ` H. Peter Anvin
2009-04-16 17:38                           ` Ingo Molnar
2009-04-16 17:28                         ` Ingo Molnar
2009-04-16 20:13                           ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v4 Yinghai Lu
2009-04-16 23:18                             ` Linus Torvalds
2009-04-16 23:54                               ` Ingo Molnar
2009-04-17  0:24                                 ` Linus Torvalds
2009-04-17 13:16                                   ` Ingo Molnar
2009-04-17 21:59                                     ` Yinghai Lu
2009-04-17 22:04                                     ` H. Peter Anvin
2009-04-18  5:37                                       ` [PATCH] pci: keep pci device resource name pointer right Yinghai Lu
2009-04-18  7:51                                         ` Ingo Molnar
2009-04-18 16:05                                           ` Jesse Barnes
2009-04-18 18:42                                         ` Linus Torvalds
2009-04-18 19:19                                           ` Yinghai Lu
2009-04-18 19:23                                             ` Greg KH
2009-04-18 20:00                                               ` Kay Sievers
2009-04-18 20:27                                                 ` Kay Sievers
2009-04-18 20:37                                                   ` Ingo Molnar
2009-04-18 22:05                                                     ` [PATCH] driver: dont update dev_name via device_add path Yinghai Lu
2009-04-28  7:36                                                       ` [PATCH] driver: make dev_set_name(, NULL) work Yinghai Lu
2009-04-28  7:42                                                         ` [RFC PATCH] use dev_set_name(,NULL) to prevent leaking Yinghai Lu
2009-04-28  8:25                                                           ` Kay Sievers
2009-04-28 15:21                                                             ` Yinghai Lu
2009-04-28 15:34                                                               ` Yinghai Lu
2009-04-28 15:39                                                                 ` Greg KH
2009-04-28 15:51                                                                   ` Yinghai Lu
2009-04-28 15:56                                                                     ` Kay Sievers
2009-04-28 16:08                                                                       ` Yinghai Lu
2009-04-28 16:15                                                                         ` Kay Sievers
2009-04-28 19:04                                                                           ` Yinghai Lu
2009-04-28 16:36                                                                       ` Yinghai Lu
2009-04-28 16:50                                                                         ` Kay Sievers
2009-04-28 14:52                                                           ` Greg KH
2009-04-28 14:51                                                         ` [PATCH] driver: make dev_set_name(, NULL) work Greg KH
2009-04-28 15:14                                                           ` Yinghai Lu
2009-04-28 15:39                                                             ` Greg KH
2009-04-18 21:07                                                   ` [PATCH] pci: keep pci device resource name pointer right Yinghai Lu
2009-04-18 22:17                                                   ` Linus Torvalds
2009-04-18 20:00                                               ` [PATCH] driver: dont update dev_name if it is not changed Yinghai Lu
2009-04-18 20:11                                                 ` Ingo Molnar
2009-04-18 20:20                                                   ` Yinghai Lu
2009-04-18 20:27                                                     ` Ingo Molnar
2009-04-18  8:33                               ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v4 Yinghai Lu
2009-04-18  9:22                                 ` Ingo Molnar
2009-04-18 17:07                                   ` Yinghai Lu
2009-04-18 18:57                                   ` Linus Torvalds
2009-04-18 19:14                                     ` Ingo Molnar
2009-04-18 19:26                                       ` Yinghai Lu
2009-04-18 22:20                                         ` Yinghai Lu
2009-04-18 22:31                                         ` Linus Torvalds
2009-04-18 20:13                                       ` Ivan Kokshaysky
2009-04-18 18:50                                 ` Linus Torvalds
2009-04-18 22:44                                   ` Yinghai Lu
2009-04-18 23:01                                     ` Yinghai Lu
2009-04-18 23:06                                       ` Linus Torvalds
2009-04-18 23:26                                         ` Yinghai Lu
2009-04-18 23:30                                           ` Yinghai Lu
2009-04-18 23:04                                     ` Linus Torvalds
2009-04-19  0:32                                       ` H. Peter Anvin
2009-04-19  4:50                                       ` Linus Torvalds
2009-04-19  5:26                                         ` Yinghai Lu
2009-04-19 19:35                                           ` Yannick Roehlly
2009-04-19 19:59                                             ` Yinghai Lu
2009-04-19 20:24                                               ` Yannick Roehlly
2009-04-19  9:02                                         ` Ingo Molnar
2009-04-19  9:06                                           ` Ingo Molnar
2009-04-19 17:52                                             ` Jesse Barnes
2009-04-20 22:33                                             ` Ivan Kokshaysky
2009-04-20 22:52                                               ` Yinghai Lu
2009-04-21 10:54                                                 ` Ivan Kokshaysky
2009-04-21  0:09                                               ` Yinghai Lu
2009-04-21 10:56                                                 ` Ivan Kokshaysky
2009-04-21 15:57                                                   ` Yinghai Lu
2009-04-22 22:37                                                   ` [RFC PATCH 1/2] pci: don't assume pref memio are 64bit -v3 Yinghai Lu
2009-04-22 22:38                                                     ` [RFC PATCH 2/2] pci: try to assign res for device under transparent bridges Yinghai Lu
2009-04-22 22:49                                                     ` [RFC PATCH 1/2] pci: don't assume pref memio are 64bit -v3 Jesse Barnes
2009-04-23  0:49                                                       ` Yinghai Lu
2009-04-23  1:05                                                         ` Jesse Barnes
2009-04-23  2:03                                                           ` Yinghai Lu
2009-04-23 12:58                                                             ` Ivan Kokshaysky
2009-04-23 15:30                                                               ` Yinghai Lu
2009-04-23  2:10                                                           ` Yinghai Lu
2009-04-23 13:22                                                             ` Ivan Kokshaysky
2009-04-23 15:13                                                               ` Yinghai Lu
2009-04-23 22:19                                                                 ` Ivan Kokshaysky
2009-04-24  3:48                                                                   ` Yinghai Lu [this message]
2009-04-24  3:49                                                                     ` [PATCH 2/4] pci: try to assign res for device under transparent bridges -v2 Yinghai Lu
2009-04-24  3:50                                                                     ` [PATCH 3/4] x86: reserve range near the ram Yinghai Lu
2009-04-24  3:50                                                                     ` [PATCH 4/4] x86/pci: make pci_mem_start to be aligned only -v5 Yinghai Lu
2009-04-24 13:16                                                                     ` [PATCH 1/4] pci/x86: don't assume pref memio are 64bit -v4 Ivan Kokshaysky
2009-05-05 18:52                                                                     ` Jesse Barnes
2009-05-06 12:33                                                                       ` Ingo Molnar
2009-05-06 15:06                                                                         ` [PATCH 1/2] x86: reserve range near the ram Yinghai Lu
2009-05-11  9:51                                                                           ` [tip:x86/mm] x86, e820, pci: reserve extra free space near end of RAM tip-bot for Linus Torvalds
2009-05-06 15:07                                                                         ` [PATCH 1/2] x86/pci: make pci_mem_start to be aligned only -v5 Yinghai Lu
2009-05-11  9:51                                                                           ` [tip:x86/mm] x86/pci: remove rounding quirk from e820_setup_gap() tip-bot for Yinghai Lu
2009-04-23 12:36                                                     ` [RFC PATCH 1/2] pci: don't assume pref memio are 64bit -v3 Ivan Kokshaysky
2009-04-23 12:41                                                       ` Ingo Molnar
2009-04-23 13:09                                                         ` Ivan Kokshaysky
2009-04-23 15:05                                                       ` Yinghai Lu
2009-04-21 15:41                                               ` [PATCH] x86/pci: make pci_mem_start to be aligned only -v4 Jesse Barnes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49F13690.3080902@kernel.org \
    --to=yinghai@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=ink@jurassic.park.msu.ru \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=yannick.roehlly@free.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.