Skip to content

Commit 46bdfe6

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: x86: avoid high BIOS area when allocating address space x86: avoid E820 regions when allocating address space x86: avoid low BIOS area when allocating address space resources: add arch hook for preventing allocation in reserved areas Revert "resources: support allocating space within a region from the top down" Revert "PCI: allocate bus resources from the top down" Revert "x86/PCI: allocate space from the end of a region, not the beginning" Revert "x86: allocate space within a region top-down" Revert "PCI: fix pci_bus_alloc_resource() hang, prefer positive decode" PCI: Update MCP55 quirk to not affect non HyperTransport variants
2 parents c15524a + a2c606d commit 46bdfe6

File tree

10 files changed

+76
-190
lines changed

10 files changed

+76
-190
lines changed

Documentation/kernel-parameters.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file
21752175
reset_devices [KNL] Force drivers to reset the underlying device
21762176
during initialization.
21772177

2178-
resource_alloc_from_bottom
2179-
Allocate new resources from the beginning of available
2180-
space, not the end. If you need to use this, please
2181-
report a bug.
2182-
21832178
resume= [SWSUSP]
21842179
Specify the partition device for software suspend
21852180

arch/x86/include/asm/e820.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ struct e820map {
7272
#define BIOS_BEGIN 0x000a0000
7373
#define BIOS_END 0x00100000
7474

75+
#define BIOS_ROM_BASE 0xffe00000
76+
#define BIOS_ROM_END 0xffffffff
77+
7578
#ifdef __KERNEL__
7679
/* see comment in arch/x86/kernel/e820.c */
7780
extern struct e820map e820;

arch/x86/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
4545
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
4646
obj-y += tsc.o io_delay.o rtc.o
4747
obj-y += pci-iommu_table.o
48+
obj-y += resource.o
4849

4950
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
5051
obj-y += process.o

arch/x86/kernel/resource.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include <linux/ioport.h>
2+
#include <asm/e820.h>
3+
4+
static void resource_clip(struct resource *res, resource_size_t start,
5+
resource_size_t end)
6+
{
7+
resource_size_t low = 0, high = 0;
8+
9+
if (res->end < start || res->start > end)
10+
return; /* no conflict */
11+
12+
if (res->start < start)
13+
low = start - res->start;
14+
15+
if (res->end > end)
16+
high = res->end - end;
17+
18+
/* Keep the area above or below the conflict, whichever is larger */
19+
if (low > high)
20+
res->end = start - 1;
21+
else
22+
res->start = end + 1;
23+
}
24+
25+
static void remove_e820_regions(struct resource *avail)
26+
{
27+
int i;
28+
struct e820entry *entry;
29+
30+
for (i = 0; i < e820.nr_map; i++) {
31+
entry = &e820.map[i];
32+
33+
resource_clip(avail, entry->addr,
34+
entry->addr + entry->size - 1);
35+
}
36+
}
37+
38+
void arch_remove_reservations(struct resource *avail)
39+
{
40+
/* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
41+
if (avail->flags & IORESOURCE_MEM) {
42+
if (avail->start < BIOS_END)
43+
avail->start = BIOS_END;
44+
resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
45+
46+
remove_e820_regions(avail);
47+
}
48+
}

arch/x86/kernel/setup.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p)
769769

770770
x86_init.oem.arch_setup();
771771

772-
resource_alloc_from_bottom = 0;
773772
iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
774773
setup_memory_map();
775774
parse_setup_data();

arch/x86/pci/i386.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
6565
resource_size_t size, resource_size_t align)
6666
{
6767
struct pci_dev *dev = data;
68-
resource_size_t start = round_down(res->end - size + 1, align);
68+
resource_size_t start = res->start;
6969

7070
if (res->flags & IORESOURCE_IO) {
71-
72-
/*
73-
* If we're avoiding ISA aliases, the largest contiguous I/O
74-
* port space is 256 bytes. Clearing bits 9 and 10 preserves
75-
* all 256-byte and smaller alignments, so the result will
76-
* still be correctly aligned.
77-
*/
78-
if (!skip_isa_ioresource_align(dev))
79-
start &= ~0x300;
80-
} else if (res->flags & IORESOURCE_MEM) {
81-
if (start < BIOS_END)
82-
start = res->end; /* fail; no space */
71+
if (skip_isa_ioresource_align(dev))
72+
return start;
73+
if (start & 0x300)
74+
start = (start + 0x3ff) & ~0x3ff;
8375
}
8476
return start;
8577
}

