From 58d9ce7d751fa11c6c8ea5dcd4d63b320aae1363 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Mon, 22 Jan 2007 20:40:34 -0800 Subject: [PATCH] Revert nmi_known_cpu() check during boot option parsing Commit f2802e7f571c05f9a901b1f5bd144aa730ccc88e and its x86 version (b7471c6da94d30d3deadc55986cc38d1ff57f9ca) adds nmi_known_cpu() check while parsing boot options in x86_64 and i386. With that, "nmi_watchdog=2" stops working for me on Intel Core 2 CPU based system. The problem is, setup_nmi_watchdog is called while parsing the boot option and identify_cpu is not done yet. So, the return value of nmi_known_cpu() is not valid at this point. So revert that check. This should not have any adverse effect as the nmi_known_cpu() check is done again later in enable_lapic_nmi_watchdog(). Signed-off-by: Venkatesh Pallipadi Cc: Don Zickus Cc: Andi Kleen Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/nmi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch/i386') 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; } -- cgit v1.2.3 From 0dbe5a111382fd1320ff4b1d889e5b8c41290619 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 22 Jan 2007 20:40:36 -0800 Subject: [PATCH] paravirt: mark the paravirt_ops export internal The paravirt subsystem is still in flux so all exports from it are definitely internal use only. The APIs around this /will/ change. Signed-off-by: Ingo Molnar Cc: Andi Kleen Cc: Zachary Amsden Cc: Jeremy Fitzhardinge Acked-by: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/paravirt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/i386') 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); -- cgit v1.2.3 From a1f3bb9ae4497a2ed3eac773fd7798ac33a0371f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 26 Jan 2007 00:56:46 -0800 Subject: [PATCH] Fix CONFIG_COMPAT_VDSO I wouldn't mind if CONFIG_COMPAT_VDSO went away entirely. But if it's there, it should work properly. Currently it's quite haphazard: both real vma and fixmap are mapped, both are put in the two different AT_* slots, sysenter returns to the vma address rather than the fixmap address, and core dumps yet are another story. This patch makes CONFIG_COMPAT_VDSO disable the real vma and use the fixmap area consistently. This makes it actually compatible with what the old vdso implementation did. Signed-off-by: Roland McGrath Cc: Ingo Molnar Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/entry.S | 4 ++++ arch/i386/kernel/sysenter.c | 2 ++ include/asm-i386/elf.h | 7 +++---- include/asm-i386/fixmap.h | 2 ++ include/asm-i386/page.h | 2 ++ 5 files changed, 13 insertions(+), 4 deletions(-) (limited to 'arch/i386') 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/sysenter.c b/arch/i386/kernel/sysenter.c index 7de9117b5a3a..454d12df59ea 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -100,6 +100,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) { @@ -187,3 +188,4 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } +#endif diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index 45d21a0c95bf..0515d61d5411 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h @@ -143,11 +143,8 @@ extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct # define VDSO_PRELINK 0 #endif -#define VDSO_COMPAT_SYM(x) \ - (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) - #define VDSO_SYM(x) \ - (VDSO_BASE + (unsigned long)(x) - VDSO_PRELINK) + (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) @@ -156,10 +153,12 @@ extern void __kernel_vsyscall; #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) +#ifndef CONFIG_COMPAT_VDSO #define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); +#endif extern unsigned int vdso_enabled; diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h index 02428cb36621..3e9f610c35df 100644 --- a/include/asm-i386/fixmap.h +++ b/include/asm-i386/fixmap.h @@ -23,6 +23,8 @@ extern unsigned long __FIXADDR_TOP; #else #define __FIXADDR_TOP 0xfffff000 +#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) +#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) #endif #ifndef __ASSEMBLY__ diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index fd3f64ace248..7b19f454761d 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -143,7 +143,9 @@ extern int page_is_ram(unsigned long pagenr); #include #include +#ifndef CONFIG_COMPAT_VDSO #define __HAVE_ARCH_GATE_AREA 1 +#endif #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */ -- cgit v1.2.3 From f47aef55d9a18945fcdd7fd6bf01121ce973b91b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 26 Jan 2007 00:56:49 -0800 Subject: [PATCH] i386 vDSO: use VM_ALWAYSDUMP This patch fixes core dumps to include the vDSO vma, which is left out now. It removes the special-case core writing macros, which were not doing the right thing for the vDSO vma anyway. Instead, it uses VM_ALWAYSDUMP in the vma; there is no need for the fixmap page to be installed. It handles the CONFIG_COMPAT_VDSO case by making elf_core_dump use the fake vma from get_gate_vma after real vmas in the same way the /proc/PID/maps code does. This changes core dumps so they no longer include the non-PT_LOAD phdrs from the vDSO. I made the change to add them in the first place, but in turned out that nothing ever wanted them there since the advent of NT_AUXV. It's cleaner to leave them out, and just let the phdrs inside the vDSO image speak for themselves. Signed-off-by: Roland McGrath Cc: Ingo Molnar Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/sysenter.c | 12 +++++++----- fs/binfmt_elf.c | 38 +++++++++++++++++++++++++++++++++++--- include/asm-i386/elf.h | 44 -------------------------------------------- mm/memory.c | 7 +++++++ 4 files changed, 49 insertions(+), 52 deletions(-) (limited to 'arch/i386') diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 454d12df59ea..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)) { @@ -147,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; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6fec8bfa6bac..90461f49e902 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1428,6 +1428,32 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) return sz; } +static struct vm_area_struct *first_vma(struct task_struct *tsk, + struct vm_area_struct *gate_vma) +{ + struct vm_area_struct *ret = tsk->mm->mmap; + + if (ret) + return ret; + return gate_vma; +} +/* + * Helper function for iterating across a vma list. It ensures that the caller + * will visit `gate_vma' prior to terminating the search. + */ +static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, + struct vm_area_struct *gate_vma) +{ + struct vm_area_struct *ret; + + ret = this_vma->vm_next; + if (ret) + return ret; + if (this_vma == gate_vma) + return NULL; + return gate_vma; +} + /* * Actual dumper * @@ -1443,7 +1469,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) int segs; size_t size = 0; int i; - struct vm_area_struct *vma; + struct vm_area_struct *vma, *gate_vma; struct elfhdr *elf = NULL; loff_t offset = 0, dataoff, foffset; unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; @@ -1529,6 +1555,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) segs += ELF_CORE_EXTRA_PHDRS; #endif + gate_vma = get_gate_vma(current); + if (gate_vma != NULL) + segs++; + /* Set up header */ fill_elf_header(elf, segs + 1); /* including notes section */ @@ -1596,7 +1626,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ - for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { + for (vma = first_vma(current, gate_vma); vma != NULL; + vma = next_vma(vma, gate_vma)) { struct elf_phdr phdr; size_t sz; @@ -1645,7 +1676,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* Align to page */ DUMP_SEEK(dataoff - foffset); - for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { + for (vma = first_vma(current, gate_vma); vma != NULL; + vma = next_vma(vma, gate_vma)) { unsigned long addr; if (!maydump(vma)) diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index 0515d61d5411..369035dfe4b6 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h @@ -168,50 +168,6 @@ do if (vdso_enabled) { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ } while (0) -/* - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out - * extra segments containing the vsyscall DSO contents. Dumping its - * contents makes post-mortem fully interpretable later without matching up - * the same kernel and hardware config to see what PC values meant. - * Dumping its extra ELF program headers includes all the other information - * a debugger needs to easily find how the vsyscall DSO was being used. - */ -#define ELF_CORE_EXTRA_PHDRS (VDSO_HIGH_EHDR->e_phnum) -#define ELF_CORE_WRITE_EXTRA_PHDRS \ -do { \ - const struct elf_phdr *const vsyscall_phdrs = \ - (const struct elf_phdr *) (VDSO_HIGH_BASE \ - + VDSO_HIGH_EHDR->e_phoff); \ - int i; \ - Elf32_Off ofs = 0; \ - for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ - struct elf_phdr phdr = vsyscall_phdrs[i]; \ - if (phdr.p_type == PT_LOAD) { \ - BUG_ON(ofs != 0); \ - ofs = phdr.p_offset = offset; \ - phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ - phdr.p_filesz = phdr.p_memsz; \ - offset += phdr.p_filesz; \ - } \ - else \ - phdr.p_offset += ofs; \ - phdr.p_paddr = 0; /* match other core phdrs */ \ - DUMP_WRITE(&phdr, sizeof(phdr)); \ - } \ -} while (0) -#define ELF_CORE_WRITE_EXTRA_DATA \ -do { \ - const struct elf_phdr *const vsyscall_phdrs = \ - (const struct elf_phdr *) (VDSO_HIGH_BASE \ - + VDSO_HIGH_EHDR->e_phoff); \ - int i; \ - for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ - if (vsyscall_phdrs[i].p_type == PT_LOAD) \ - DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ - PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ - } \ -} while (0) - #endif #endif diff --git a/mm/memory.c b/mm/memory.c index 5beb4b894c5a..ef09f0acb1d8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2608,6 +2608,13 @@ static int __init gate_vma_init(void) gate_vma.vm_end = FIXADDR_USER_END; gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; gate_vma.vm_page_prot = __P101; + /* + * 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. + */ + gate_vma.vm_flags |= VM_ALWAYSDUMP; return 0; } __initcall(gate_vma_init); -- cgit v1.2.3 From 3453c8478a228d9b374956ea99256163f1a0c88c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 29 Jan 2007 00:07:04 -0500 Subject: [CPUFREQ] Remove unneeded errata workaround from p4-clockmod. This workaround unnecessarily cripples functionality to work around an errata that doesn't seem possible to hit due to us using the automatic clock throttling in the p4 mcheck code. See http://lkml.org/lkml/2006/10/28/148 for complete reasoning and lack of disconsent. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/i386') 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; } -- cgit v1.2.3 From 8339f0008c47cdd921c73f6d53d5588b5484f93c Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 29 Jan 2007 13:19:05 -0700 Subject: [PATCH] i386: In assign_irq_vector look at all vectors before giving up When the world was a simple and static place setting up irqs was easy. It sufficed to allocate a linux irq number and a find a free cpu vector we could receive that linux irq on. In those days it was a safe assumption that any allocated vector was actually in use so after one global pass through all of the vectors we would have none left. These days things are much more dynamic with interrupt controllers (in the form of MSI or MSI-X) appearing on plug in cards and linux irqs appearing and disappearing. As these irqs come and go vectors are allocated and freed, invalidating the ancient assumption that all allocated vectors stayed in use forever. So this patch modifies the vector allocator to walk through every possible vector before giving up, and to check to see if a vector is in use before assigning it. With these changes we stop leaking freed vectors and it becomes possible to allocate and free irq vectors all day long. This changed was modeled after the vector allocator on x86_64 where this limitation has already been removed. In essence we don't update the static variables that hold the position of the last vector we allocated until have successfully allocated another vector. This allows us to detect if we have completed one complete scan through all of the possible vectors. Acked-by: Auke Kok Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'arch/i386') 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; -- cgit v1.2.3 From aaba6d4bf6f2a52a0c30ad1da4374ba24bd7163b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 1 Feb 2007 13:52:28 +0000 Subject: [PATCH] mca_nmi_hook() can be called at any point ... and having it __init is a bad idea. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/i386/mach-default/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386') diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index c511705c386c..cc2f519b2f7f 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c @@ -102,7 +102,7 @@ void __init time_init_hook(void) * along the MCA bus. Use this to hook into that chain if you will need * it. **/ -void __init mca_nmi_hook(void) +void mca_nmi_hook(void) { /* If I recall correctly, there's a whole bunch of other things that * we can do to check for NMI problems, but that's all I know about -- cgit v1.2.3 From 2a3d4f1f1f839e354ebd7d40b2d5d8ac8481a930 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 1 Feb 2007 13:52:23 +0000 Subject: [PATCH] __crc_... is intended to be absolute i386 boot/compressed/relocs checks for absolute symbols and warns about unexpected ones. If you build with modversions, you get ~2500 warnings about __crc_. These suckers are really absolute symbols - we do _not_ want to modify them on relocation. They are generated by genksyms - EXPORT_... generates a weak alias, then genksyms produces an ld script with __crc_ = and it's fed to ld to produce the final object file. Their only use is to match kernel and module at modprobe time; they _must_ be absolute. boot/compressed/relocs has a whitelist of known absolute symbols, but it doesn't know about __crc_... stuff. As the result, we get shitloads of false positives on any ld(1) version. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/i386/boot/compressed/relocs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/i386') diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c index 468da89153c4..881951ca03e1 100644 --- a/arch/i386/boot/compressed/relocs.c +++ b/arch/i386/boot/compressed/relocs.c @@ -43,6 +43,8 @@ static int is_safe_abs_reloc(const char* sym_name) /* Match found */ return 1; } + if (strncmp(sym_name, "__crc_", 6) == 0) + return 1; return 0; } -- cgit v1.2.3 From 435f8a605d3b56bb96212f4d70b62ecbd0629340 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 2 Feb 2007 08:07:42 -0800 Subject: Revert "[PATCH] fix typo in geode_configre()@cyrix.c" This reverts commit e4f0ae0ea63caceff37a13f281a72652b7ea71ba. It's not wrong, but it's not right either, and everybody seems to agree that the right fix is probably to do the ccr3 write after the ccr4 one (and that we also should clean it up a bit). And after that we need to really validate that all the bits that we write to ccr4 actually do work. The old 2.6.19 code was insane, and basically didn't change ccr4 at all (even though it certainly looks like it was the *intent* to do so). So let's revert the change that may fix things, just because it's not what was actually ever tested when the code was written, even if it _was_ the intent. There's a discussion on http://lkml.org/lkml/2007/1/9/63 that was started by the patch that now gets reverted, and that discussion may well contain the proper long-term fix. Suggested-by: Adrian Bunk Acked-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/cyrix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386') 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(); -- cgit v1.2.3 From 40c373cc3af9720d1cec0e32c3da26b1d220a95b Mon Sep 17 00:00:00 2001 From: Frédéric Riss Date: Tue, 30 Jan 2007 21:41:17 +0100 Subject: [PATCH] EFI x86: pass firmware call parameters on the stack When calling into the EFI firmware, the parameters need to be passed on the stack. The recent change to use -mregparm=3 breaks x86 EFI support. This patch is needed to allow the new Intel-based Macs to suspend to ram (efi.get_time is called during the suspend phase). Signed-off-by: Frederic Riss Signed-off-by: Linus Torvalds --- arch/i386/kernel/efi.c | 89 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 16 deletions(-) (limited to 'arch/i386') 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 @@ -472,6 +472,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 @@ -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 -- cgit v1.2.3