Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 289708 Details for
Bug 425794
PCI allocation errors result in Xserver resetting the machine
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Fix 32-bit BARs being allocated above 4GB
d-pci-32bit (text/plain), 7.05 KB, created by
Richard Henderson
on 2007-12-15 21:23:56 UTC
(
hide
)
Description:
Fix 32-bit BARs being allocated above 4GB
Filename:
MIME Type:
Creator:
Richard Henderson
Created:
2007-12-15 21:23:56 UTC
Size:
7.05 KB
patch
obsolete
>diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/arch/i386/pci/fixup.c linux-2.6.23.x86_64-rth/arch/i386/pci/fixup.c >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/arch/i386/pci/fixup.c 2007-10-09 13:31:38.000000000 -0700 >+++ linux-2.6.23.x86_64-rth/arch/i386/pci/fixup.c 2007-12-14 17:14:25.000000000 -0800 >@@ -444,3 +444,37 @@ static void __devinit pci_siemens_interr > } > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, > pci_siemens_interrupt_controller); >+ >+/* >+ * Force all VGA device BARs to be allocated in the low 4G. The X server >+ * (even x86-64 native) doesn't handle 64-bit pci addresses, resulting in >+ * machine resets or worse. >+ */ >+static void __devinit pci_fixup_video_32bit(struct pci_dev *pdev) >+{ >+ int i; >+ >+ if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) >+ return; >+ >+ pdev->force_32bit_bar = 1; >+ >+ for (i = 0; i < PCI_ROM_RESOURCE; i++) { >+ struct resource *r = &pdev->resource[i]; >+ >+ if (r->flags == 0) >+ continue; >+ if (r->flags & IORESOURCE_PCI_FIXED) >+ continue; >+ if ((r->flags & IORESOURCE_MEM) == 0) >+ continue; >+ >+ /* If the BIOS allocated the region above 4G, disable it >+ for now and try to reallocate. */ >+ if (r->start > 0xffffffff) { >+ r->end -= r->start; >+ r->start = 0; >+ } >+ } >+} >+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video_32bit) >diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pci/bus.c linux-2.6.23.x86_64-rth/drivers/pci/bus.c >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pci/bus.c 2007-10-09 13:31:38.000000000 -0700 >+++ linux-2.6.23.x86_64-rth/drivers/pci/bus.c 2007-12-14 16:03:01.000000000 -0800 >@@ -24,6 +24,7 @@ > * @size: size of resource to allocate > * @align: alignment of resource to allocate > * @min: minimum /proc/iomem address to allocate >+ * @max: maximum /proc/iomem address to allocate > * @type_mask: IORESOURCE_* type flags > * @alignf: resource alignment function > * @alignf_data: data argument for resource alignment function >@@ -35,7 +36,8 @@ > int > pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, > resource_size_t size, resource_size_t align, >- resource_size_t min, unsigned int type_mask, >+ resource_size_t min, resource_size_t max, >+ unsigned int type_mask, > void (*alignf)(void *, struct resource *, resource_size_t, > resource_size_t), > void *alignf_data) >@@ -62,8 +64,7 @@ pci_bus_alloc_resource(struct pci_bus *b > /* Ok, try it out.. */ > ret = allocate_resource(r, res, size, > r->start ? : min, >- -1, align, >- alignf, alignf_data); >+ max, align, alignf, alignf_data); > if (ret == 0) > break; > } >diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pci/setup-res.c linux-2.6.23.x86_64-rth/drivers/pci/setup-res.c >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pci/setup-res.c 2007-12-15 13:00:02.000000000 -0800 >+++ linux-2.6.23.x86_64-rth/drivers/pci/setup-res.c 2007-12-14 17:36:57.000000000 -0800 >@@ -131,18 +131,41 @@ int pci_assign_resource(struct pci_dev * > { > struct pci_bus *bus = dev->bus; > struct resource *res = dev->resource + resno; >- resource_size_t size, min, align; >+ resource_size_t size, min, max, align; > int ret; > > size = res->end - res->start + 1; >- min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; >+ >+ if (res->flags & IORESOURCE_IO) { >+ min = PCIBIOS_MIN_IO; >+ max = -1; >+ } else { >+ min = PCIBIOS_MIN_MEM; >+ >+ /* Respect the maximum address range for this BAR. */ >+ switch (res->flags & PCI_BASE_ADDRESS_MEM_MASK) { >+ case PCI_BASE_ADDRESS_MEM_TYPE_1M: >+ max = 0xfffff; >+ break; >+ case PCI_BASE_ADDRESS_MEM_TYPE_64: >+ if (!dev->force_32bit_bar) { >+ max = -1; >+ break; >+ } >+ /* FALLTHRU */ >+ default: >+ max = 0xffffffff; >+ break; >+ } >+ } >+ > /* The bridge resources are special, as their > size != alignment. Sizing routines return > required alignment in the "start" field. */ > align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start; > > /* First, try exact prefetching match.. */ >- ret = pci_bus_alloc_resource(bus, res, size, align, min, >+ ret = pci_bus_alloc_resource(bus, res, size, align, min, max, > IORESOURCE_PREFETCH, > pcibios_align_resource, dev); > >@@ -153,8 +176,8 @@ int pci_assign_resource(struct pci_dev * > * But a prefetching area can handle a non-prefetching > * window (it will just not perform as well). > */ >- ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, >- pcibios_align_resource, dev); >+ ret = pci_bus_alloc_resource(bus, res, size, align, min, max, >+ 0, pcibios_align_resource, dev); > } > > if (ret) { >diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pcmcia/rsrc_mgr.c linux-2.6.23.x86_64-rth/drivers/pcmcia/rsrc_mgr.c >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pcmcia/rsrc_mgr.c 2007-10-09 13:31:38.000000000 -0700 >+++ linux-2.6.23.x86_64-rth/drivers/pcmcia/rsrc_mgr.c 2007-12-14 16:03:41.000000000 -0800 >@@ -246,7 +246,7 @@ static struct resource *iodyn_find_io_re > #ifdef CONFIG_PCI > if (s->cb_dev) { > ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, >- min, 0, pcmcia_align, &data); >+ min, -1, 0, pcmcia_align, &data); > } else > #endif > ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, >diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pcmcia/rsrc_nonstatic.c linux-2.6.23.x86_64-rth/drivers/pcmcia/rsrc_nonstatic.c >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/drivers/pcmcia/rsrc_nonstatic.c 2007-10-09 13:31:38.000000000 -0700 >+++ linux-2.6.23.x86_64-rth/drivers/pcmcia/rsrc_nonstatic.c 2007-12-14 16:03:34.000000000 -0800 >@@ -633,7 +633,7 @@ static struct resource *nonstatic_find_i > #ifdef CONFIG_PCI > if (s->cb_dev) { > ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, >- min, 0, pcmcia_align, &data); >+ min, -1, 0, pcmcia_align, &data); > } else > #endif > ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, >@@ -675,7 +675,7 @@ static struct resource * nonstatic_find_ > #ifdef CONFIG_PCI > if (s->cb_dev) { > ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, >- 1, min, 0, >+ 1, min, -1, 0, > pcmcia_align, &data); > } else > #endif >diff -rup BUILD/kernel-2.6.23/linux-2.6.23.x86_64/include/linux/pci.h linux-2.6.23.x86_64-rth/include/linux/pci.h >--- BUILD/kernel-2.6.23/linux-2.6.23.x86_64/include/linux/pci.h 2007-10-09 13:31:38.000000000 -0700 >+++ linux-2.6.23.x86_64-rth/include/linux/pci.h 2007-12-14 16:55:58.000000000 -0800 >@@ -183,6 +183,7 @@ struct pci_dev { > unsigned int msi_enabled:1; > unsigned int msix_enabled:1; > unsigned int is_managed:1; >+ unsigned int force_32bit_bar:1; /* allocate bars below 4g anyway */ > atomic_t enable_cnt; /* pci_enable_device has been called */ > > u32 saved_config_space[16]; /* config space saved at suspend time */ >@@ -603,7 +604,7 @@ void pci_release_selected_regions(struct > int __must_check pci_bus_alloc_resource(struct pci_bus *bus, > struct resource *res, resource_size_t size, > resource_size_t align, resource_size_t min, >- unsigned int type_mask, >+ resource_size_t max, unsigned int type_mask, > void (*alignf)(void *, struct resource *, > resource_size_t, resource_size_t), > void *alignf_data);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 425794
:
289707
| 289708 |
289932
|
289933
|
289934