diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/boot/tools/build.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 57 | ||||
-rw-r--r-- | arch/i386/kernel/apic.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/apm.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/kprobes.c | 133 | ||||
-rw-r--r-- | arch/i386/kernel/process.c | 29 | ||||
-rw-r--r-- | arch/i386/kernel/syscall_table.S | 2 | ||||
-rw-r--r-- | arch/i386/kernel/time.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/timers/timer_cyclone.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/timers/timer_pit.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/timers/timer_tsc.c | 3 | ||||
-rw-r--r-- | arch/i386/mach-voyager/voyager_basic.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 9 | ||||
-rw-r--r-- | arch/i386/pci/i386.c | 11 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 51 | ||||
-rw-r--r-- | arch/i386/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 39 | ||||
-rw-r--r-- | arch/i386/pci/numa.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 1 |
21 files changed, 254 insertions, 114 deletions
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512e1..6835f6d47c31 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -70,7 +70,8 @@ void usage(void) | |||
70 | 70 | ||
71 | int main(int argc, char ** argv) | 71 | int main(int argc, char ** argv) |
72 | { | 72 | { |
73 | unsigned int i, c, sz, setup_sectors; | 73 | unsigned int i, sz, setup_sectors; |
74 | int c; | ||
74 | u32 sys_size; | 75 | u32 sys_size; |
75 | byte major_root, minor_root; | 76 | byte major_root, minor_root; |
76 | struct stat sb; | 77 | struct stat sb; |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f404b..b7808a89d945 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) | |||
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | #ifdef CONFIG_PCI_MMCONFIG | 161 | #ifdef CONFIG_PCI_MMCONFIG |
162 | static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | 162 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ |
163 | struct acpi_table_mcfg_config *pci_mmcfg_config; | ||
164 | int pci_mmcfg_config_num; | ||
165 | |||
166 | int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | ||
163 | { | 167 | { |
164 | struct acpi_table_mcfg *mcfg; | 168 | struct acpi_table_mcfg *mcfg; |
169 | unsigned long i; | ||
170 | int config_size; | ||
165 | 171 | ||
166 | if (!phys_addr || !size) | 172 | if (!phys_addr || !size) |
167 | return -EINVAL; | 173 | return -EINVAL; |
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
172 | return -ENODEV; | 178 | return -ENODEV; |
173 | } | 179 | } |
174 | 180 | ||
175 | if (mcfg->base_reserved) { | 181 | /* how many config structures do we have */ |
176 | printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); | 182 | pci_mmcfg_config_num = 0; |
183 | i = size - sizeof(struct acpi_table_mcfg); | ||
184 | while (i >= sizeof(struct acpi_table_mcfg_config)) { | ||
185 | ++pci_mmcfg_config_num; | ||
186 | i -= sizeof(struct acpi_table_mcfg_config); | ||
187 | }; | ||
188 | if (pci_mmcfg_config_num == 0) { | ||
189 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | ||
177 | return -ENODEV; | 190 | return -ENODEV; |
178 | } | 191 | } |
179 | 192 | ||
180 | pci_mmcfg_base_addr = mcfg->base_address; | 193 | config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); |
194 | pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); | ||
195 | if (!pci_mmcfg_config) { | ||
196 | printk(KERN_WARNING PREFIX | ||
197 | "No memory for MCFG config tables\n"); | ||
198 | return -ENOMEM; | ||
199 | } | ||
200 | |||
201 | memcpy(pci_mmcfg_config, &mcfg->config, config_size); | ||
202 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
203 | if (mcfg->config[i].base_reserved) { | ||
204 | printk(KERN_ERR PREFIX | ||
205 | "MMCONFIG not in low 4GB of memory\n"); | ||
206 | return -ENODEV; | ||
207 | } | ||
208 | } | ||
181 | 209 | ||
182 | return 0; | 210 | return 0; |
183 | } | 211 | } |
184 | #else | 212 | #endif /* CONFIG_PCI_MMCONFIG */ |
185 | #define acpi_parse_mcfg NULL | ||
186 | #endif /* !CONFIG_PCI_MMCONFIG */ | ||
187 | 213 | ||
188 | #ifdef CONFIG_X86_LOCAL_APIC | 214 | #ifdef CONFIG_X86_LOCAL_APIC |
189 | static int __init | 215 | static int __init |
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) | |||
507 | EXPORT_SYMBOL(acpi_unmap_lsapic); | 533 | EXPORT_SYMBOL(acpi_unmap_lsapic); |
508 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 534 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
509 | 535 | ||
536 | int | ||
537 | acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
538 | { | ||
539 | /* TBD */ | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | EXPORT_SYMBOL(acpi_register_ioapic); | ||
543 | |||
544 | int | ||
545 | acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | ||
546 | { | ||
547 | /* TBD */ | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | EXPORT_SYMBOL(acpi_unregister_ioapic); | ||
551 | |||
510 | static unsigned long __init | 552 | static unsigned long __init |
511 | acpi_scan_rsdp ( | 553 | acpi_scan_rsdp ( |
512 | unsigned long start, | 554 | unsigned long start, |
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) | |||
1123 | acpi_process_madt(); | 1165 | acpi_process_madt(); |
1124 | 1166 | ||
1125 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); | 1167 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); |
1126 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
1127 | 1168 | ||
1128 | return 0; | 1169 | return 0; |
1129 | } | 1170 | } |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 93df90bbb87e..bd1dbf3bd223 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/desc.h> | 35 | #include <asm/desc.h> |
36 | #include <asm/arch_hooks.h> | 36 | #include <asm/arch_hooks.h> |
37 | #include <asm/hpet.h> | 37 | #include <asm/hpet.h> |
38 | #include <asm/i8253.h> | ||
38 | 39 | ||
39 | #include <mach_apic.h> | 40 | #include <mach_apic.h> |
40 | 41 | ||
@@ -879,7 +880,6 @@ fake_ioapic_page: | |||
879 | */ | 880 | */ |
880 | static unsigned int __devinit get_8254_timer_count(void) | 881 | static unsigned int __devinit get_8254_timer_count(void) |
881 | { | 882 | { |
882 | extern spinlock_t i8253_lock; | ||
883 | unsigned long flags; | 883 | unsigned long flags; |
884 | 884 | ||
885 | unsigned int count; | 885 | unsigned int count; |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index d48ce9290963..064211d5f41b 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -228,10 +228,10 @@ | |||
228 | #include <asm/system.h> | 228 | #include <asm/system.h> |
229 | #include <asm/uaccess.h> | 229 | #include <asm/uaccess.h> |
230 | #include <asm/desc.h> | 230 | #include <asm/desc.h> |
231 | #include <asm/i8253.h> | ||
231 | 232 | ||
232 | #include "io_ports.h" | 233 | #include "io_ports.h" |
233 | 234 | ||
234 | extern spinlock_t i8253_lock; | ||
235 | extern unsigned long get_cmos_time(void); | 235 | extern unsigned long get_cmos_time(void); |
236 | extern void machine_real_restart(unsigned char *, int); | 236 | extern void machine_real_restart(unsigned char *, int); |
237 | 237 | ||
@@ -1168,8 +1168,7 @@ static void get_time_diff(void) | |||
1168 | static void reinit_timer(void) | 1168 | static void reinit_timer(void) |
1169 | { | 1169 | { |
1170 | #ifdef INIT_TIMER_AFTER_SUSPEND | 1170 | #ifdef INIT_TIMER_AFTER_SUSPEND |
1171 | unsigned long flags; | 1171 | unsigned long flags; |
1172 | extern spinlock_t i8253_lock; | ||
1173 | 1172 | ||
1174 | spin_lock_irqsave(&i8253_lock, flags); | 1173 | spin_lock_irqsave(&i8253_lock, flags); |
1175 | /* set the clock to 100 Hz */ | 1174 | /* set the clock to 100 Hz */ |
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 1a49adb1f4a6..e86ea486c311 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | |||
@@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_chipset(void) | |||
190 | 190 | ||
191 | /* detect which companion chip is used */ | 191 | /* detect which companion chip is used */ |
192 | while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { | 192 | while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { |
193 | if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { | 193 | if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { |
194 | return gx_pci; | 194 | return gx_pci; |
195 | } | 195 | } |
196 | } | 196 | } |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 35eb8e29c485..6578f40bd501 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/smp.h> | 37 | #include <asm/smp.h> |
38 | #include <asm/desc.h> | 38 | #include <asm/desc.h> |
39 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
40 | #include <asm/i8259.h> | ||
40 | 41 | ||
41 | #include <mach_apic.h> | 42 | #include <mach_apic.h> |
42 | 43 | ||
@@ -1566,7 +1567,6 @@ void print_all_local_APICs (void) | |||
1566 | 1567 | ||
1567 | void /*__init*/ print_PIC(void) | 1568 | void /*__init*/ print_PIC(void) |
1568 | { | 1569 | { |
1569 | extern spinlock_t i8259A_lock; | ||
1570 | unsigned int v; | 1570 | unsigned int v; |
1571 | unsigned long flags; | 1571 | unsigned long flags; |
1572 | 1572 | ||
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 3762f6b35ab2..a6d8c45961d3 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -127,48 +127,23 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
127 | regs->eip = (unsigned long)&p->ainsn.insn; | 127 | regs->eip = (unsigned long)&p->ainsn.insn; |
128 | } | 128 | } |
129 | 129 | ||
130 | struct task_struct *arch_get_kprobe_task(void *ptr) | ||
131 | { | ||
132 | return ((struct thread_info *) (((unsigned long) ptr) & | ||
133 | (~(THREAD_SIZE -1))))->task; | ||
134 | } | ||
135 | |||
136 | void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) | 130 | void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) |
137 | { | 131 | { |
138 | unsigned long *sara = (unsigned long *)®s->esp; | 132 | unsigned long *sara = (unsigned long *)®s->esp; |
139 | struct kretprobe_instance *ri; | 133 | struct kretprobe_instance *ri; |
140 | static void *orig_ret_addr; | 134 | |
135 | if ((ri = get_free_rp_inst(rp)) != NULL) { | ||
136 | ri->rp = rp; | ||
137 | ri->task = current; | ||
138 | ri->ret_addr = (kprobe_opcode_t *) *sara; | ||
141 | 139 | ||
142 | /* | ||
143 | * Save the return address when the return probe hits | ||
144 | * the first time, and use it to populate the (krprobe | ||
145 | * instance)->ret_addr for subsequent return probes at | ||
146 | * the same addrress since stack address would have | ||
147 | * the kretprobe_trampoline by then. | ||
148 | */ | ||
149 | if (((void*) *sara) != kretprobe_trampoline) | ||
150 | orig_ret_addr = (void*) *sara; | ||
151 | |||
152 | if ((ri = get_free_rp_inst(rp)) != NULL) { | ||
153 | ri->rp = rp; | ||
154 | ri->stack_addr = sara; | ||
155 | ri->ret_addr = orig_ret_addr; | ||
156 | add_rp_inst(ri); | ||
157 | /* Replace the return addr with trampoline addr */ | 140 | /* Replace the return addr with trampoline addr */ |
158 | *sara = (unsigned long) &kretprobe_trampoline; | 141 | *sara = (unsigned long) &kretprobe_trampoline; |
159 | } else { | ||
160 | rp->nmissed++; | ||
161 | } | ||
162 | } | ||
163 | 142 | ||
164 | void arch_kprobe_flush_task(struct task_struct *tk) | 143 | add_rp_inst(ri); |
165 | { | 144 | } else { |
166 | struct kretprobe_instance *ri; | 145 | rp->nmissed++; |
167 | while ((ri = get_rp_inst_tsk(tk)) != NULL) { | 146 | } |
168 | *((unsigned long *)(ri->stack_addr)) = | ||
169 | (unsigned long) ri->ret_addr; | ||
170 | recycle_rp_inst(ri); | ||
171 | } | ||
172 | } | 147 | } |
173 | 148 | ||
174 | /* | 149 | /* |
@@ -286,36 +261,59 @@ no_kprobe: | |||
286 | */ | 261 | */ |
287 | int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | 262 | int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
288 | { | 263 | { |
289 | struct task_struct *tsk; | 264 | struct kretprobe_instance *ri = NULL; |
290 | struct kretprobe_instance *ri; | 265 | struct hlist_head *head; |
291 | struct hlist_head *head; | 266 | struct hlist_node *node, *tmp; |
292 | struct hlist_node *node; | 267 | unsigned long orig_ret_address = 0; |
293 | unsigned long *sara = ((unsigned long *) ®s->esp) - 1; | 268 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; |
294 | |||
295 | tsk = arch_get_kprobe_task(sara); | ||
296 | head = kretprobe_inst_table_head(tsk); | ||
297 | |||
298 | hlist_for_each_entry(ri, node, head, hlist) { | ||
299 | if (ri->stack_addr == sara && ri->rp) { | ||
300 | if (ri->rp->handler) | ||
301 | ri->rp->handler(ri, regs); | ||
302 | } | ||
303 | } | ||
304 | return 0; | ||
305 | } | ||
306 | 269 | ||
307 | void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, | 270 | head = kretprobe_inst_table_head(current); |
308 | unsigned long flags) | ||
309 | { | ||
310 | struct kretprobe_instance *ri; | ||
311 | /* RA already popped */ | ||
312 | unsigned long *sara = ((unsigned long *)®s->esp) - 1; | ||
313 | 271 | ||
314 | while ((ri = get_rp_inst(sara))) { | 272 | /* |
315 | regs->eip = (unsigned long)ri->ret_addr; | 273 | * It is possible to have multiple instances associated with a given |
274 | * task either because an multiple functions in the call path | ||
275 | * have a return probe installed on them, and/or more then one return | ||
276 | * return probe was registered for a target function. | ||
277 | * | ||
278 | * We can handle this because: | ||
279 | * - instances are always inserted at the head of the list | ||
280 | * - when multiple return probes are registered for the same | ||
281 | * function, the first instance's ret_addr will point to the | ||
282 | * real return address, and all the rest will point to | ||
283 | * kretprobe_trampoline | ||
284 | */ | ||
285 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | ||
286 | if (ri->task != current) | ||
287 | /* another task is sharing our hash bucket */ | ||
288 | continue; | ||
289 | |||
290 | if (ri->rp && ri->rp->handler) | ||
291 | ri->rp->handler(ri, regs); | ||
292 | |||
293 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
316 | recycle_rp_inst(ri); | 294 | recycle_rp_inst(ri); |
295 | |||
296 | if (orig_ret_address != trampoline_address) | ||
297 | /* | ||
298 | * This is the real return address. Any other | ||
299 | * instances associated with this task are for | ||
300 | * other calls deeper on the call stack | ||
301 | */ | ||
302 | break; | ||
317 | } | 303 | } |
318 | regs->eflags &= ~TF_MASK; | 304 | |
305 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | ||
306 | regs->eip = orig_ret_address; | ||
307 | |||
308 | unlock_kprobes(); | ||
309 | preempt_enable_no_resched(); | ||
310 | |||
311 | /* | ||
312 | * By returning a non-zero value, we are telling | ||
313 | * kprobe_handler() that we have handled unlocking | ||
314 | * and re-enabling preemption. | ||
315 | */ | ||
316 | return 1; | ||
319 | } | 317 | } |
320 | 318 | ||
321 | /* | 319 | /* |
@@ -403,8 +401,7 @@ static inline int post_kprobe_handler(struct pt_regs *regs) | |||
403 | current_kprobe->post_handler(current_kprobe, regs, 0); | 401 | current_kprobe->post_handler(current_kprobe, regs, 0); |
404 | } | 402 | } |
405 | 403 | ||
406 | if (current_kprobe->post_handler != trampoline_post_handler) | 404 | resume_execution(current_kprobe, regs); |
407 | resume_execution(current_kprobe, regs); | ||
408 | regs->eflags |= kprobe_saved_eflags; | 405 | regs->eflags |= kprobe_saved_eflags; |
409 | 406 | ||
410 | /*Restore back the original saved kprobes variables and continue. */ | 407 | /*Restore back the original saved kprobes variables and continue. */ |
@@ -534,3 +531,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
534 | } | 531 | } |
535 | return 0; | 532 | return 0; |
536 | } | 533 | } |
534 | |||
535 | static struct kprobe trampoline_p = { | ||
536 | .addr = (kprobe_opcode_t *) &kretprobe_trampoline, | ||
537 | .pre_handler = trampoline_probe_handler | ||
538 | }; | ||
539 | |||
540 | int __init arch_init_kprobes(void) | ||
541 | { | ||
542 | return register_kprobe(&trampoline_p); | ||
543 | } | ||
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 5f8cfa6b7940..ba243a4cc119 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -617,6 +617,33 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) | |||
617 | } | 617 | } |
618 | 618 | ||
619 | /* | 619 | /* |
620 | * This function selects if the context switch from prev to next | ||
621 | * has to tweak the TSC disable bit in the cr4. | ||
622 | */ | ||
623 | static inline void disable_tsc(struct task_struct *prev_p, | ||
624 | struct task_struct *next_p) | ||
625 | { | ||
626 | struct thread_info *prev, *next; | ||
627 | |||
628 | /* | ||
629 | * gcc should eliminate the ->thread_info dereference if | ||
630 | * has_secure_computing returns 0 at compile time (SECCOMP=n). | ||
631 | */ | ||
632 | prev = prev_p->thread_info; | ||
633 | next = next_p->thread_info; | ||
634 | |||
635 | if (has_secure_computing(prev) || has_secure_computing(next)) { | ||
636 | /* slow path here */ | ||
637 | if (has_secure_computing(prev) && | ||
638 | !has_secure_computing(next)) { | ||
639 | write_cr4(read_cr4() & ~X86_CR4_TSD); | ||
640 | } else if (!has_secure_computing(prev) && | ||
641 | has_secure_computing(next)) | ||
642 | write_cr4(read_cr4() | X86_CR4_TSD); | ||
643 | } | ||
644 | } | ||
645 | |||
646 | /* | ||
620 | * switch_to(x,yn) should switch tasks from x to y. | 647 | * switch_to(x,yn) should switch tasks from x to y. |
621 | * | 648 | * |
622 | * We fsave/fwait so that an exception goes off at the right time | 649 | * We fsave/fwait so that an exception goes off at the right time |
@@ -695,6 +722,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas | |||
695 | if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) | 722 | if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) |
696 | handle_io_bitmap(next, tss); | 723 | handle_io_bitmap(next, tss); |
697 | 724 | ||
725 | disable_tsc(prev_p, next_p); | ||
726 | |||
698 | return prev_p; | 727 | return prev_p; |
699 | } | 728 | } |
700 | 729 | ||
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 442a6e937b19..3db9a04aec6e 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -289,3 +289,5 @@ ENTRY(sys_call_table) | |||
289 | .long sys_add_key | 289 | .long sys_add_key |
290 | .long sys_request_key | 290 | .long sys_request_key |
291 | .long sys_keyctl | 291 | .long sys_keyctl |
292 | .long sys_ioprio_set | ||
293 | .long sys_ioprio_get /* 290 */ | ||
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index e68d9fdb0759..2854c357377f 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c | |||
@@ -68,7 +68,8 @@ | |||
68 | 68 | ||
69 | #include "io_ports.h" | 69 | #include "io_ports.h" |
70 | 70 | ||
71 | extern spinlock_t i8259A_lock; | 71 | #include <asm/i8259.h> |
72 | |||
72 | int pit_latch_buggy; /* extern */ | 73 | int pit_latch_buggy; /* extern */ |
73 | 74 | ||
74 | #include "do_timer.h" | 75 | #include "do_timer.h" |
@@ -85,6 +86,8 @@ extern unsigned long wall_jiffies; | |||
85 | DEFINE_SPINLOCK(rtc_lock); | 86 | DEFINE_SPINLOCK(rtc_lock); |
86 | EXPORT_SYMBOL(rtc_lock); | 87 | EXPORT_SYMBOL(rtc_lock); |
87 | 88 | ||
89 | #include <asm/i8253.h> | ||
90 | |||
88 | DEFINE_SPINLOCK(i8253_lock); | 91 | DEFINE_SPINLOCK(i8253_lock); |
89 | EXPORT_SYMBOL(i8253_lock); | 92 | EXPORT_SYMBOL(i8253_lock); |
90 | 93 | ||
diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c index f6f1206a11bb..13892a65c941 100644 --- a/arch/i386/kernel/timers/timer_cyclone.c +++ b/arch/i386/kernel/timers/timer_cyclone.c | |||
@@ -17,9 +17,9 @@ | |||
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | #include <asm/fixmap.h> | 19 | #include <asm/fixmap.h> |
20 | #include "io_ports.h" | 20 | #include <asm/i8253.h> |
21 | 21 | ||
22 | extern spinlock_t i8253_lock; | 22 | #include "io_ports.h" |
23 | 23 | ||
24 | /* Number of usecs that the last interrupt was delayed */ | 24 | /* Number of usecs that the last interrupt was delayed */ |
25 | static int delay_at_last_interrupt; | 25 | static int delay_at_last_interrupt; |
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index 967d5453cd0e..06de036a820c 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c | |||
@@ -15,9 +15,8 @@ | |||
15 | #include <asm/smp.h> | 15 | #include <asm/smp.h> |
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/arch_hooks.h> | 17 | #include <asm/arch_hooks.h> |
18 | #include <asm/i8253.h> | ||
18 | 19 | ||
19 | extern spinlock_t i8259A_lock; | ||
20 | extern spinlock_t i8253_lock; | ||
21 | #include "do_timer.h" | 20 | #include "do_timer.h" |
22 | #include "io_ports.h" | 21 | #include "io_ports.h" |
23 | 22 | ||
@@ -166,7 +165,6 @@ struct init_timer_opts __initdata timer_pit_init = { | |||
166 | 165 | ||
167 | void setup_pit_timer(void) | 166 | void setup_pit_timer(void) |
168 | { | 167 | { |
169 | extern spinlock_t i8253_lock; | ||
170 | unsigned long flags; | 168 | unsigned long flags; |
171 | 169 | ||
172 | spin_lock_irqsave(&i8253_lock, flags); | 170 | spin_lock_irqsave(&i8253_lock, flags); |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index f46e625bab67..8f4e4d5bc560 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "mach_timer.h" | 24 | #include "mach_timer.h" |
25 | 25 | ||
26 | #include <asm/hpet.h> | 26 | #include <asm/hpet.h> |
27 | #include <asm/i8253.h> | ||
27 | 28 | ||
28 | #ifdef CONFIG_HPET_TIMER | 29 | #ifdef CONFIG_HPET_TIMER |
29 | static unsigned long hpet_usec_quotient; | 30 | static unsigned long hpet_usec_quotient; |
@@ -35,8 +36,6 @@ static inline void cpufreq_delayed_get(void); | |||
35 | 36 | ||
36 | int tsc_disable __devinitdata = 0; | 37 | int tsc_disable __devinitdata = 0; |
37 | 38 | ||
38 | extern spinlock_t i8253_lock; | ||
39 | |||
40 | static int use_tsc; | 39 | static int use_tsc; |
41 | /* Number of usecs that the last interrupt was delayed */ | 40 | /* Number of usecs that the last interrupt was delayed */ |
42 | static int delay_at_last_interrupt; | 41 | static int delay_at_last_interrupt; |
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 602aea240e9b..3e439ce5e1b2 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> |
32 | #include <asm/arch_hooks.h> | 32 | #include <asm/arch_hooks.h> |
33 | #include <asm/i8253.h> | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Power off function, if any | 36 | * Power off function, if any |
@@ -182,7 +183,6 @@ voyager_timer_interrupt(struct pt_regs *regs) | |||
182 | * and swiftly introduce it to something sharp and | 183 | * and swiftly introduce it to something sharp and |
183 | * pointy. */ | 184 | * pointy. */ |
184 | __u16 val; | 185 | __u16 val; |
185 | extern spinlock_t i8253_lock; | ||
186 | 186 | ||
187 | spin_lock(&i8253_lock); | 187 | spin_lock(&i8253_lock); |
188 | 188 | ||
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af50..70bcd53451f6 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | |||
25 | 25 | ||
26 | int pci_routeirq; | 26 | int pci_routeirq; |
27 | int pcibios_last_bus = -1; | 27 | int pcibios_last_bus = -1; |
28 | struct pci_bus *pci_root_bus = NULL; | 28 | unsigned long pirq_table_addr; |
29 | struct pci_bus *pci_root_bus; | ||
29 | struct pci_raw_ops *raw_pci_ops; | 30 | struct pci_raw_ops *raw_pci_ops; |
30 | 31 | ||
31 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 32 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
133 | 134 | ||
134 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); | 135 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); |
135 | 136 | ||
136 | return pci_scan_bus(busnum, &pci_root_ops, NULL); | 137 | return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); |
137 | } | 138 | } |
138 | 139 | ||
139 | extern u8 pci_cache_line_size; | 140 | extern u8 pci_cache_line_size; |
@@ -164,6 +165,7 @@ static int __init pcibios_init(void) | |||
164 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) | 165 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) |
165 | pcibios_sort(); | 166 | pcibios_sort(); |
166 | #endif | 167 | #endif |
168 | pci_assign_unassigned_resources(); | ||
167 | return 0; | 169 | return 0; |
168 | } | 170 | } |
169 | 171 | ||
@@ -188,6 +190,9 @@ char * __devinit pcibios_setup(char *str) | |||
188 | } else if (!strcmp(str, "biosirq")) { | 190 | } else if (!strcmp(str, "biosirq")) { |
189 | pci_probe |= PCI_BIOS_IRQ_SCAN; | 191 | pci_probe |= PCI_BIOS_IRQ_SCAN; |
190 | return NULL; | 192 | return NULL; |
193 | } else if (!strncmp(str, "pirqaddr=", 9)) { | ||
194 | pirq_table_addr = simple_strtoul(str+9, NULL, 0); | ||
195 | return NULL; | ||
191 | } | 196 | } |
192 | #endif | 197 | #endif |
193 | #ifdef CONFIG_PCI_DIRECT | 198 | #ifdef CONFIG_PCI_DIRECT |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index c205ea7e233b..93a364c82150 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
106 | if ((dev = bus->self)) { | 106 | if ((dev = bus->self)) { |
107 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { | 107 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { |
108 | r = &dev->resource[idx]; | 108 | r = &dev->resource[idx]; |
109 | if (!r->start) | 109 | if (!r->flags) |
110 | continue; | 110 | continue; |
111 | pr = pci_find_parent_resource(dev, r); | 111 | pr = pci_find_parent_resource(dev, r); |
112 | if (!pr || request_resource(pr, r) < 0) | 112 | if (!r->start || !pr || request_resource(pr, r) < 0) { |
113 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); | 113 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); |
114 | /* Something is wrong with the region. | ||
115 | Invalidate the resource to prevent child | ||
116 | resource allocations in this range. */ | ||
117 | r->flags = 0; | ||
118 | } | ||
114 | } | 119 | } |
115 | } | 120 | } |
116 | pcibios_allocate_bus_resources(&bus->children); | 121 | pcibios_allocate_bus_resources(&bus->children); |
@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
227 | 232 | ||
228 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 233 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
229 | old_cmd = cmd; | 234 | old_cmd = cmd; |
230 | for(idx=0; idx<6; idx++) { | 235 | for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { |
231 | /* Only set up the requested stuff */ | 236 | /* Only set up the requested stuff */ |
232 | if (!(mask & (1<<idx))) | 237 | if (!(mask & (1<<idx))) |
233 | continue; | 238 | continue; |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e661..78ca1ecbb907 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -58,6 +58,35 @@ struct irq_router_handler { | |||
58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | 58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Check passed address for the PCI IRQ Routing Table signature | ||
62 | * and perform checksum verification. | ||
63 | */ | ||
64 | |||
65 | static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) | ||
66 | { | ||
67 | struct irq_routing_table *rt; | ||
68 | int i; | ||
69 | u8 sum; | ||
70 | |||
71 | rt = (struct irq_routing_table *) addr; | ||
72 | if (rt->signature != PIRQ_SIGNATURE || | ||
73 | rt->version != PIRQ_VERSION || | ||
74 | rt->size % 16 || | ||
75 | rt->size < sizeof(struct irq_routing_table)) | ||
76 | return NULL; | ||
77 | sum = 0; | ||
78 | for (i=0; i < rt->size; i++) | ||
79 | sum += addr[i]; | ||
80 | if (!sum) { | ||
81 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
82 | return rt; | ||
83 | } | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
61 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. | 90 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. |
62 | */ | 91 | */ |
63 | 92 | ||
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) | |||
65 | { | 94 | { |
66 | u8 *addr; | 95 | u8 *addr; |
67 | struct irq_routing_table *rt; | 96 | struct irq_routing_table *rt; |
68 | int i; | ||
69 | u8 sum; | ||
70 | 97 | ||
98 | if (pirq_table_addr) { | ||
99 | rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); | ||
100 | if (rt) | ||
101 | return rt; | ||
102 | printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); | ||
103 | } | ||
71 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { | 104 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { |
72 | rt = (struct irq_routing_table *) addr; | 105 | rt = pirq_check_routing_table(addr); |
73 | if (rt->signature != PIRQ_SIGNATURE || | 106 | if (rt) |
74 | rt->version != PIRQ_VERSION || | ||
75 | rt->size % 16 || | ||
76 | rt->size < sizeof(struct irq_routing_table)) | ||
77 | continue; | ||
78 | sum = 0; | ||
79 | for(i=0; i<rt->size; i++) | ||
80 | sum += addr[i]; | ||
81 | if (!sum) { | ||
82 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
83 | return rt; | 107 | return rt; |
84 | } | ||
85 | } | 108 | } |
86 | return NULL; | 109 | return NULL; |
87 | } | 110 | } |
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c | |||
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) | |||
45 | 45 | ||
46 | printk("PCI: Probing PCI hardware\n"); | 46 | printk("PCI: Probing PCI hardware\n"); |
47 | pci_root_bus = pcibios_scan_root(0); | 47 | pci_root_bus = pcibios_scan_root(0); |
48 | if (pci_root_bus) | ||
49 | pci_bus_add_devices(pci_root_bus); | ||
48 | 50 | ||
49 | pcibios_fixup_peer_bridges(); | 51 | pcibios_fixup_peer_bridges(); |
50 | 52 | ||
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51f4..60f0e7a1162a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -11,11 +11,9 @@ | |||
11 | 11 | ||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
15 | 16 | ||
16 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | ||
17 | u32 pci_mmcfg_base_addr; | ||
18 | |||
19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 17 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
20 | 18 | ||
21 | /* The base address of the last MMCONFIG device accessed */ | 19 | /* The base address of the last MMCONFIG device accessed */ |
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device; | |||
24 | /* | 22 | /* |
25 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 23 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
26 | */ | 24 | */ |
25 | static u32 get_base_addr(unsigned int seg, int bus) | ||
26 | { | ||
27 | int cfg_num = -1; | ||
28 | struct acpi_table_mcfg_config *cfg; | ||
29 | |||
30 | while (1) { | ||
31 | ++cfg_num; | ||
32 | if (cfg_num >= pci_mmcfg_config_num) { | ||
33 | /* something bad is going on, no cfg table is found. */ | ||
34 | /* so we fall back to the old way we used to do this */ | ||
35 | /* and just rely on the first entry to be correct. */ | ||
36 | return pci_mmcfg_config[0].base_address; | ||
37 | } | ||
38 | cfg = &pci_mmcfg_config[cfg_num]; | ||
39 | if (cfg->pci_segment_group_number != seg) | ||
40 | continue; | ||
41 | if ((cfg->start_bus_number <= bus) && | ||
42 | (cfg->end_bus_number >= bus)) | ||
43 | return cfg->base_address; | ||
44 | } | ||
45 | } | ||
27 | 46 | ||
28 | static inline void pci_exp_set_dev_base(int bus, int devfn) | 47 | static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) |
29 | { | 48 | { |
30 | u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); | 49 | u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); |
31 | if (dev_base != mmcfg_last_accessed_device) { | 50 | if (dev_base != mmcfg_last_accessed_device) { |
32 | mmcfg_last_accessed_device = dev_base; | 51 | mmcfg_last_accessed_device = dev_base; |
33 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); | 52 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); |
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
44 | 63 | ||
45 | spin_lock_irqsave(&pci_config_lock, flags); | 64 | spin_lock_irqsave(&pci_config_lock, flags); |
46 | 65 | ||
47 | pci_exp_set_dev_base(bus, devfn); | 66 | pci_exp_set_dev_base(seg, bus, devfn); |
48 | 67 | ||
49 | switch (len) { | 68 | switch (len) { |
50 | case 1: | 69 | case 1: |
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
73 | 92 | ||
74 | spin_lock_irqsave(&pci_config_lock, flags); | 93 | spin_lock_irqsave(&pci_config_lock, flags); |
75 | 94 | ||
76 | pci_exp_set_dev_base(bus, devfn); | 95 | pci_exp_set_dev_base(seg, bus, devfn); |
77 | 96 | ||
78 | switch (len) { | 97 | switch (len) { |
79 | case 1: | 98 | case 1: |
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void) | |||
101 | { | 120 | { |
102 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 121 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
103 | goto out; | 122 | goto out; |
104 | if (!pci_mmcfg_base_addr) | 123 | |
124 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
125 | if ((pci_mmcfg_config_num == 0) || | ||
126 | (pci_mmcfg_config == NULL) || | ||
127 | (pci_mmcfg_config[0].base_address == 0)) | ||
105 | goto out; | 128 | goto out; |
106 | 129 | ||
107 | /* Kludge for now. Don't use mmconfig on AMD systems because | 130 | /* Kludge for now. Don't use mmconfig on AMD systems because |
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c | |||
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void) | |||
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | pci_root_bus = pcibios_scan_root(0); | 117 | pci_root_bus = pcibios_scan_root(0); |
118 | if (pci_root_bus) | ||
119 | pci_bus_add_devices(pci_root_bus); | ||
118 | if (num_online_nodes() > 1) | 120 | if (num_online_nodes() > 1) |
119 | for_each_online_node(quad) { | 121 | for_each_online_node(quad) { |
120 | if (quad == 0) | 122 | if (quad == 0) |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69f3..a80f0f55ff51 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 | 27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 |
28 | 28 | ||
29 | extern unsigned int pci_probe; | 29 | extern unsigned int pci_probe; |
30 | extern unsigned long pirq_table_addr; | ||
30 | 31 | ||
31 | /* pci-i386.c */ | 32 | /* pci-i386.c */ |
32 | 33 | ||