aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/cpu/common.c13
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c9
-rw-r--r--arch/i386/kernel/entry.S4
-rw-r--r--arch/i386/kernel/io_apic.c32
-rw-r--r--arch/i386/kernel/nmi.c8
-rw-r--r--arch/i386/kernel/paravirt.c9
-rw-r--r--arch/i386/kernel/smpboot.c9
-rw-r--r--arch/i386/kernel/sysenter.c14
8 files changed, 56 insertions, 42 deletions
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 8689d62abd4a..8a8bbdaaf38a 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -710,11 +710,8 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle)
710 return 1; 710 return 1;
711} 711}
712 712
713/* Common CPU init for both boot and secondary CPUs */ 713void __cpuinit cpu_set_gdt(int cpu)
714static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
715{ 714{
716 struct tss_struct * t = &per_cpu(init_tss, cpu);
717 struct thread_struct *thread = &curr->thread;
718 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); 715 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
719 716
720 /* Reinit these anyway, even if they've already been done (on 717 /* Reinit these anyway, even if they've already been done (on
@@ -722,6 +719,13 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
722 the real ones). */ 719 the real ones). */
723 load_gdt(cpu_gdt_descr); 720 load_gdt(cpu_gdt_descr);
724 set_kernel_gs(); 721 set_kernel_gs();
722}
723
724/* Common CPU init for both boot and secondary CPUs */
725static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
726{
727 struct tss_struct * t = &per_cpu(init_tss, cpu);
728 struct thread_struct *thread = &curr->thread;
725 729
726 if (cpu_test_and_set(cpu, cpu_initialized)) { 730 if (cpu_test_and_set(cpu, cpu_initialized)) {
727 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); 731 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
@@ -807,6 +811,7 @@ void __cpuinit cpu_init(void)
807 local_irq_enable(); 811 local_irq_enable();
808 } 812 }
809 813
814 cpu_set_gdt(cpu);
810 _cpu_init(cpu, curr); 815 _cpu_init(cpu, curr);
811} 816}
812 817
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index bec50170b75a..4786fedca6eb 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -51,7 +51,6 @@ enum {
51 51
52 52
53static int has_N44_O17_errata[NR_CPUS]; 53static int has_N44_O17_errata[NR_CPUS];
54static int has_N60_errata[NR_CPUS];
55static unsigned int stock_freq; 54static unsigned int stock_freq;
56static struct cpufreq_driver p4clockmod_driver; 55static struct cpufreq_driver p4clockmod_driver;
57static unsigned int cpufreq_p4_get(unsigned int cpu); 56static unsigned int cpufreq_p4_get(unsigned int cpu);
@@ -224,12 +223,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
224 case 0x0f12: 223 case 0x0f12:
225 has_N44_O17_errata[policy->cpu] = 1; 224 has_N44_O17_errata[policy->cpu] = 1;
226 dprintk("has errata -- disabling low frequencies\n"); 225 dprintk("has errata -- disabling low frequencies\n");
227 break;
228
229 case 0x0f29:
230 has_N60_errata[policy->cpu] = 1;
231 dprintk("has errata -- disabling frequencies lower than 2ghz\n");
232 break;
233 } 226 }
234 227
235 /* get max frequency */ 228 /* get max frequency */
@@ -241,8 +234,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
241 for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { 234 for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
242 if ((i<2) && (has_N44_O17_errata[policy->cpu])) 235 if ((i<2) && (has_N44_O17_errata[policy->cpu]))
243 p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; 236 p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
244 else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000)
245 p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
246 else 237 else
247 p4clockmod_table[i].frequency = (stock_freq * i)/8; 238 p4clockmod_table[i].frequency = (stock_freq * i)/8;
248 } 239 }
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 06461b8b715d..5e47683fc63a 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -302,12 +302,16 @@ sysenter_past_esp:
302 pushl $(__USER_CS) 302 pushl $(__USER_CS)
303 CFI_ADJUST_CFA_OFFSET 4 303 CFI_ADJUST_CFA_OFFSET 4
304 /*CFI_REL_OFFSET cs, 0*/ 304 /*CFI_REL_OFFSET cs, 0*/
305#ifndef CONFIG_COMPAT_VDSO
305 /* 306 /*
306 * Push current_thread_info()->sysenter_return to the stack. 307 * Push current_thread_info()->sysenter_return to the stack.
307 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words 308 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
308 * pushed above; +8 corresponds to copy_thread's esp0 setting. 309 * pushed above; +8 corresponds to copy_thread's esp0 setting.
309 */ 310 */
310 pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) 311 pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
312#else
313 pushl $SYSENTER_RETURN
314#endif
311 CFI_ADJUST_CFA_OFFSET 4 315 CFI_ADJUST_CFA_OFFSET 4
312 CFI_REL_OFFSET eip, 0 316 CFI_REL_OFFSET eip, 0
313 317
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 2424cc9c7b3d..6a3875f81a0a 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1227,26 +1227,32 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }
1227 1227
1228static int __assign_irq_vector(int irq) 1228static int __assign_irq_vector(int irq)
1229{ 1229{
1230 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 1230 static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
1231 int vector; 1231 int vector, offset, i;
1232 1232
1233 BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); 1233 BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
1234 1234
1235 if (irq_vector[irq] > 0) 1235 if (irq_vector[irq] > 0)
1236 return irq_vector[irq]; 1236 return irq_vector[irq];
1237 1237
1238 current_vector += 8;
1239 if (current_vector == SYSCALL_VECTOR)
1240 current_vector += 8;
1241
1242 if (current_vector >= FIRST_SYSTEM_VECTOR) {
1243 offset++;
1244 if (!(offset % 8))
1245 return -ENOSPC;
1246 current_vector = FIRST_DEVICE_VECTOR + offset;
1247 }
1248
1249 vector = current_vector; 1238 vector = current_vector;
1239 offset = current_offset;
1240next:
1241 vector += 8;
1242 if (vector >= FIRST_SYSTEM_VECTOR) {
1243 offset = (offset + 1) % 8;
1244 vector = FIRST_DEVICE_VECTOR + offset;
1245 }
1246 if (vector == current_vector)
1247 return -ENOSPC;
1248 if (vector == SYSCALL_VECTOR)
1249 goto next;
1250 for (i = 0; i < NR_IRQ_VECTORS; i++)
1251 if (irq_vector[i] == vector)
1252 goto next;
1253
1254 current_vector = vector;
1255 current_offset = offset;
1250 irq_vector[irq] = vector; 1256 irq_vector[irq] = vector;
1251 1257
1252 return vector; 1258 return vector;
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index a5e34d655965..1a6f8bb8881c 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -310,13 +310,7 @@ static int __init setup_nmi_watchdog(char *str)
310 310
311 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) 311 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE))
312 return 0; 312 return 0;
313 /* 313
314 * If any other x86 CPU has a local APIC, then
315 * please test the NMI stuff there and send me the
316 * missing bits. Right now Intel P6/P4 and AMD K7 only.
317 */
318 if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0))
319 return 0; /* no lapic support */
320 nmi_watchdog = nmi; 314 nmi_watchdog = nmi;
321 return 1; 315 return 1;
322} 316}
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c
index 3dceab5828f1..e55fd05da0f5 100644
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -566,4 +566,11 @@ struct paravirt_ops paravirt_ops = {
566 .irq_enable_sysexit = native_irq_enable_sysexit, 566 .irq_enable_sysexit = native_irq_enable_sysexit,
567 .iret = native_iret, 567 .iret = native_iret,
568}; 568};
569EXPORT_SYMBOL(paravirt_ops); 569
570/*
571 * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops
572 * semantics are subject to change. Hence we only do this
573 * internal-only export of this, until it gets sorted out and
574 * all lowlevel CPU ops used by modules are separately exported.
575 */
576EXPORT_SYMBOL_GPL(paravirt_ops);
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index dea7ef9d3e82..8c6c8c52b95c 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -596,6 +596,12 @@ static void __cpuinit start_secondary(void *unused)
596void __devinit initialize_secondary(void) 596void __devinit initialize_secondary(void)
597{ 597{
598 /* 598 /*
599 * switch to the per CPU GDT we already set up
600 * in do_boot_cpu()
601 */
602 cpu_set_gdt(current_thread_info()->cpu);
603
604 /*
599 * We don't actually need to load the full TSS, 605 * We don't actually need to load the full TSS,
600 * basically just the stack pointer and the eip. 606 * basically just the stack pointer and the eip.
601 */ 607 */
@@ -972,9 +978,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
972 /* Stack for startup_32 can be just as for start_secondary onwards */ 978 /* Stack for startup_32 can be just as for start_secondary onwards */
973 stack_start.esp = (void *) idle->thread.esp; 979 stack_start.esp = (void *) idle->thread.esp;
974 980
975 start_pda = cpu_pda(cpu);
976 cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu);
977
978 irq_ctx_init(cpu); 981 irq_ctx_init(cpu);
979 982
980 x86_cpu_to_apicid[cpu] = apicid; 983 x86_cpu_to_apicid[cpu] = apicid;
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
index 7de9117b5a3a..5da744204d10 100644
--- a/arch/i386/kernel/sysenter.c
+++ b/arch/i386/kernel/sysenter.c
@@ -79,11 +79,6 @@ int __init sysenter_setup(void)
79#ifdef CONFIG_COMPAT_VDSO 79#ifdef CONFIG_COMPAT_VDSO
80 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); 80 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
81 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); 81 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
82#else
83 /*
84 * In the non-compat case the ELF coredumping code needs the fixmap:
85 */
86 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO);
87#endif 82#endif
88 83
89 if (!boot_cpu_has(X86_FEATURE_SEP)) { 84 if (!boot_cpu_has(X86_FEATURE_SEP)) {
@@ -100,6 +95,7 @@ int __init sysenter_setup(void)
100 return 0; 95 return 0;
101} 96}
102 97
98#ifndef CONFIG_COMPAT_VDSO
103static struct page *syscall_nopage(struct vm_area_struct *vma, 99static struct page *syscall_nopage(struct vm_area_struct *vma,
104 unsigned long adr, int *type) 100 unsigned long adr, int *type)
105{ 101{
@@ -146,6 +142,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
146 vma->vm_end = addr + PAGE_SIZE; 142 vma->vm_end = addr + PAGE_SIZE;
147 /* MAYWRITE to allow gdb to COW and set breakpoints */ 143 /* MAYWRITE to allow gdb to COW and set breakpoints */
148 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; 144 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
145 /*
146 * Make sure the vDSO gets into every core dump.
147 * Dumping its contents makes post-mortem fully interpretable later
148 * without matching up the same kernel and hardware config to see
149 * what PC values meant.
150 */
151 vma->vm_flags |= VM_ALWAYSDUMP;
149 vma->vm_flags |= mm->def_flags; 152 vma->vm_flags |= mm->def_flags;
150 vma->vm_page_prot = protection_map[vma->vm_flags & 7]; 153 vma->vm_page_prot = protection_map[vma->vm_flags & 7];
151 vma->vm_ops = &syscall_vm_ops; 154 vma->vm_ops = &syscall_vm_ops;
@@ -187,3 +190,4 @@ int in_gate_area_no_task(unsigned long addr)
187{ 190{
188 return 0; 191 return 0;
189} 192}
193#endif