drivers/pci/bus.c

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
6464
}
6565
}
6666

67-
static bool pci_bus_resource_better(struct resource *res1, bool pos1,
68-
struct resource *res2, bool pos2)
69-
{
70-
/* If exactly one is positive decode, always prefer that one */
71-
if (pos1 != pos2)
72-
return pos1 ? true : false;
73-
74-
/* Prefer the one that contains the highest address */
75-
if (res1->end != res2->end)
76-
return (res1->end > res2->end) ? true : false;
77-
78-
/* Otherwise, prefer the one with highest "center of gravity" */
79-
if (res1->start != res2->start)
80-
return (res1->start > res2->start) ? true : false;
81-
82-
/* Otherwise, choose one arbitrarily (but consistently) */
83-
return (res1 > res2) ? true : false;
84-
}
85-
86-
static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res)
87-
{
88-
struct pci_bus_resource *bus_res;
89-
90-
/*
91-
* This relies on the fact that pci_bus.resource[] refers to P2P or
92-
* CardBus bridge base/limit registers, which are always positively
93-
* decoded. The pci_bus.resources list contains host bridge or
94-
* subtractively decoded resources.
95-
*/
96-
list_for_each_entry(bus_res, &bus->resources, list) {
97-
if (bus_res->res == res)
98-
return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ?
99-
false : true;
100-
}
101-
return true;
102-
}
103-
104-
/*
105-
* Find the next-best bus resource after the cursor "res". If the cursor is
106-
* NULL, return the best resource. "Best" means that we prefer positive
107-
* decode regions over subtractive decode, then those at higher addresses.
108-
*/
109-
static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
110-
unsigned int type,
111-
struct resource *res)
112-
{
113-
bool res_pos, r_pos, prev_pos = false;
114-
struct resource *r, *prev = NULL;
115-
int i;
116-
117-
res_pos = pci_bus_resource_positive(bus, res);
118-
pci_bus_for_each_resource(bus, r, i) {
119-
if (!r)
120-
continue;
121-
122-
if ((r->flags & IORESOURCE_TYPE_BITS) != type)
123-
continue;
124-
125-
r_pos = pci_bus_resource_positive(bus, r);
126-
if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) {
127-
if (!prev || pci_bus_resource_better(r, r_pos,
128-
prev, prev_pos)) {
129-
prev = r;
130-
prev_pos = r_pos;
131-
}
132-
}
133-
}
134-
135-
return prev;
136-
}
137-
13867
/**
13968
* pci_bus_alloc_resource - allocate a resource from a parent bus
14069
* @bus: PCI bus
@@ -160,20 +89,20 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
16089
resource_size_t),
16190
void *alignf_data)
16291
{
163-
int ret = -ENOMEM;
92+
int i, ret = -ENOMEM;
16493
struct resource *r;
16594
resource_size_t max = -1;
166-
unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
16795

16896
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
16997

17098
/* don't allocate too high if the pref mem doesn't support 64bit*/
17199
if (!(res->flags & IORESOURCE_MEM_64))
172100
max = PCIBIOS_MAX_MEM_32;
173101

174-
/* Look for space at highest addresses first */
175-
r = pci_bus_find_resource_prev(bus, type, NULL);
176-
for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) {
102+
pci_bus_for_each_resource(bus, r, i) {
103+
if (!r)
104+
continue;
105+
177106
/* type_mask must match */
178107
if ((res->flags ^ r->flags) & type_mask)
179108
continue;

drivers/pci/quirks.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
23292329
{
23302330
u32 cfg;
23312331

2332+
if (!pci_find_capability(dev, PCI_CAP_ID_HT))
2333+
return;
2334+
23322335
pci_read_config_dword(dev, 0x74, &cfg);
23332336

23342337
if (cfg & ((1 << 2) | (1 << 15))) {

include/linux/ioport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ struct resource_list {
112112
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
113113
extern struct resource ioport_resource;
114114
extern struct resource iomem_resource;
115-
extern int resource_alloc_from_bottom;
116115

117116
extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
118117
extern int request_resource(struct resource *root, struct resource *new);
@@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root,
124123
extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
125124
extern int insert_resource(struct resource *parent, struct resource *new);
126125
extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
126+
extern void arch_remove_reservations(struct resource *avail);
127127
extern int allocate_resource(struct resource *root, struct resource *new,
128128
resource_size_t size, resource_size_t min,
129129
resource_size_t max, resource_size_t align,

0 commit comments

Comments
 (0)