diff options
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cyrix.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/efi.c | 89 | ||||
-rw-r--r-- | arch/i386/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 32 | ||||
-rw-r--r-- | arch/i386/kernel/nmi.c | 8 | ||||
-rw-r--r-- | arch/i386/kernel/paravirt.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/sysenter.c | 14 |
8 files changed, 115 insertions, 52 deletions
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 { static int has_N44_O17_errata[NR_CPUS]; -static int has_N60_errata[NR_CPUS]; static unsigned int stock_freq; static struct cpufreq_driver p4clockmod_driver; static unsigned int cpufreq_p4_get(unsigned int cpu); @@ -224,12 +223,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) case 0x0f12: has_N44_O17_errata[policy->cpu] = 1; dprintk("has errata -- disabling low frequencies\n"); - break; - - case 0x0f29: - has_N60_errata[policy->cpu] = 1; - dprintk("has errata -- disabling frequencies lower than 2ghz\n"); - break; } /* get max frequency */ @@ -241,8 +234,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { if ((i<2) && (has_N44_O17_errata[policy->cpu])) p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; - else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) - p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; else p4clockmod_table[i].frequency = (stock_freq * i)/8; } diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index abcff92f994c..c0c3b59de32c 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -173,7 +173,7 @@ static void __cpuinit geode_configure(void) ccr4 = getCx86(CX86_CCR4); ccr4 |= 0x38; /* FPU fast, DTE cache, Mem bypass */ - setCx86(CX86_CCR4, ccr4); + setCx86(CX86_CCR3, ccr3); set_cx86_memwb(); set_cx86_reorder(); diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index b92c7f0a358a..8f9c624ace6f 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -473,6 +473,70 @@ static inline void __init check_range_for_systab(efi_memory_desc_t *md) } /* + * Wrap all the virtual calls in a way that forces the parameters on the stack. + */ + +#define efi_call_virt(f, args...) \ + ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args) + +static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) +{ + return efi_call_virt(get_time, tm, tc); +} + +static efi_status_t virt_efi_set_time (efi_time_t *tm) +{ + return efi_call_virt(set_time, tm); +} + +static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled, + efi_bool_t *pending, + efi_time_t *tm) +{ + return efi_call_virt(get_wakeup_time, enabled, pending, tm); +} + +static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled, + efi_time_t *tm) +{ + return efi_call_virt(set_wakeup_time, enabled, tm); +} + +static efi_status_t virt_efi_get_variable (efi_char16_t *name, + efi_guid_t *vendor, u32 *attr, + unsigned long *data_size, void *data) +{ + return efi_call_virt(get_variable, name, vendor, attr, data_size, data); +} + +static efi_status_t virt_efi_get_next_variable (unsigned long *name_size, + efi_char16_t *name, + efi_guid_t *vendor) +{ + return efi_call_virt(get_next_variable, name_size, name, vendor); +} + +static efi_status_t virt_efi_set_variable (efi_char16_t *name, + efi_guid_t *vendor, + unsigned long attr, + unsigned long data_size, void *data) +{ + return efi_call_virt(set_variable, name, vendor, attr, data_size, data); +} + +static efi_status_t virt_efi_get_next_high_mono_count (u32 *count) +{ + return efi_call_virt(get_next_high_mono_count, count); +} + +static void virt_efi_reset_system (int reset_type, efi_status_t status, + unsigned long data_size, + efi_char16_t *data) +{ + efi_call_virt(reset_system, reset_type, status, data_size, data); +} + +/* * This function will switch the EFI runtime services to virtual mode. * Essentially, look through the EFI memmap and map every region that * has the runtime attribute bit set in its memory descriptor and update @@ -525,22 +589,15 @@ void __init efi_enter_virtual_mode(void) * pointers in the runtime service table to the new virtual addresses. */ - efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time; - efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time; - efi.get_wakeup_time = (efi_get_wakeup_time_t *) - efi.systab->runtime->get_wakeup_time; - efi.set_wakeup_time = (efi_set_wakeup_time_t *) - efi.systab->runtime->set_wakeup_time; - efi.get_variable = (efi_get_variable_t *) - efi.systab->runtime->get_variable; - efi.get_next_variable = (efi_get_next_variable_t *) - efi.systab->runtime->get_next_variable; - efi.set_variable = (efi_set_variable_t *) - efi.systab->runtime->set_variable; - efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *) - efi.systab->runtime->get_next_high_mono_count; - efi.reset_system = (efi_reset_system_t *) - efi.systab->runtime->reset_system; + efi.get_time = virt_efi_get_time; + efi.set_time = virt_efi_set_time; + efi.get_wakeup_time = virt_efi_get_wakeup_time; + efi.set_wakeup_time = virt_efi_set_wakeup_time; + efi.get_variable = virt_efi_get_variable; + efi.get_next_variable = virt_efi_get_next_variable; + efi.set_variable = virt_efi_set_variable; + efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; + efi.reset_system = virt_efi_reset_system; } void __init 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: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ +#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) +#else + pushl $SYSENTER_RETURN +#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 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 } static int __assign_irq_vector(int irq) { - static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - int vector; + static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; + int vector, offset, i; BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); if (irq_vector[irq] > 0) return irq_vector[irq]; - current_vector += 8; - if (current_vector == SYSCALL_VECTOR) - current_vector += 8; - - if (current_vector >= FIRST_SYSTEM_VECTOR) { - offset++; - if (!(offset % 8)) - return -ENOSPC; - current_vector = FIRST_DEVICE_VECTOR + offset; - } - vector = current_vector; + offset = current_offset; +next: + vector += 8; + if (vector >= FIRST_SYSTEM_VECTOR) { + offset = (offset + 1) % 8; + vector = FIRST_DEVICE_VECTOR + offset; + } + if (vector == current_vector) + return -ENOSPC; + if (vector == SYSCALL_VECTOR) + goto next; + for (i = 0; i < NR_IRQ_VECTORS; i++) + if (irq_vector[i] == vector) + goto next; + + current_vector = vector; + current_offset = offset; irq_vector[irq] = vector; 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) if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) return 0; - /* - * If any other x86 CPU has a local APIC, then - * please test the NMI stuff there and send me the - * missing bits. Right now Intel P6/P4 and AMD K7 only. - */ - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ + nmi_watchdog = nmi; return 1; } 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 = { .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, }; -EXPORT_SYMBOL(paravirt_ops); + +/* + * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops + * semantics are subject to change. Hence we only do this + * internal-only export of this, until it gets sorted out and + * all lowlevel CPU ops used by modules are separately exported. + */ +EXPORT_SYMBOL_GPL(paravirt_ops); 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) #ifdef CONFIG_COMPAT_VDSO __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); -#else - /* - * In the non-compat case the ELF coredumping code needs the fixmap: - */ - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); #endif if (!boot_cpu_has(X86_FEATURE_SEP)) { @@ -100,6 +95,7 @@ int __init sysenter_setup(void) return 0; } +#ifndef CONFIG_COMPAT_VDSO static struct page *syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type) { @@ -146,6 +142,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) vma->vm_end = addr + PAGE_SIZE; /* MAYWRITE to allow gdb to COW and set breakpoints */ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + vma->vm_flags |= VM_ALWAYSDUMP; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &syscall_vm_ops; @@ -187,3 +190,4 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } +#endif |