diff options
Diffstat (limited to 'arch')
152 files changed, 980 insertions, 1131 deletions
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index f042cc42b00..dbe327d32b6 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -36,7 +36,6 @@ #include <asm/cacheflush.h> #include <asm/vga.h> -#define __KERNEL_SYSCALLS__ #include <asm/unistd.h> extern struct hwrpb_struct *hwrpb; @@ -116,7 +115,7 @@ EXPORT_SYMBOL(sys_dup); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_write); EXPORT_SYMBOL(sys_lseek); -EXPORT_SYMBOL(execve); +EXPORT_SYMBOL(kernel_execve); EXPORT_SYMBOL(sys_setsid); EXPORT_SYMBOL(sys_wait4); diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 01ecd09d4a6..c95e95e1ab0 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -655,12 +655,12 @@ kernel_thread: .end kernel_thread /* - * execve(path, argv, envp) + * kernel_execve(path, argv, envp) */ .align 4 - .globl execve - .ent execve -execve: + .globl kernel_execve + .ent kernel_execve +kernel_execve: /* We can be called from a module. */ ldgp $gp, 0($27) lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) @@ -704,7 +704,7 @@ execve: 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) ret -.end execve +.end kernel_execve /* diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 73c7622b529..8a31fc1bfb1 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -402,15 +402,15 @@ osf_utsname(char __user *name) down_read(&uts_sem); error = -EFAULT; - if (copy_to_user(name + 0, system_utsname.sysname, 32)) + if (copy_to_user(name + 0, utsname()->sysname, 32)) goto out; - if (copy_to_user(name + 32, system_utsname.nodename, 32)) + if (copy_to_user(name + 32, utsname()->nodename, 32)) goto out; - if (copy_to_user(name + 64, system_utsname.release, 32)) + if (copy_to_user(name + 64, utsname()->release, 32)) goto out; - if (copy_to_user(name + 96, system_utsname.version, 32)) + if (copy_to_user(name + 96, utsname()->version, 32)) goto out; - if (copy_to_user(name + 128, system_utsname.machine, 32)) + if (copy_to_user(name + 128, utsname()->machine, 32)) goto out; error = 0; @@ -449,8 +449,8 @@ osf_getdomainname(char __user *name, int namelen) down_read(&uts_sem); for (i = 0; i < len; ++i) { - __put_user(system_utsname.domainname[i], name + i); - if (system_utsname.domainname[i] == '\0') + __put_user(utsname()->domainname[i], name + i); + if (utsname()->domainname[i] == '\0') break; } up_read(&uts_sem); @@ -607,12 +607,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss) asmlinkage long osf_sysinfo(int command, char __user *buf, long count) { - static char * sysinfo_table[] = { - system_utsname.sysname, - system_utsname.nodename, - system_utsname.release, - system_utsname.version, - system_utsname.machine, + char *sysinfo_table[] = { + utsname()->sysname, + utsname()->nodename, + utsname()->release, + utsname()->version, + utsname()->machine, "alpha", /* instruction set architecture */ "dummy", /* hardware serial number */ "dummy", /* hardware manufacturer */ diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 9d7dff27f81..75692320386 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp) static struct tty_driver *srmcons_driver; -static struct tty_operations srmcons_ops = { +static const struct tty_operations srmcons_ops = { .open = srmcons_open, .close = srmcons_close, .write = srmcons_write, diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 0a722e77c14..6bbd93dd186 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -348,7 +348,7 @@ static void __init setup_processor(void) cpu_name, processor_id, (int)processor_id & 15, proc_arch[cpu_architecture()], cr_alignment); - sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; #ifndef CONFIG_ARM_THUMB diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 68e9634d260..421329f5e18 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -36,7 +36,9 @@ * The online bitmask indicates that the CPU is up and running. */ cpumask_t cpu_possible_map; +EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; +EXPORT_SYMBOL(cpu_online_map); /* * as from 2.5, kernels no longer have an init_tasks structure diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 8170af47143..00c18d35913 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -279,7 +279,7 @@ out: return error; } -long execve(const char *filename, char **argv, char **envp) +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) { struct pt_regs regs; int ret; @@ -317,7 +317,7 @@ long execve(const char *filename, char **argv, char **envp) out: return ret; } -EXPORT_SYMBOL(execve); +EXPORT_SYMBOL(kernel_execve); /* * Since loff_t is a 64 bit type we avoid a lot of ABI hastle diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c index e7eb070f794..466ddb54b44 100644 --- a/arch/arm26/kernel/setup.c +++ b/arch/arm26/kernel/setup.c @@ -143,7 +143,7 @@ static void __init setup_processor(void) dump_cpu_info(); - sprintf(system_utsname.machine, "%s", list->arch_name); + sprintf(init_utsname()->machine, "%s", list->arch_name); sprintf(elf_platform, "%s", list->elf_name); elf_hwcap = list->elf_hwcap; diff --git a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c index 85457897b8a..dc05aba58ba 100644 --- a/arch/arm26/kernel/sys_arm.c +++ b/arch/arm26/kernel/sys_arm.c @@ -283,7 +283,7 @@ out: } /* FIXME - see if this is correct for arm26 */ -long execve(const char *filename, char **argv, char **envp) +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) { struct pt_regs regs; int ret; @@ -320,4 +320,4 @@ long execve(const char *filename, char **argv, char **envp) return ret; } -EXPORT_SYMBOL(execve); +EXPORT_SYMBOL(kernel_execve); diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c index 6ec5693da44..8deb6003ee6 100644 --- a/arch/avr32/kernel/sys_avr32.c +++ b/arch/avr32/kernel/sys_avr32.c @@ -49,3 +49,17 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, fput(file); return error; } + +int kernel_execve(const char *file, char **argv, char **envp) +{ + register long scno asm("r8") = __NR_execve; + register long sc1 asm("r12") = (long)file; + register long sc2 asm("r11") = (long)argv; + register long sc3 asm("r10") = (long)envp; + + asm volatile("scall" + : "=r"(sc1) + : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3) + : "cc", "memory"); + return sc1; +} diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 464ecaec3bc..2d0023f2d49 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -28,6 +28,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; /* CPU masks */ cpumask_t cpu_online_map = CPU_MASK_NONE; +EXPORT_SYMBOL(cpu_online_map); cpumask_t phys_cpu_present_map = CPU_MASK_NONE; EXPORT_SYMBOL(phys_cpu_present_map); diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 7af3d5d43e4..ca8b45a0fe2 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -160,7 +160,7 @@ setup_arch(char **cmdline_p) show_etrax_copyright(); /* Setup utsname */ - strcpy(system_utsname.machine, cris_machine_name); + strcpy(init_utsname()->machine, cris_machine_name); } static void *c_start(struct seq_file *m, loff_t *pos) diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index 32db3499c46..e8f73ed28b5 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile @@ -8,7 +8,7 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o extra-y:= head.o init_task.o vmlinux.lds obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ - process.o traps.o ptrace.o signal.o dma.o \ + kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ debug-stub.o irq.o sleep.o uaccess.o diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S new file mode 100644 index 00000000000..9b074a16a05 --- /dev/null +++ b/arch/frv/kernel/kernel_execve.S @@ -0,0 +1,33 @@ +/* in-kernel program execution + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/linkage.h> +#include <asm/unistd.h> + +############################################################################### +# +# Do a system call from kernel instead of calling sys_execve so we end up with +# proper pt_regs. +# +# int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +# +# On entry: GR8/GR9/GR10: arguments to function +# On return: GR8: syscall return. +# +############################################################################### + .globl kernel_execve + .type kernel_execve,@function +kernel_execve: + setlos __NR_execve,gr7 + tira gr0,#0 + bralr + + .size kernel_execve,.-kernel_execve diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index 0f61b7ad69a..302a2dfe634 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c @@ -25,6 +25,7 @@ #include <asm/cachectl.h> #include <asm/traps.h> #include <asm/ipc.h> +#include <asm/unistd.h> /* * sys_pipe() is the normal C calling standard for creating @@ -280,3 +281,26 @@ asmlinkage void syscall_print(void *dummy,...) ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0); } #endif + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register long res __asm__("er0"); + register const char * _a __asm__("er1") = filename; + register void *_b __asm__("er2") = argv; + register void *_c __asm__("er3") = envp; + __asm__ __volatile__ ("mov.l %1,er0\n\t" + "trapa #0\n\t" + : "=r" (res) + : "g" (__NR_execve), + "g" (_a), + "g" (_b), + "g" (_c) + : "cc", "memory"); + return res; +} + + diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 3fd2f256f2b..af219e51734 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1142,7 +1142,7 @@ source "arch/i386/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index afe6505ca0b..d98e44b16fe 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -230,20 +230,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; - struct kretprobe_instance *ri; - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - - add_rp_inst(ri); - } else { - rp->nmissed++; - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -359,7 +359,7 @@ no_kprobe: void __kprobes kretprobe_trampoline_holder(void) { asm volatile ( ".global kretprobe_trampoline\n" - "kretprobe_trampoline: \n" + "kretprobe_trampoline: \n" " pushf\n" /* skip cs, eip, orig_eax, es, ds */ " subl $20, %esp\n" @@ -395,14 +395,15 @@ no_kprobe: */ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -413,14 +414,14 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler){ __get_cpu_var(current_kprobe) = &ri->rp->kp; @@ -429,7 +430,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) } orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri); + recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) /* @@ -444,6 +445,10 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } return (void*)orig_ret_address; } diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 96cd0232e1e..dad02a960e0 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -297,9 +297,9 @@ void show_regs(struct pt_regs * regs) if (user_mode_vm(regs)) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx %s (%s %.*s)\n", - regs->eflags, print_tainted(), system_utsname.release, - (int)strcspn(system_utsname.version, " "), - system_utsname.version); + regs->eflags, print_tainted(), init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 0831f709f77..9d93ecf6d99 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -612,6 +612,7 @@ extern struct { /* which logical CPUs are on which nodes */ cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; +EXPORT_SYMBOL(node_2_cpu_mask); /* which node each logical CPU is on */ int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_2_node); diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c index 8fdb1fb17a5..4048397f174 100644 --- a/arch/i386/kernel/sys_i386.c +++ b/arch/i386/kernel/sys_i386.c @@ -21,6 +21,7 @@ #include <linux/utsname.h> #include <asm/uaccess.h> +#include <asm/unistd.h> #include <asm/ipc.h> /* @@ -210,7 +211,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -226,16 +227,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error |= __put_user(0,name->sysname+__OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error |= __put_user(0,name->nodename+__OLD_UTS_LEN); - error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error |= __put_user(0,name->release+__OLD_UTS_LEN); - error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error |= __put_user(0,name->version+__OLD_UTS_LEN); - error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error |= __put_user(0,name->machine+__OLD_UTS_LEN); + error = __copy_to_user(&name->sysname, &utsname()->sysname, + __OLD_UTS_LEN); + error |= __put_user(0, name->sysname + __OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename, &utsname()->nodename, + __OLD_UTS_LEN); + error |= __put_user(0, name->nodename + __OLD_UTS_LEN); + error |= __copy_to_user(&name->release, &utsname()->release, + __OLD_UTS_LEN); + error |= __put_user(0, name->release + __OLD_UTS_LEN); + error |= __copy_to_user(&name->version, &utsname()->version, + __OLD_UTS_LEN); + error |= __put_user(0, name->version + __OLD_UTS_LEN); + error |= __copy_to_user(&name->machine, &utsname()->machine, + __OLD_UTS_LEN); + error |= __put_user(0, name->machine + __OLD_UTS_LEN); up_read(&uts_sem); @@ -243,3 +249,17 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) return error; } + + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" + : "=a" (__res) + : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory"); + return __res; +} diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 6820b8d643c..00489b706d2 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -357,9 +357,9 @@ void show_registers(struct pt_regs *regs) KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", smp_processor_id(), 0xffff & regs->xcs, regs->eip, - print_tainted(), regs->eflags, system_utsname.release, - (int)strcspn(system_utsname.version, " "), - system_utsname.version); + print_tainted(), regs->eflags, init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 0b7f701d5cf..70f7eb9fed3 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -516,7 +516,7 @@ source "arch/ia64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 0daacc20ed3..246eb3d3757 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -940,7 +940,7 @@ static inline void show_serial_version(void) printk(KERN_INFO " no serial options enabled\n"); } -static struct tty_operations hp_ops = { +static const struct tty_operations hp_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 12701cf32d9..e5b1be51b19 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -492,11 +492,11 @@ GLOBAL_ENTRY(prefetch_stack) br.ret.sptk.many rp END(prefetch_stack) -GLOBAL_ENTRY(execve) +GLOBAL_ENTRY(kernel_execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL br.ret.sptk.many rp -END(execve) +END(kernel_execve) GLOBAL_ENTRY(clone) mov r15=__NR_clone // put syscall number in place diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 169ec3a7156..51217d63285 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, p->ainsn.target_br_reg = 0; /* Check for Break instruction - * Bits 37:40 Major opcode to be zero + * Bits 37:40 Major opcode to be zero * Bits 27:32 X6 to be zero * Bits 32:35 X3 to be zero */ @@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, switch (major_opcode) { case INDIRECT_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; case IP_RELATIVE_PREDICT_OPCODE: case IP_RELATIVE_BRANCH_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - break; + break; case IP_RELATIVE_CALL_OPCODE: - p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; + p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; } - } else if (bundle_encoding[template][slot] == X) { + } else if (bundle_encoding[template][slot] == X) { switch (major_opcode) { case LONG_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; @@ -258,18 +258,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot, switch (slot) { case 0: - *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); - *kprobe_inst = bundle->quad0.slot0; - break; + *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); + *kprobe_inst = bundle->quad0.slot0; + break; case 1: - *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); - kprobe_inst_p0 = bundle->quad0.slot1_p0; - kprobe_inst_p1 = bundle->quad1.slot1_p1; - *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); + *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); + kprobe_inst_p0 = bundle->quad0.slot1_p0; + kprobe_inst_p1 = bundle->quad1.slot1_p1; + *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); break; case 2: - *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); - *kprobe_inst = bundle->quad1.slot2; + *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); + *kprobe_inst = bundle->quad1.slot2; break; } } @@ -290,11 +290,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot, return -EINVAL; } - if (in_ivt_functions(addr)) { - printk(KERN_WARNING "Kprobes can't be inserted inside " + if (in_ivt_functions(addr)) { + printk(KERN_WARNING "Kprobes can't be inserted inside " "IVT functions at 0x%lx\n", addr); - return -EINVAL; - } + return -EINVAL; + } if (slot == 1 && bundle_encoding[template][1] != L) { printk(KERN_WARNING "Inserting kprobes on slot #1 " @@ -338,12 +338,13 @@ static void kretprobe_trampoline(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head; + struct hlist_head *head, empty_rp; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = ((struct fnptr *)kretprobe_trampoline)->ip; + INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -369,7 +370,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri); + recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) /* @@ -387,6 +388,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler @@ -424,14 +429,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) bundle_t *bundle; bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle; - template = bundle->quad0.template; + template = bundle->quad0.template; if(valid_kprobe_addr(template, slot, addr)) return -EINVAL; /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ - if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + if (slot == 1 && bundle_encoding[template][1] == L) + slot++; /* Get kprobe_inst and major_opcode from the bundle */ get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); @@ -489,21 +494,22 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) */ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); - unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; - unsigned long template; - int slot = ((unsigned long)p->addr & 0xf); + unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); + unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; + unsigned long template; + int slot = ((unsigned long)p->addr & 0xf); template = p->ainsn.insn->bundle.quad0.template; - if (slot == 1 && bundle_encoding[template][1] == L) - slot = 2; + if (slot == 1 && bundle_encoding[template][1] == L) + slot = 2; if (p->ainsn.inst_flag) { if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) { /* Fix relative IP address */ - regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr; + regs->cr_iip = (regs->cr_iip - bundle_addr) + + resume_addr; } if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) { @@ -540,18 +546,18 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) } if (slot == 2) { - if (regs->cr_iip == bundle_addr + 0x10) { - regs->cr_iip = resume_addr + 0x10; - } - } else { - if (regs->cr_iip == bundle_addr) { - regs->cr_iip = resume_addr; - } + if (regs->cr_iip == bundle_addr + 0x10) { + regs->cr_iip = resume_addr + 0x10; + } + } else { + if (regs->cr_iip == bundle_addr) { + regs->cr_iip = resume_addr; + } } turn_ss_off: - /* Turn off Single Step bit */ - ia64_psr(regs)->ss = 0; + /* Turn off Single Step bit */ + ia64_psr(regs)->ss = 0; } static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) @@ -587,7 +593,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs) /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + slot++; /* Get Kprobe probe instruction at given slot*/ get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode); @@ -627,7 +633,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) if (p) { if ((kcb->kprobe_status == KPROBE_HIT_SS) && (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { - ia64_psr(regs)->ss = 0; + ia64_psr(regs)->ss = 0; goto no_kprobe; } /* We have reentered the pre_kprobe_handler(), since @@ -887,7 +893,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) * fix the return address to our jprobe_inst_return() function * in the jprobes.S file */ - regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; + regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; return 1; } diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c index 20340631179..a78b45f5fe2 100644 --- a/arch/ia64/kernel/numa.c +++ b/arch/ia64/kernel/numa.c @@ -28,6 +28,7 @@ u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_to_node_map); cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; +EXPORT_SYMBOL(node_to_cpu_mask); void __cpuinit map_cpu_to_node(int cpu, int nid) { diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index ea914cc6812..51922b98086 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -8,8 +8,6 @@ * 2005-10-07 Keith Owens <kaos@sgi.com> * Add notify_die() hooks. */ -#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ - #include <linux/cpu.h> #include <linux/pm.h> #include <linux/elf.h> diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index b632b9c1e3b..462ea178f49 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -423,7 +423,7 @@ static int sn_topology_show(struct seq_file *s, void *d) "coherency_domain %d, " "region_size %d\n", - partid, system_utsname.nodename, + partid, utsname()->nodename, shubtype ? "shub2" : "shub1", (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift, system_size, sharing_size, coher, region_size); diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index a9cea32eb82..b567351f3c5 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c @@ -25,6 +25,8 @@ #include <asm/cachectl.h> #include <asm/cacheflush.h> #include <asm/ipc.h> +#include <asm/syscall.h> +#include <asm/unistd.h> /* * sys_tas() - test-and-set @@ -205,7 +207,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -223,3 +225,21 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) return -ENOSYS; } +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register long __scno __asm__ ("r7") = __NR_execve; + register long __arg3 __asm__ ("r2") = (long)(envp); + register long __arg2 __asm__ ("r1") = (long)(argv); + register long __res __asm__ ("r0") = (long)(filename); + __asm__ __volatile__ ( + "trap #" SYSCALL_VECTOR "|| nop" + : "=r" (__res) + : "r" (__scno), "0" (__res), "r" (__arg2), + "r" (__arg3) + : "memory"); + return __res; +} diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 143c552d38f..90238a8c9e1 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -27,6 +27,7 @@ #include <asm/traps.h> #include <asm/ipc.h> #include <asm/page.h> +#include <asm/unistd.h> /* * sys_pipe() is the normal C calling standard for creating @@ -663,3 +664,18 @@ asmlinkage int sys_getpagesize(void) { return PAGE_SIZE; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register long __res asm ("%d0") = __NR_execve; + register long __a asm ("%d1") = (long)(filename); + register long __b asm ("%d2") = (long)(argv); + register long __c asm ("%d3") = (long)(envp); + asm volatile ("trap #0" : "+d" (__res) + : "d" (__a), "d" (__b), "d" (__c)); + return __res; +} diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index d87e1e0a133..c3494b8447d 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c @@ -26,6 +26,7 @@ #include <asm/traps.h> #include <asm/ipc.h> #include <asm/cacheflush.h> +#include <asm/unistd.h> /* * sys_pipe() is the normal C calling standard for creating @@ -206,3 +207,17 @@ asmlinkage int sys_getpagesize(void) return PAGE_SIZE; } +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register long __res asm ("%d0") = __NR_execve; + register long __a asm ("%d1") = (long)(filename); + register long __b asm ("%d2") = (long)(argv); + register long __c asm ("%d3") = (long)(envp); + asm volatile ("trap #0" : "+d" (__res) + : "d" (__a), "d" (__b), "d" (__c)); + return __res; +} diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 30750c54bdf..87cee341eb5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -537,6 +537,7 @@ config QEMU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_SPARSEMEM_ENABLE help Qemu is a software emulator which among other architectures also @@ -1841,6 +1842,14 @@ config RWSEM_GENERIC_SPINLOCK bool default y +config LOCKDEP_SUPPORT + bool + default y + +config STACKTRACE_SUPPORT + bool + default y + source "init/Kconfig" menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" diff --git a/arch/mips/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c deleted file mode 100644 index f0024a8e329..00000000000 --- a/arch/mips/basler/excite/excite_flashtest.c +++ /dev/null @@ -1,294 +0,0 @@ -/* -* Copyright (C) 2005 by Basler Vision Technologies AG -* Author: Thies Moeller <thies.moeller@baslerweb.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/ioport.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/kernel.h> - -#include <excite.h> - -#include <asm/io.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/nand_ecc.h> -#include <linux/mtd/partitions.h> -#include <asm/rm9k-ocd.h> // for ocd_write -#include <linux/workqueue.h> // for queue - -#include "excite_nandflash.h" -#include "nandflash.h" - -#define PFX "excite flashtest: " -typedef void __iomem *io_reg_t; - -#define io_readb(__a__) __raw_readb((__a__)) -#define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__)) - - - -static inline const struct resource *excite_nandflash_get_resource( - struct platform_device *d, unsigned long flags, const char *basename) -{ - const char fmt[] = "%s_%u"; - char buf[80]; - - if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf)) - return NULL; - - return platform_get_resource_byname(d, flags, buf); -} - -static inline io_reg_t -excite_nandflash_map_regs(struct platform_device *d, const char *basename) -{ - void *result = NULL; - const struct resource *const r = - excite_nandflash_get_resource(d, IORESOURCE_MEM, basename); - if (r) - result = ioremap_nocache(r->start, r->end + 1 - r->start); - return result; -} - -/* controller and mtd information */ - -struct excite_nandflash_drvdata { - struct mtd_info board_mtd; - struct nand_chip board_chip; - io_reg_t regs; -}; - - -/* command and control functions */ -static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd) -{ - struct nand_chip *this = mtd->priv; - io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs; - - switch (cmd) { - /* Select the command latch */ - case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD; - break; - /* Deselect the command latch */ - case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; - break; - /* Select the address latch */ - case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR; - break; - /* Deselect the address latch */ - case NAND_CTL_CLRALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; - break; - /* Select the chip -- not used */ - case NAND_CTL_SETNCE: - break; - /* Deselect the chip -- not used */ - case NAND_CTL_CLRNCE: - break; - } - - this->IO_ADDR_R = this->IO_ADDR_W; -} - -/* excite_nandflash_devready() - * - * returns 0 if the nand is busy, 1 if it is ready - */ -static int excite_nandflash_devready(struct mtd_info *mtd) -{ - struct excite_nandflash_drvdata *drvdata = - container_of(mtd, struct excite_nandflash_drvdata, board_mtd); - - return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); -} - -/* device management functions */ - -/* excite_nandflash_remove - * - * called by device layer to remove the driver - * the binding to the mtd and all allocated - * resources are released - */ -static int excite_nandflash_remove(struct device *dev) -{ - struct excite_nandflash_drvdata *this = dev_get_drvdata(dev); - - pr_info(PFX "remove"); - - dev_set_drvdata(dev, NULL); - - if (this == NULL) { - pr_debug(PFX "call remove without private data!!"); - return 0; - } - - - /* free the common resources */ - if (this->regs != NULL) { - iounmap(this->regs); - this->regs = NULL; - } - - kfree(this); - - return 0; -} - -static int elapsed; - -void my_workqueue_handler(void *arg) -{ - elapsed = 1; -} - -DECLARE_WORK(sigElapsed, my_workqueue_handler, 0); - - -/* excite_nandflash_probe - * - * called by device layer when it finds a device matching - * one our driver can handled. This code checks to see if - * it can allocate all necessary resources then calls the - * nand layer to look for devices -*/ -static int excite_nandflash_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - - struct excite_nandflash_drvdata *drvdata; /* private driver data */ - struct nand_chip *board_chip; /* private flash chip data */ - struct mtd_info *board_mtd; /* mtd info for this board */ - - int err = 0; - int count = 0; - struct timeval tv,endtv; - unsigned int dt; - - pr_info(PFX "probe dev: (%p)\n", dev); - - pr_info(PFX "adjust LB timing\n"); - ocd_writel(0x00000330, LDP2); - - drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL); - if (unlikely(!drvdata)) { - printk(KERN_ERR PFX "no memory for drvdata\n"); - err = -ENOMEM; - goto mem_error; - } - - /* Initialize structures */ - memset(drvdata, 0, sizeof(*drvdata)); - - /* bind private data into driver */ - dev_set_drvdata(dev, drvdata); - - /* allocate and map the resource */ - drvdata->regs = - excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS); - - if (unlikely(!drvdata->regs)) { - printk(KERN_ERR PFX "cannot reserve register region\n"); - err = -ENXIO; - goto io_error; - } - - /* initialise our chip */ - board_chip = &drvdata->board_chip; - - board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA; - board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA; - - board_chip->hwcontrol = excite_nandflash_hwcontrol; - board_chip->dev_ready = excite_nandflash_devready; - - board_chip->chip_delay = 25; - #if 0 - /* TODO: speedup the initial scan */ - board_chip->options = NAND_USE_FLASH_BBT; - #endif - board_chip->eccmode = NAND_ECC_SOFT; - - /* link chip to mtd */ - board_mtd = &drvdata->board_mtd; - board_mtd->priv = board_chip; - - - pr_info(PFX "FlashTest\n"); - elapsed = 0; -/* schedule_delayed_work(&sigElapsed, 1*HZ); - while (!elapsed) { - io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); - count++; - } - pr_info(PFX "reads in 1 sec --> %d\n",count); -*/ - do_gettimeofday(&tv); - for (count = 0 ; count < 1000000; count ++) { - io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); - } - do_gettimeofday(&endtv); - dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec - tv.tv_usec; - pr_info(PFX "%8d us timeval\n",dt); - pr_info(PFX "EndFlashTest\n"); - -/* return with error to unload everything -*/ -io_error: - iounmap(drvdata->regs); - -mem_error: - kfree(drvdata); - - if (err == 0) - err = -EINVAL; - return err; -} - -static struct device_driver excite_nandflash_driver = { - .name = "excite_nand", - .bus = &platform_bus_type, - .probe = excite_nandflash_probe, - .remove = excite_nandflash_remove, -}; - -static int __init excite_nandflash_init(void) -{ - pr_info(PFX "register Driver (Rev: $Revision:$)\n"); - return driver_register(&excite_nandflash_driver); -} - -static void __exit excite_nandflash_exit(void) -{ - driver_unregister(&excite_nandflash_driver); - pr_info(PFX "Driver unregistered"); -} - -module_init(excite_nandflash_init); -module_exit(excite_nandflash_exit); - -MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>"); -MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver"); -MODULE_LICENSE("GPL"); diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index d3705284de3..35931bedc3d 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -161,6 +161,8 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1304,6 +1306,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index e12a475dcbf..c6a015940b4 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -167,6 +167,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -904,6 +906,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index bfade9abb76..e5358121d2d 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -149,6 +149,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -891,6 +893,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 4baf2ff1128..adf1e8c98c6 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -146,6 +146,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -889,6 +891,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 93cca1585bc..4fd29ffdfb8 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index ffd99252a83..025b960ba99 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 63eac5e89b9..80c9dd98f89 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1087,6 +1089,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 25a095f7dc4..6caa90b0e17 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -149,6 +149,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1290,6 +1292,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index dda469c842b..c6cae86c6ab 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1111,6 +1113,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index fcd3dd19bc7..72f24001c99 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -146,6 +146,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -852,6 +854,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 8683e0df12e..be901df7fef 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=128 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -828,6 +830,7 @@ CONFIG_ULTRIX_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 4ace61c9577..6133c28beb8 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index 5847c916c13..a484b7d396f 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1180,6 +1182,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig index bc4c4f125c4..21bfcdebf8f 100644 --- a/arch/mips/configs/ev64120_defconfig +++ b/arch/mips/configs/ev64120_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index eb87cbbfd03..1a5b06cfb4d 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -149,6 +149,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1184,6 +1186,7 @@ CONFIG_NLS_ISO8859_1=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index cc9b24eda9e..21d53e0c9ee 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 50092ba8aa7..e3e94c7e5ee 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -162,6 +162,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y # CONFIG_MIPS_INSANE_LARGE is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -980,6 +982,7 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index dec2ba6ba03..b4ab2bea972 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -922,6 +924,7 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig index 37f9dd7187b..18d20fb7d5f 100644 --- a/arch/mips/configs/it8172_defconfig +++ b/arch/mips/configs/it8172_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -900,6 +902,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig index 18874a4c24f..99831d0bf76 100644 --- a/arch/mips/configs/ivr_defconfig +++ b/arch/mips/configs/ivr_defconfig @@ -144,6 +144,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -856,6 +858,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig index 9f1e3048d62..9d4d17ace12 100644 --- a/arch/mips/configs/jaguar-atx_defconfig +++ b/arch/mips/configs/jaguar-atx_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -775,6 +777,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index fded3f73815..d03746667a9 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -143,6 +143,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_RTC_DS1742=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -872,6 +874,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index 320b8cdd6e5..1db8249b4c0 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -151,6 +151,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -970,6 +972,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 0ba1ef5048f..aeefe2873e3 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -170,6 +170,8 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1341,6 +1343,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index adbeeadddb8..a3cbd23bf21 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -799,6 +801,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 79fd544fcb2..6570b47426c 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index 4d87da2b99f..440d65f93a9 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1091,6 +1093,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index a7ac2b0a827..c2c7ae77da3 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -150,6 +150,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -839,6 +841,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 853e7bba512..67efe270e0c 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -154,6 +154,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -788,6 +790,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig index 8524efa23a4..a10f34de5f7 100644 --- a/arch/mips/configs/ocelot_g_defconfig +++ b/arch/mips/configs/ocelot_g_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 1a16e92900c..741f8258075 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -149,6 +149,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1000,6 +1002,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 9ea8edea6f2..8576340714d 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1106,6 +1108,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index c4a158976f8..3db7427d1b5 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -148,6 +148,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1098,6 +1100,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 1cbf270c301..26b0b988349 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -876,6 +878,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig index bec30b15b9b..e93266b37dd 100644 --- a/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/arch/mips/configs/pnx8550-v2pci_defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1057,6 +1059,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index f5f799e9370..9b0dab822bd 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -145,6 +145,8 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -733,6 +735,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 2f5650227ba..dd029603602 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -155,6 +155,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1335,6 +1337,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 4fee90b2b10..d8a498d64d6 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -158,6 +158,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1584,6 +1586,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 9041f095f96..805a4fe450f 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -171,6 +171,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -873,6 +875,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index 02abb2f1bfa..6fcb656d8d8 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -151,6 +151,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -581,6 +583,7 @@ CONFIG_PARTITION_ADVANCED=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index ca3d0c4ba15..dc312f19ada 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -151,6 +151,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1059,6 +1061,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig index 4e2009ace27..85615d99b01 100644 --- a/arch/mips/configs/tb0229_defconfig +++ b/arch/mips/configs/tb0229_defconfig @@ -151,6 +151,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -968,6 +970,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 535a813d01a..ad7271b3f26 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -151,6 +151,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1146,6 +1148,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index 3a3ef20b21c..863f6a7cadf 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -147,6 +147,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index e6b1dea5584..c10267d61cc 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -155,6 +155,8 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -829,6 +831,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 06a072b77b1..4d3c1329f3c 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -152,6 +152,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -760,6 +762,7 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index cc9b24eda9e..21d53e0c9ee 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -153,6 +153,8 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 881c467c698..cd9cec9e39e 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -11,6 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_APM) += apm.o diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 37fda3dcdfc..af6ef2fd830 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp) CLI TRACE_IRQS_OFF move a0, sp - jalr v0 - j ret_from_irq + PTR_LA ra, ret_from_irq + jr v0 END(except_vec_vi_handler) /* @@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp) .set at __BUILD_\verbose \exception move a0, sp - jal do_\handler - j ret_from_exception + PTR_LA ra, ret_from_exception + j do_\handler END(handle_\exception) .endm diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index ea36c8e8852..48e3418c217 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -302,11 +302,11 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY + .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY + .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY }; /* diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 43b1162d714..52cada45b35 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -1039,7 +1039,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name) int ret = 0; down_read(&uts_sem); - if (copy_to_user(name,&system_utsname,sizeof *name)) + if (copy_to_user(name, utsname(), sizeof *name)) ret = -EFAULT; up_read(&uts_sem); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 2613a0dd4b8..045d987bc68 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -40,6 +40,7 @@ #include <asm/elf.h> #include <asm/isadep.h> #include <asm/inst.h> +#include <asm/stacktrace.h> #ifdef CONFIG_MIPS_MT_SMTC #include <asm/mipsmtregs.h> extern void smtc_idle_loop_hook(void); @@ -398,7 +399,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) #ifdef CONFIG_KALLSYMS /* used by show_backtrace() */ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long ra) + unsigned long pc, unsigned long *ra) { unsigned long stack_page; struct mips_frame_info info; @@ -406,18 +407,42 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; + extern void ret_from_irq(void); + extern void ret_from_exception(void); stack_page = (unsigned long)task_stack_page(task); if (!stack_page) return 0; + /* + * If we reached the bottom of interrupt context, + * return saved pc in pt_regs. + */ + if (pc == (unsigned long)ret_from_irq || + pc == (unsigned long)ret_from_exception) { + struct pt_regs *regs; + if (*sp >= stack_page && + *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { + regs = (struct pt_regs *)*sp; + pc = regs->cp0_epc; + if (__kernel_text_address(pc)) { + *sp = regs->regs[29]; + *ra = regs->regs[31]; + return pc; + } + } + return 0; + } if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) return 0; /* * Return ra if an exception occured at the first instruction */ - if (unlikely(ofs == 0)) - return ra; + if (unlikely(ofs == 0)) { + pc = *ra; + *ra = 0; + return pc; + } info.func = (void *)(pc - ofs); info.func_size = ofs; /* analyze from start to ofs */ @@ -436,11 +461,12 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, * one. In that cases avoid to return always the * same value. */ - pc = pc != ra ? ra : 0; + pc = pc != *ra ? *ra : 0; else pc = ((unsigned long *)(*sp))[info.pc_offset]; *sp += info.frame_size; + *ra = 0; return __kernel_text_address(pc) ? pc : 0; } #endif @@ -453,6 +479,7 @@ unsigned long get_wchan(struct task_struct *task) unsigned long pc = 0; #ifdef CONFIG_KALLSYMS unsigned long sp; + unsigned long ra = 0; #endif if (!task || task == current || task->state == TASK_RUNNING) @@ -466,7 +493,7 @@ unsigned long get_wchan(struct task_struct *task) sp = task->thread.reg29 + schedule_mfi.frame_size; while (in_sched_functions(pc)) - pc = unwind_stack(task, &sp, pc, 0); + pc = unwind_stack(task, &sp, pc, &ra); #endif out: diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index e7178510220..61362e6fa9e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -28,18 +28,7 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME -#ifdef CONFIG_TRACE_IRQFLAGS - TRACE_IRQS_ON -#ifdef CONFIG_64BIT - LONG_L $8, PT_R8(sp) - LONG_L $9, PT_R9(sp) -#endif - LONG_L $7, PT_R7(sp) - LONG_L $6, PT_R6(sp) - LONG_L $5, PT_R5(sp) - LONG_L $4, PT_R4(sp) - LONG_L $2, PT_R2(sp) -#endif + TRACE_IRQS_ON_RELOAD STI .set at diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 4c22d0b4825..6c7b5ed0ea6 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp) */ .set noat SAVE_SOME - TRACE_IRQS_ON + TRACE_IRQS_ON_RELOAD STI .set at #endif diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f25c2a2f103..6d9f18727ac 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) #ifndef CONFIG_MIPS32_O32 .set noat SAVE_SOME - TRACE_IRQS_ON + TRACE_IRQS_ON_RELOAD STI .set at #endif diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 288ee4ac4db..2e6d0673163 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -28,7 +28,7 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME - TRACE_IRQS_ON + TRACE_IRQS_ON_RELOAD STI .set at ld t1, PT_EPC(sp) # skip syscall on return diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 50c17eaa7f2..477c5334ec1 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -42,8 +42,6 @@ #include "signal-common.h" -extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); - /* * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... */ @@ -83,6 +81,8 @@ struct rt_sigframe_n32 { #endif }; +extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); + save_static_function(sysn32_rt_sigsuspend); __attribute_used__ noinline static int _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c new file mode 100644 index 00000000000..4aabe526a68 --- /dev/null +++ b/arch/mips/kernel/stacktrace.c @@ -0,0 +1,85 @@ +/* + * arch/mips/kernel/stacktrace.c + * + * Stack trace management functions + * + * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> + */ +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <asm/stacktrace.h> + +/* + * Save stack-backtrace addresses into a stack_trace buffer: + */ +static void save_raw_context_stack(struct stack_trace *trace, + unsigned long reg29) +{ + unsigned long *sp = (unsigned long *)reg29; + unsigned long addr; + + while (!kstack_end(sp)) { + addr = *sp++; + if (__kernel_text_address(addr)) { + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = addr; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +} + +static void save_context_stack(struct stack_trace *trace, + struct task_struct *task, struct pt_regs *regs) +{ + unsigned long sp = regs->regs[29]; +#ifdef CONFIG_KALLSYMS + unsigned long ra = regs->regs[31]; + unsigned long pc = regs->cp0_epc; + + if (raw_show_trace || !__kernel_text_address(pc)) { + unsigned long stack_page = + (unsigned long)task_stack_page(task); + if (stack_page && sp >= stack_page && + sp <= stack_page + THREAD_SIZE - 32) + save_raw_context_stack(trace, sp); + return; + } + do { + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = pc; + if (trace->nr_entries >= trace->max_entries) + break; + pc = unwind_stack(task, &sp, pc, &ra); + } while (pc); +#else + save_raw_context_stack(sp); +#endif +} + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + */ +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + struct pt_regs dummyregs; + struct pt_regs *regs = &dummyregs; + + WARN_ON(trace->nr_entries || !trace->max_entries); + + if (task && task != current) { + regs->regs[29] = task->thread.reg29; + regs->regs[31] = 0; + regs->cp0_epc = task->thread.reg31; + } else { + if (!task) + task = current; + prepare_frametrace(regs); + } + + save_context_stack(trace, task, regs); +} diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 9951240cc3f..26e1a7e78d1 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -231,7 +231,7 @@ out: */ asmlinkage int sys_uname(struct old_utsname __user * name) { - if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) + if (name && !copy_to_user(name, utsname(), sizeof (*name))) return 0; return -EFAULT; } @@ -248,16 +248,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); - error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); - error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); - error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error = __put_user(0,name->machine+__OLD_UTS_LEN); + error = __copy_to_user(&name->sysname, &utsname()->sysname, + __OLD_UTS_LEN); + error -= __put_user(0, name->sysname + __OLD_UTS_LEN); + error -= __copy_to_user(&name->nodename, &utsname()->nodename, + __OLD_UTS_LEN); + error -= __put_user(0, name->nodename + __OLD_UTS_LEN); + error -= __copy_to_user(&name->release, &utsname()->release, + __OLD_UTS_LEN); + error -= __put_user(0, name->release + __OLD_UTS_LEN); + error -= __copy_to_user(&name->version, &utsname()->version, + __OLD_UTS_LEN); + error -= __put_user(0, name->version + __OLD_UTS_LEN); + error -= __copy_to_user(&name->machine, &utsname()->machine, + __OLD_UTS_LEN); + error = __put_user(0, name->machine + __OLD_UTS_LEN); error = error ? -EFAULT : 0; return error; @@ -401,3 +406,32 @@ asmlinkage void bad_stack(void) { do_exit(SIGSEGV); } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register unsigned long __a0 asm("$4") = (unsigned long) filename; + register unsigned long __a1 asm("$5") = (unsigned long) argv; + register unsigned long __a2 asm("$6") = (unsigned long) envp; + register unsigned long __a3 asm("$7"); + unsigned long __v0; + + __asm__ volatile (" \n" + " .set noreorder \n" + " li $2, %5 # __NR_execve \n" + " syscall \n" + " move %0, $2 \n" + " .set reorder \n" + : "=&r" (__v0), "=r" (__a3) + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve) + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", + "memory"); + + if (__a3 == 0) + return __v0; + + return -__v0; +} diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 1137dd6ea7a..11bb9717497 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -884,7 +884,7 @@ asmlinkage int irix_getdomainname(char __user *name, int len) down_read(&uts_sem); if (len > __NEW_UTS_LEN) len = __NEW_UTS_LEN; - err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0; + err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0; up_read(&uts_sem); return err; @@ -1127,11 +1127,11 @@ struct iuname { asmlinkage int irix_uname(struct iuname __user *buf) { down_read(&uts_sem); - if (copy_from_user(system_utsname.sysname, buf->sysname, 65) - || copy_from_user(system_utsname.nodename, buf->nodename, 65) - || copy_from_user(system_utsname.release, buf->release, 65) - || copy_from_user(system_utsname.version, buf->version, 65) - || copy_from_user(system_utsname.machine, buf->machine, 65)) { + if (copy_from_user(utsname()->sysname, buf->sysname, 65) + || copy_from_user(utsname()->nodename, buf->nodename, 65) + || copy_from_user(utsname()->release, buf->release, 65) + || copy_from_user(utsname()->version, buf->version, 65) + || copy_from_user(utsname()->machine, buf->machine, 65)) { return -EFAULT; } up_read(&uts_sem); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e51d8fd9a15..b7292a56d4c 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -41,6 +41,7 @@ #include <asm/mmu_context.h> #include <asm/watch.h> #include <asm/types.h> +#include <asm/stacktrace.h> extern asmlinkage void handle_int(void); extern asmlinkage void handle_tlbm(void); @@ -92,16 +93,14 @@ static void show_raw_backtrace(unsigned long reg29) } #ifdef CONFIG_KALLSYMS -static int raw_show_trace; +int raw_show_trace; static int __init set_raw_show_trace(char *str) { raw_show_trace = 1; return 1; } __setup("raw_show_trace", set_raw_show_trace); - -extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long ra); +#endif static void show_backtrace(struct task_struct *task, struct pt_regs *regs) { @@ -116,14 +115,10 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs) printk("Call Trace:\n"); do { print_ip_sym(pc); - pc = unwind_stack(task, &sp, pc, ra); - ra = 0; + pc = unwind_stack(task, &sp, pc, &ra); } while (pc); printk("\n"); } -#else -#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]); -#endif /* * This routine abuses get_user()/put_user() to reference pointers @@ -158,28 +153,6 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) show_backtrace(task, regs); } -static __always_inline void prepare_frametrace(struct pt_regs *regs) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set noat\n\t" -#ifdef CONFIG_64BIT - "1: dla $1, 1b\n\t" - "sd $1, %0\n\t" - "sd $29, %1\n\t" - "sd $31, %2\n\t" -#else - "1: la $1, 1b\n\t" - "sw $1, %0\n\t" - "sw $29, %1\n\t" - "sw $31, %2\n\t" -#endif - ".set pop\n\t" - : "=m" (regs->cp0_epc), - "=m" (regs->regs[29]), "=m" (regs->regs[31]) - : : "memory"); -} - void show_stack(struct task_struct *task, unsigned long *sp) { struct pt_regs regs; @@ -206,11 +179,6 @@ void dump_stack(void) { struct pt_regs regs; - /* - * Remove any garbage that may be in regs (specially func - * addresses) to avoid show_raw_backtrace() to report them - */ - memset(®s, 0, sizeof(regs)); prepare_frametrace(®s); show_backtrace(current, ®s); } diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index e1f35ef8114..d1af42c2a52 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -268,26 +268,6 @@ static void r3k_flush_data_cache_page(unsigned long addr) { } -static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long physpage; - - if (cpu_context(smp_processor_id(), mm) == 0) - return; - - if (!(vma->vm_flags & VM_EXEC)) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); -#endif - - physpage = (unsigned long) page_address(page); - if (physpage) - r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); -} - static void r3k_flush_cache_sigtramp(unsigned long addr) { unsigned long flags; @@ -335,7 +315,6 @@ void __init r3k_cache_init(void) flush_cache_mm = r3k_flush_cache_mm; flush_cache_range = r3k_flush_cache_range; flush_cache_page = r3k_flush_cache_page; - __flush_icache_page = r3k_flush_icache_page; flush_icache_range = r3k_flush_icache_range; flush_cache_sigtramp = r3k_flush_cache_sigtramp; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 0b2da53750b..cc895dad71d 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -551,82 +551,6 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. Otoh we at - * least know the kernel address of the page so we can flush it - * selectivly. - */ - -struct flush_icache_page_args { - struct vm_area_struct *vma; - struct page *page; -}; - -static inline void local_r4k_flush_icache_page(void *args) -{ - struct flush_icache_page_args *fip_args = args; - struct vm_area_struct *vma = fip_args->vma; - struct page *page = fip_args->page; - - /* - * Tricky ... Because we don't know the virtual address we've got the - * choice of either invalidating the entire primary and secondary - * caches or invalidating the secondary caches also. With the subset - * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the - * secondary cache will result in any entries in the primary caches - * also getting invalidated which hopefully is a bit more economical. - */ - if (cpu_has_inclusive_pcaches) { - unsigned long addr = (unsigned long) page_address(page); - - r4k_blast_scache_page(addr); - ClearPageDcacheDirty(page); - - return; - } - - if (!cpu_has_ic_fills_f_dc) { - unsigned long addr = (unsigned long) page_address(page); - r4k_blast_dcache_page(addr); - if (!cpu_icache_snoops_remote_store) - r4k_blast_scache_page(addr); - ClearPageDcacheDirty(page); - } - - /* - * We're not sure of the virtual address(es) involved here, so - * we have to flush the entire I-cache. - */ - if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { - int cpu = smp_processor_id(); - - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); - } else - r4k_blast_icache(); -} - -static void r4k_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - struct flush_icache_page_args args; - - /* - * If there's no context yet, or the page isn't executable, no I-cache - * flush is needed. - */ - if (!(vma->vm_flags & VM_EXEC)) - return; - - args.vma = vma; - args.page = page; - - r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1); -} - - #ifdef CONFIG_DMA_NONCOHERENT static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1291,7 +1215,6 @@ void __init r4k_cache_init(void) __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; - __flush_icache_page = r4k_flush_icache_page; flush_cache_range = r4k_flush_cache_range; flush_cache_sigtramp = r4k_flush_cache_sigtramp; diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 16bad7c0a63..5537558f19f 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -307,66 +307,6 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) #endif /* - * Flush the icache for a given physical page. Need to writeback the - * dcache first, then invalidate the icache. If the page isn't - * executable, nothing is required. - */ -static void local_sb1_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - unsigned long start; - int cpu = smp_processor_id(); - -#ifndef CONFIG_SMP - if (!(vma->vm_flags & VM_EXEC)) - return; -#endif - - /* Need to writeback any dirty data for that page, we have the PA */ - start = (unsigned long)(page-mem_map) << PAGE_SHIFT; - __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); - /* - * If there's a context, bump the ASID (cheaper than a flush, - * since we don't know VAs!) - */ - if (vma->vm_mm == current->active_mm) { - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); - } else - __sb1_flush_icache_range(start, start + PAGE_SIZE); - -} - -#ifdef CONFIG_SMP -struct flush_icache_page_args { - struct vm_area_struct *vma; - struct page *page; -}; - -static void sb1_flush_icache_page_ipi(void *info) -{ - struct flush_icache_page_args *args = info; - local_sb1_flush_icache_page(args->vma, args->page); -} - -/* Dirty dcache could be on another CPU, so do the IPIs */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - struct flush_icache_page_args args; - - if (!(vma->vm_flags & VM_EXEC)) - return; - args.vma = vma; - args.page = page; - on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); -} -#else -void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) - __attribute__((alias("local_sb1_flush_icache_page"))); -#endif - -/* * A signal trampoline must fit into a single cacheline. */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) @@ -526,7 +466,6 @@ void sb1_cache_init(void) /* These routines are for Icache coherence with the Dcache */ flush_icache_range = sb1_flush_icache_range; - __flush_icache_page = sb1_flush_icache_page; flush_icache_all = __sb1_flush_icache_all; /* local only */ /* This implies an Icache flush too, so can't be nop'ed */ diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 932a09d7ef8..f32ebde30cc 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -248,33 +248,6 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end) } } -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. Otoh we at - * least know the kernel address of the page so we can flush it - * selectivly. - */ -static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - unsigned long addr; - /* - * If there's no context yet, or the page isn't executable, no icache - * flush is needed. - */ - if (!(vma->vm_flags & VM_EXEC)) - return; - - addr = (unsigned long) page_address(page); - tx39_blast_dcache_page(addr); - - /* - * We're not sure of the virtual address(es) involved here, so - * we have to flush the entire I-cache. - */ - tx39_blast_icache(); -} - static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end; @@ -382,7 +355,6 @@ void __init tx39_cache_init(void) flush_cache_mm = (void *) tx39h_flush_icache_all; flush_cache_range = (void *) tx39h_flush_icache_all; flush_cache_page = (void *) tx39h_flush_icache_all; - __flush_icache_page = (void *) tx39h_flush_icache_all; flush_icache_range = (void *) tx39h_flush_icache_all; flush_cache_sigtramp = (void *) tx39h_flush_icache_all; @@ -408,7 +380,6 @@ void __init tx39_cache_init(void) flush_cache_mm = tx39_flush_cache_mm; flush_cache_range = tx39_flush_cache_range; flush_cache_page = tx39_flush_cache_page; - __flush_icache_page = tx39_flush_icache_page; flush_icache_range = tx39_flush_icache_range; flush_cache_sigtramp = tx39_flush_cache_sigtramp; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 40c8b023518..caf807ded51 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -25,7 +25,6 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); -void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S index 9e7f4175b49..e99eaa1fbed 100644 --- a/arch/mips/mm/tlbex-fault.S +++ b/arch/mips/mm/tlbex-fault.S @@ -19,8 +19,8 @@ move a0, sp REG_S a2, PT_BVADDR(sp) li a1, \write - jal do_page_fault - j ret_from_exception + PTR_LA ra, ret_from_exception + j do_page_fault END(tlb_do_page_fault_\write) .endm diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 8134220ed60..7a941ecff3b 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -123,7 +123,8 @@ static inline void power_button(void) if (machine_state & MACHINE_PANICED) return; - if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { + if ((machine_state & MACHINE_SHUTTING_DOWN) || + kill_cad_pid(SIGINT, 1)) { /* No init process or button pressed twice. */ sgi_machine_power_off(); } diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index 79ddb460565..fd0932b2d52 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c @@ -120,7 +120,7 @@ static inline void ip32_power_button(void) if (has_panicked) return; - if (shuting_down || kill_proc(1, SIGINT, 1)) { + if (shuting_down || kill_cad_pid(SIGINT, 1)) { /* No init process or button pressed twice. */ ip32_machine_power_off(); } diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index cb69727027a..2e2dc4f2c85 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c @@ -266,16 +266,21 @@ static int hpux_uname(struct hpux_utsname *name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1); - error |= __put_user(0,name->sysname+HPUX_UTSLEN-1); - error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1); - error |= __put_user(0,name->nodename+HPUX_UTSLEN-1); - error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1); - error |= __put_user(0,name->release+HPUX_UTSLEN-1); - error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1); - error |= __put_user(0,name->version+HPUX_UTSLEN-1); - error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1); - error |= __put_user(0,name->machine+HPUX_UTSLEN-1); + error = __copy_to_user(&name->sysname, &utsname()->sysname, + HPUX_UTSLEN - 1); + error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1); + error |= __copy_to_user(&name->nodename, &utsname()->nodename, + HPUX_UTSLEN - 1); + error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1); + error |= __copy_to_user(&name->release, &utsname()->release, + HPUX_UTSLEN - 1); + error |= __put_user(0, name->release + HPUX_UTSLEN - 1); + error |= __copy_to_user(&name->version, &utsname()->version, + HPUX_UTSLEN - 1); + error |= __put_user(0, name->version + HPUX_UTSLEN - 1); + error |= __copy_to_user(&name->machine, &utsname()->machine, + HPUX_UTSLEN - 1); + error |= __put_user(0, name->machine + HPUX_UTSLEN - 1); up_read(&uts_sem); @@ -373,8 +378,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about using this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(system_utsname.sysname, ubuf, len)) { - system_utsname.sysname[len] = 0; + if (!copy_from_user(utsname()->sysname, ubuf, len)) { + utsname()->sysname[len] = 0; error = 0; } up_write(&uts_sem); @@ -400,8 +405,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(system_utsname.release, ubuf, len)) { - system_utsname.release[len] = 0; + if (!copy_from_user(utsname()->release, ubuf, len)) { + utsname()->release[len] = 0; error = 0; } up_write(&uts_sem); @@ -422,13 +427,13 @@ int hpux_getdomainname(char *name, int len) down_read(&uts_sem); - nlen = strlen(system_utsname.domainname) + 1; + nlen = strlen(utsname()->domainname) + 1; if (nlen < len) len = nlen; if(len > __NEW_UTS_LEN) goto done; - if(copy_to_user(name, system_utsname.domainname, len)) + if(copy_to_user(name, utsname()->domainname, len)) goto done; err = 0; done: diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 0b485ef4be8..2f9f9dfa66f 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -368,7 +368,14 @@ out: return error; } -unsigned long +extern int __execve(const char *filename, char *const argv[], + char *const envp[], struct task_struct *task); +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + return __execve(filename, argv, envp, current); +} + +unsigned long get_wchan(struct task_struct *p) { struct unwind_frame_info info; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a0dd1b0ee48..032e6ab5d3c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -1069,7 +1069,7 @@ source "arch/powerpc/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on PPC64 && EXPERIMENTAL && MODULES + depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index cd65c367b8b..7b8d12b9026 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -259,14 +259,15 @@ void kretprobe_trampoline_holder(void) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -277,20 +278,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri); + recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) /* @@ -308,12 +309,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler - * to run (and have re-enabled preemption) - */ - return 1; + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler + * to run (and have re-enabled preemption) + */ + return 1; } /* diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 58758d88336..88fd73fdf04 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -843,7 +843,7 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr -_GLOBAL(execve) +_GLOBAL(kernel_execve) li r0,__NR_execve sc bnslr diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e3ed21cd3d9..9c54eccad99 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -556,7 +556,7 @@ _GLOBAL(giveup_altivec) #endif /* CONFIG_ALTIVEC */ -_GLOBAL(execve) +_GLOBAL(kernel_execve) li r0,__NR_execve sc bnslr diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a127a1e3c09..7b2f6452ba7 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs) printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %p TRAP: %04lx %s (%s)\n", - regs, regs->trap, print_tainted(), system_utsname.release); + regs, regs->trap, print_tainted(), init_utsname()->release); printk("MSR: "REG" ", regs->msr); printbits(regs->msr, msr_bits); printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 962ad5ebc76..cda2dbe70a7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -414,7 +414,7 @@ void __init setup_system(void) smp_release_cpus(); #endif - printk("Starting Linux PPC64 %s\n", system_utsname.version); + printk("Starting Linux PPC64 %s\n", init_utsname()->version); printk("-----------------------------------------------------\n"); printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 9b69d99a910..d358866b880 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -260,7 +260,7 @@ long ppc_newuname(struct new_utsname __user * name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, &system_utsname, sizeof(*name))) + if (copy_to_user(name, utsname(), sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -273,7 +273,7 @@ int sys_uname(struct old_utsname __user *name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, &system_utsname, sizeof(*name))) + if (copy_to_user(name, utsname(), sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -289,19 +289,19 @@ int sys_olduname(struct oldold_utsname __user *name) return -EFAULT; down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &system_utsname.sysname, + error = __copy_to_user(&name->sysname, &utsname()->sysname, __OLD_UTS_LEN); error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &system_utsname.nodename, + error |= __copy_to_user(&name->nodename, &utsname()->nodename, __OLD_UTS_LEN); error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &system_utsname.release, + error |= __copy_to_user(&name->release, &utsname()->release, __OLD_UTS_LEN); error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &system_utsname.version, + error |= __copy_to_user(&name->version, &utsname()->version, __OLD_UTS_LEN); error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &system_utsname.machine, + error |= __copy_to_user(&name->machine, &utsname()->machine, __OLD_UTS_LEN); error |= override_machine(name->machine); up_read(&uts_sem); diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 1a2c2a50f92..1983b640bac 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg, */ static int shutdown(void) { - int rc = kill_proc(1, SIGINT, 1); + int rc = kill_cad_pid(SIGINT, 1); if (rc) { printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), " diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8ed36214045..98189d8efac 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -342,7 +342,7 @@ static int __init pSeries_init_panel(void) { /* Manually leave the kernel version on the panel. */ ppc_md.progress("Linux ppc64\n", 0); - ppc_md.progress(system_utsname.release, 0); + ppc_md.progress(init_utsname()->version, 0); return 0; } diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c index b81a367dc27..87fe9a89dba 100644 --- a/arch/ppc/4xx_io/serial_sicc.c +++ b/arch/ppc/4xx_io/serial_sicc.c @@ -1720,7 +1720,7 @@ static int siccuart_open(struct tty_struct *tty, struct file *filp) return 0; } -static struct tty_operations sicc_ops = { +static const struct tty_operations sicc_ops = { .open = siccuart_open, .close = siccuart_close, .write = siccuart_write, diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 50b4bbd0680..5f6684012de 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -942,20 +942,16 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr +_GLOBAL(kernel_execve) + li r0,__NR_execve + sc + bnslr + neg r3,r3 + blr + /* * This routine is just here to keep GCC happy - sigh... */ _GLOBAL(__main) blr -#define SYSCALL(name) \ -_GLOBAL(name) \ - li r0,__NR_##name; \ - sc; \ - bnslr; \ - lis r4,errno@ha; \ - stw r3,errno@l(r4); \ - li r3,-1; \ - blr - -SYSCALL(execve) diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index ca28fb0b379..4d9ff5ce4cb 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -369,11 +369,12 @@ void __kprobes kretprobe_trampoline_holder(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head; + struct hlist_head *head, empty_rp; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; + INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -399,7 +400,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri); + recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) { /* @@ -417,6 +418,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index e351780bb66..584ed95f338 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -27,6 +27,7 @@ #include <linux/file.h> #include <linux/utsname.h> #include <linux/personality.h> +#include <linux/unistd.h> #include <asm/uaccess.h> #include <asm/ipc.h> @@ -266,3 +267,22 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register const char *__arg1 asm("2") = filename; + register char *const*__arg2 asm("3") = argv; + register char *const*__arg3 asm("4") = envp; + register long __svcres asm("2"); + asm volatile( + "svc %b1" + : "=d" (__svcres) + : "i" (__NR_execve), + "0" (__arg1), + "d" (__arg2), + "d" (__arg3) : "memory"); + return __svcres; +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 5f587332234..77491cf9b25 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -459,7 +459,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "machine\t\t: %s\n", get_system_type()); seq_printf(m, "processor\t: %d\n", cpu); - seq_printf(m, "cpu family\t: %s\n", system_utsname.machine); + seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); show_cpuflags(m); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 6c0fb7c4af1..dbebaddcfe3 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -42,6 +42,7 @@ cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; +EXPORT_SYMBOL(cpu_online_map); static atomic_t cpus_booted = ATOMIC_INIT(0); /* These are defined by the board-specific code. */ diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index b68ff705f06..8fde95001c3 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -25,6 +25,7 @@ #include <asm/cacheflush.h> #include <asm/uaccess.h> #include <asm/ipc.h> +#include <asm/unistd.h> /* * sys_pipe() is the normal C calling standard for creating @@ -281,7 +282,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -309,3 +310,19 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, (u64)len0 << 32 | len1, advice); #endif } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register long __sc0 __asm__ ("r3") = __NR_execve; + register long __sc4 __asm__ ("r4") = (long) filename; + register long __sc5 __asm__ ("r5") = (long) argv; + register long __sc6 __asm__ ("r6") = (long) envp; + __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0) + : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) + : "memory"); + return __sc0; +} diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c index db475b7833f..525d0ec19b7 100644 --- a/arch/sh64/kernel/process.c +++ b/arch/sh64/kernel/process.c @@ -20,261 +20,16 @@ /* * This file handles the architecture-dependent parts of process handling.. */ - -/* Temporary flags/tests. All to be removed/undefined. BEGIN */ -#define IDLE_TRACE -#define VM_SHOW_TABLES -#define VM_TEST_FAULT -#define VM_TEST_RTLBMISS -#define VM_TEST_WTLBMISS - -#undef VM_SHOW_TABLES -#undef IDLE_TRACE -/* Temporary flags/tests. All to be removed/undefined. END */ - -#define __KERNEL_SYSCALLS__ -#include <stdarg.h> - -#include <linux/kernel.h> -#include <linux/rwsem.h> #include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/user.h> -#include <linux/a.out.h> -#include <linux/interrupt.h> -#include <linux/unistd.h> -#include <linux/delay.h> #include <linux/reboot.h> #include <linux/init.h> - +#include <linux/module.h> #include <asm/uaccess.h> #include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/io.h> -#include <asm/processor.h> /* includes also <asm/registers.h> */ -#include <asm/mmu_context.h> -#include <asm/elf.h> -#include <asm/page.h> - -#include <linux/irq.h> struct task_struct *last_task_used_math = NULL; -#ifdef IDLE_TRACE -#ifdef VM_SHOW_TABLES -/* For testing */ -static void print_PTE(long base) -{ - int i, skip=0; - long long x, y, *p = (long long *) base; - - for (i=0; i< 512; i++, p++){ - if (*p == 0) { - if (!skip) { - skip++; - printk("(0s) "); - } - } else { - skip=0; - x = (*p) >> 32; - y = (*p) & 0xffffffff; - printk("%08Lx%08Lx ", x, y); - if (!((i+1)&0x3)) printk("\n"); - } - } -} - -/* For testing */ -static void print_DIR(long base) -{ - int i, skip=0; - long *p = (long *) base; - - for (i=0; i< 512; i++, p++){ - if (*p == 0) { - if (!skip) { - skip++; - printk("(0s) "); - } - } else { - skip=0; - printk("%08lx ", *p); - if (!((i+1)&0x7)) printk("\n"); - } - } -} - -/* For testing */ -static void print_vmalloc_first_tables(void) -{ - -#define PRESENT 0x800 /* Bit 11 */ - - /* - * Do it really dirty by looking at raw addresses, - * raw offsets, no types. If we used pgtable/pgalloc - * macros/definitions we could hide potential bugs. - * - * Note that pointers are 32-bit for CDC. - */ - long pgdt, pmdt, ptet; - - pgdt = (long) &swapper_pg_dir; - printk("-->PGD (0x%08lx):\n", pgdt); - print_DIR(pgdt); - printk("\n"); - - /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */ - pgdt += 4; - pmdt = (long) (* (long *) pgdt); - if (!(pmdt & PRESENT)) { - printk("No PMD\n"); - return; - } else pmdt &= 0xfffff000; - - printk("-->PMD (0x%08lx):\n", pmdt); - print_DIR(pmdt); - printk("\n"); - - /* Get the pmdt displacement for 0xc0000000 */ - pmdt += 2048; - - /* just look at first two address ranges ... */ - /* ... 0xc0000000 ... */ - ptet = (long) (* (long *) pmdt); - if (!(ptet & PRESENT)) { - printk("No PTE0\n"); - return; - } else ptet &= 0xfffff000; - - printk("-->PTE0 (0x%08lx):\n", ptet); - print_PTE(ptet); - printk("\n"); - - /* ... 0xc0001000 ... */ - ptet += 4; - if (!(ptet & PRESENT)) { - printk("No PTE1\n"); - return; - } else ptet &= 0xfffff000; - printk("-->PTE1 (0x%08lx):\n", ptet); - print_PTE(ptet); - printk("\n"); -} -#else -#define print_vmalloc_first_tables() -#endif /* VM_SHOW_TABLES */ - -static void test_VM(void) -{ - void *a, *b, *c; - -#ifdef VM_SHOW_TABLES - printk("Initial PGD/PMD/PTE\n"); -#endif - print_vmalloc_first_tables(); - - printk("Allocating 2 bytes\n"); - a = vmalloc(2); - print_vmalloc_first_tables(); - - printk("Allocating 4100 bytes\n"); - b = vmalloc(4100); - print_vmalloc_first_tables(); - - printk("Allocating 20234 bytes\n"); - c = vmalloc(20234); - print_vmalloc_first_tables(); - -#ifdef VM_TEST_FAULT - /* Here you may want to fault ! */ - -#ifdef VM_TEST_RTLBMISS - printk("Ready to fault upon read.\n"); - if (* (char *) a) { - printk("RTLBMISSed on area a !\n"); - } - printk("RTLBMISSed on area a !\n"); -#endif - -#ifdef VM_TEST_WTLBMISS - printk("Ready to fault upon write.\n"); - *((char *) b) = 'L'; - printk("WTLBMISSed on area b !\n"); -#endif - -#endif /* VM_TEST_FAULT */ - - printk("Deallocating the 4100 byte chunk\n"); - vfree(b); - print_vmalloc_first_tables(); - - printk("Deallocating the 2 byte chunk\n"); - vfree(a); - print_vmalloc_first_tables(); - - printk("Deallocating the last chunk\n"); - vfree(c); - print_vmalloc_first_tables(); -} - -extern unsigned long volatile jiffies; -int once = 0; -unsigned long old_jiffies; -int pid = -1, pgid = -1; - -void idle_trace(void) -{ - - _syscall0(int, getpid) - _syscall1(int, getpgid, int, pid) - - if (!once) { - /* VM allocation/deallocation simple test */ - test_VM(); - pid = getpid(); - - printk("Got all through to Idle !!\n"); - printk("I'm now going to loop forever ...\n"); - printk("Any ! below is a timer tick.\n"); - printk("Any . below is a getpgid system call from pid = %d.\n", pid); - - - old_jiffies = jiffies; - once++; - } - - if (old_jiffies != jiffies) { - old_jiffies = jiffies - old_jiffies; - switch (old_jiffies) { - case 1: - printk("!"); - break; - case 2: - printk("!!"); - break; - case 3: - printk("!!!"); - break; - case 4: - printk("!!!!"); - break; - default: - printk("(%d!)", (int) old_jiffies); - } - old_jiffies = jiffies; - } - pgid = getpgid(pid); - printk("."); -} -#else -#define idle_trace() do { } while (0) -#endif /* IDLE_TRACE */ - static int hlt_counter = 1; #define HARD_IDLE_TIMEOUT (HZ / 3) @@ -323,7 +78,6 @@ void cpu_idle(void) local_irq_disable(); while (!need_resched()) { local_irq_enable(); - idle_trace(); hlt(); local_irq_disable(); } @@ -622,6 +376,10 @@ void free_task_struct(struct task_struct *p) /* * Create a kernel thread */ +ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) +{ + do_exit(fn(arg)); +} /* * This is the mechanism for creating a new kernel thread. @@ -633,19 +391,17 @@ void free_task_struct(struct task_struct *p) */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - /* A bit less processor dependent than older sh ... */ - unsigned int reply; + struct pt_regs regs; -static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) -static __inline__ _syscall1(int,exit,int,ret) + memset(®s, 0, sizeof(regs)); + regs.regs[2] = (unsigned long)arg; + regs.regs[3] = (unsigned long)fn; - reply = clone(flags | CLONE_VM, 0); - if (!reply) { - /* Child */ - reply = exit(fn(arg)); - } + regs.pc = (unsigned long)kernel_thread_helper; + regs.sr = (1 << 30); - return reply; + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, + ®s, 0, NULL, NULL); } /* diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c index 58ff7d522d8..ad0fa4e003e 100644 --- a/arch/sh64/kernel/sys_sh64.c +++ b/arch/sh64/kernel/sys_sh64.c @@ -32,6 +32,7 @@ #include <asm/uaccess.h> #include <asm/ipc.h> #include <asm/ptrace.h> +#include <asm/unistd.h> #define REG_3 3 @@ -279,7 +280,25 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); + register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; + register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv; + register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp; + __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)" + : "=r" (__sc0) + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); + __asm__ __volatile__ ("!dummy %0 %1 %2 %3" + : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory"); + return __sc0; +} diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 896863fb208..a954a0c0000 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -24,6 +24,7 @@ #include <asm/uaccess.h> #include <asm/ipc.h> +#include <asm/unistd.h> /* #define DEBUG_UNIMP_SYSCALL */ @@ -475,16 +476,38 @@ asmlinkage int sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(system_utsname.domainname) + 1; + nlen = strlen(utsname()->domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, system_utsname.domainname, nlen)) + if (!copy_to_user(name, utsname()->domainname, nlen)) err = 0; out: up_read(&uts_sem); return err; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + register long __g1 __asm__ ("g1") = __NR_execve; + register long __o0 __asm__ ("o0") = (long)(filename); + register long __o1 __asm__ ("o1") = (long)(argv); + register long __o2 __asm__ ("o2") = (long)(envp); + asm volatile ("t 0x10\n\t" + "bcc 1f\n\t" + "mov %%o0, %0\n\t" + "sub %%g0, %%o0, %0\n\t" + "1:\n\t" + : "=r" (__res), "=&r" (__o0) + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) + : "cc"); + return __res; +} diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index aa0fb2efb61..9d2cd97d1c3 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -483,13 +483,18 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); + ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], + sizeof(name->sname) - 1); if (!ret) { - ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); + ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0], + sizeof(name->nname) - 1); ret |= __put_user('\0', &name->nname[8]); - ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); - ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); - ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); + ret |= __copy_to_user(&name->rel[0], &utsname()->release[0], + sizeof(name->rel) - 1); + ret |= __copy_to_user(&name->ver[0], &utsname()->version[0], + sizeof(name->ver) - 1); + ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0], + sizeof(name->mach) - 1); } up_read(&uts_sem); return ret ? -EFAULT : 0; diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 8d8ca716f7a..b627f8dbcaa 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -420,7 +420,7 @@ source "arch/sparc64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index e55466c77b6..0b9c70627ce 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -4,8 +4,6 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ -#define __KERNEL_SYSCALLS__ - #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -14,6 +12,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/pm.h> +#include <linux/syscalls.h> #include <asm/system.h> #include <asm/auxio.h> @@ -98,7 +97,7 @@ again: /* Ok, down we go... */ button_pressed = 0; - if (execve("/sbin/shutdown", argv, envp) < 0) { + if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { printk("powerd: shutdown execution failed\n"); add_wait_queue(&powerd_wait, &wait); goto again; diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index c608c947e6c..a53d4abb4b4 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -31,6 +31,7 @@ #include <asm/utrap.h> #include <asm/perfctr.h> #include <asm/a.out.h> +#include <asm/unistd.h> /* #define DEBUG_UNIMP_SYSCALL */ @@ -712,13 +713,13 @@ asmlinkage long sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(system_utsname.domainname) + 1; + nlen = strlen(utsname()->domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, system_utsname.domainname, nlen)) + if (!copy_to_user(name, utsname()->domainname, nlen)) err = 0; out: @@ -963,3 +964,23 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, }; return err; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + register long __g1 __asm__ ("g1") = __NR_execve; + register long __o0 __asm__ ("o0") = (long)(filename); + register long __o1 __asm__ ("o1") = (long)(argv); + register long __o2 __asm__ ("o2") = (long)(envp); + asm volatile ("t 0x6d\n\t" + "sub %%g0, %%o0, %0\n\t" + "movcc %%xcc, %%o0, %0\n\t" + : "=r" (__res), "=&r" (__o0) + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) + : "cc"); + return __res; +} diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 87ebdf858a3..953296b73f3 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -439,16 +439,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], + ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], sizeof(name->sname) - 1); - ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], + ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); - ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], + ret |= copy_to_user(&name->rel[0], &utsname()->release[0], sizeof(name->rel) - 1); - ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], + ret |= copy_to_user(&name->ver[0], &utsname()->version[0], sizeof(name->ver) - 1); - ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], + ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], sizeof(name->mach) - 1); up_read(&uts_sem); return (ret ? -EFAULT : 0); diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 9c581328e76..9ed997982f8 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -249,7 +249,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) /* Let's cheat */ err = set_utsfield(v->sysname, "SunOS", 1, 0); down_read(&uts_sem); - err |= set_utsfield(v->nodename, system_utsname.nodename, + err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); up_read(&uts_sem); err |= set_utsfield(v->release, "2.6", 0, 0); @@ -273,7 +273,7 @@ asmlinkage int solaris_utsname(u32 buf) /* Why should we not lie a bit? */ down_read(&uts_sem); err = set_utsfield(v->sysname, "SunOS", 0, 0); - err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1); + err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); err |= set_utsfield(v->release, "5.6", 0, 0); err |= set_utsfield(v->version, "Generic", 0, 0); err |= set_utsfield(v->machine, machine(), 0, 0); @@ -305,7 +305,7 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) case SI_HOSTNAME: r = buffer + 256; down_read(&uts_sem); - for (p = system_utsname.nodename, q = buffer; + for (p = utsname()->nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); up_read(&uts_sem); *q = 0; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 563ce7690a1..24747a41378 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -642,9 +642,9 @@ int line_remove(struct line *lines, unsigned int num, int n) } struct tty_driver *line_register_devfs(struct lines *set, - struct line_driver *line_driver, - struct tty_operations *ops, struct line *lines, - int nlines) + struct line_driver *line_driver, + const struct tty_operations *ops, + struct line *lines, int nlines) { int i; struct tty_driver *driver = alloc_tty_driver(nlines); diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 773a134e7fd..a67dcbd78de 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req) { char version[256]; - sprintf(version, "%s %s %s %s %s", system_utsname.sysname, - system_utsname.nodename, system_utsname.release, - system_utsname.version, system_utsname.machine); + sprintf(version, "%s %s %s %s %s", utsname()->sysname, + utsname()->nodename, utsname()->release, + utsname()->version, utsname()->machine); mconsole_reply(req, version, 0, 0); } diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 642c9a0320f..7be24811bb3 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h @@ -91,10 +91,9 @@ extern int line_setup_irq(int fd, int input, int output, struct line *line, void *data); extern void line_close_chan(struct line *line); extern struct tty_driver * line_register_devfs(struct lines *set, - struct line_driver *line_driver, - struct tty_operations *driver, - struct line *lines, - int nlines); + struct line_driver *line_driver, + const struct tty_operations *driver, + struct line *lines, int nlines); extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); extern void close_lines(struct line *lines, int nlines); diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 48cf88dd02d..f5ed8624648 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -110,7 +110,7 @@ long sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -126,21 +126,21 @@ long sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname,&system_utsname.sysname, + error = __copy_to_user(&name->sysname, &utsname()->sysname, __OLD_UTS_LEN); - error |= __put_user(0,name->sysname+__OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename,&system_utsname.nodename, + error |= __put_user(0, name->sysname + __OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename, &utsname()->nodename, __OLD_UTS_LEN); - error |= __put_user(0,name->nodename+__OLD_UTS_LEN); - error |= __copy_to_user(&name->release,&system_utsname.release, + error |= __put_user(0, name->nodename + __OLD_UTS_LEN); + error |= __copy_to_user(&name->release, &utsname()->release, __OLD_UTS_LEN); - error |= __put_user(0,name->release+__OLD_UTS_LEN); - error |= __copy_to_user(&name->version,&system_utsname.version, + error |= __put_user(0, name->release + __OLD_UTS_LEN); + error |= __copy_to_user(&name->version, &utsname()->version, __OLD_UTS_LEN); - error |= __put_user(0,name->version+__OLD_UTS_LEN); - error |= __copy_to_user(&name->machine,&system_utsname.machine, + error |= __put_user(0, name->version + __OLD_UTS_LEN); + error |= __copy_to_user(&name->machine, &utsname()->machine, __OLD_UTS_LEN); - error |= __put_user(0,name->machine+__OLD_UTS_LEN); + error |= __put_user(0, name->machine + __OLD_UTS_LEN); up_read(&uts_sem); @@ -164,3 +164,16 @@ int next_syscall_index(int limit) spin_unlock(&syscall_lock); return(ret); } + +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + mm_segment_t fs; + int ret; + + fs = get_fs(); + set_fs(KERNEL_DS); + ret = um_execve(filename, argv, envp); + set_fs(fs); + + return ret; +} diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 55005710dcb..97d88e7902f 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -167,7 +167,7 @@ static char *usage_string = static int __init uml_version_setup(char *line, int *add) { - printf("%s\n", system_utsname.release); + printf("%s\n", init_utsname()->release); exit(0); return 0; @@ -278,7 +278,7 @@ static int __init Usage(char *line, int *add) { const char **p; - printf(usage_string, system_utsname.release); + printf(usage_string, init_utsname()->release); p = &__uml_help_start; while (p < &__uml_help_end) { printf("%s", *p); @@ -403,7 +403,7 @@ int linux_main(int argc, char **argv) /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); - setup_machinename(system_utsname.machine); + setup_machinename(init_utsname()->machine); #ifdef CONFIG_CMDLINE_ON_HOST argv1_begin = argv[1]; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index ff203625a4b..51f0893640a 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -11,6 +11,7 @@ #include <sys/mman.h> #include <sys/wait.h> #include <sys/mman.h> +#include <sys/syscall.h> #include "ptrace_user.h" #include "os.h" #include "user.h" @@ -140,11 +141,9 @@ void os_usr1_process(int pid) * syscalls, and also breaks with clone(), which does not unshare the TLS. */ -inline _syscall0(pid_t, getpid) - int os_getpid(void) { - return(getpid()); + return(syscall(__NR_getpid)); } int os_getpgrp(void) diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 120abbe4e3c..6e945ab4584 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -1,10 +1,9 @@ #include <errno.h> #include <linux/unistd.h> +#include <sys/syscall.h> #include "sysdep/tls.h" #include "user_util.h" -static _syscall1(int, get_thread_area, user_desc_t *, u_info); - /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ @@ -17,7 +16,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) { user_desc_t info; info.entry_number = val[i]; - if (get_thread_area(&info) == 0) { + if (syscall(__NR_get_thread_area, &info) == 0) { *tls_min = val[i]; *supports_tls = 1; return; diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index 9cb09a45546..a2de2580b8a 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c @@ -1,5 +1,6 @@ #include <errno.h> #include <sys/ptrace.h> +#include <sys/syscall.h> #include <asm/ldt.h> #include "sysdep/tls.h" #include "uml-config.h" @@ -48,14 +49,11 @@ int os_get_thread_area(user_desc_t *info, int pid) #ifdef UML_CONFIG_MODE_TT #include "linux/unistd.h" -static _syscall1(int, get_thread_area, user_desc_t *, u_info); -static _syscall1(int, set_thread_area, user_desc_t *, u_info); - int do_set_thread_area_tt(user_desc_t *info) { int ret; - ret = set_thread_area(info); + ret = syscall(__NR_set_thread_area,info); if (ret < 0) { ret = -errno; } @@ -66,7 +64,7 @@ int do_get_thread_area_tt(user_desc_t *info) { int ret; - ret = get_thread_area(info); + ret = syscall(__NR_get_thread_area,info); if (ret < 0) { ret = -errno; } diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c index 1b0ad0e4adc..8e55cd5d3d0 100644 --- a/arch/um/sys-i386/unmap.c +++ b/arch/um/sys-i386/unmap.c @@ -5,20 +5,17 @@ #include <linux/mman.h> #include <asm/unistd.h> +#include <sys/syscall.h> -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if(munmap(to, size) < 0){ + if (syscall(__NR_munmap, to, size) < 0){ return(-1); } - if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ + if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } - if(munmap(from, size) < 0){ + if (syscall(__NR_munmap, from, size) < 0){ return(-1); } return(0); diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 6fce9f45dfd..73ce4463f70 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -21,7 +21,7 @@ asmlinkage long sys_uname64(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c index d0a25af19a5..ce3e07fcf28 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/um/sys-x86_64/sysrq.c @@ -16,7 +16,7 @@ void __show_regs(struct pt_regs * regs) printk("\n"); print_modules(); printk("Pid: %d, comm: %.20s %s %s\n", - current->pid, current->comm, print_tainted(), system_utsname.release); + current->pid, current->comm, print_tainted(), init_utsname()->release); printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, PT_REGS_RIP(regs)); printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c index f4a4bffd8a1..57c9286a701 100644 --- a/arch/um/sys-x86_64/unmap.c +++ b/arch/um/sys-x86_64/unmap.c @@ -5,20 +5,17 @@ #include <linux/mman.h> #include <asm/unistd.h> +#include <sys/syscall.h> -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if(munmap(to, size) < 0){ + if (syscall(__NR_munmap, to, size) < 0){ return(-1); } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ + if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } - if(munmap(from, size) < 0){ + if (syscall(__NR_munmap, from, size) < 0){ return(-1); } return(0); diff --git a/arch/v850/kernel/memcons.c b/arch/v850/kernel/memcons.c index 815f8a43926..92f514fdcc7 100644 --- a/arch/v850/kernel/memcons.c +++ b/arch/v850/kernel/memcons.c @@ -104,7 +104,7 @@ int memcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static struct tty_operations ops = { +static const struct tty_operations ops = { .open = memcons_tty_open, .write = memcons_tty_write, .write_room = memcons_tty_write_room, diff --git a/arch/v850/kernel/simcons.c b/arch/v850/kernel/simcons.c index 3975aa02cef..9973596ae30 100644 --- a/arch/v850/kernel/simcons.c +++ b/arch/v850/kernel/simcons.c @@ -77,7 +77,7 @@ int simcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static struct tty_operations ops = { +static const struct tty_operations ops = { .open = simcons_tty_open, .write = simcons_tty_write, .write_room = simcons_tty_write_room, diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c index 2ec0700fc46..d2b1fb19d24 100644 --- a/arch/v850/kernel/syscalls.c +++ b/arch/v850/kernel/syscalls.c @@ -33,6 +33,7 @@ #include <asm/uaccess.h> #include <asm/ipc.h> #include <asm/semaphore.h> +#include <asm/unistd.h> /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. @@ -194,3 +195,22 @@ unsigned long sys_mmap (unsigned long addr, size_t len, out: return err; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register char *__a __asm__ ("r6") = filename; + register void *__b __asm__ ("r7") = argv; + register void *__c __asm__ ("r8") = envp; + register unsigned long __syscall __asm__ ("r12") = __NR_execve; + register unsigned long __ret __asm__ ("r10"); + __asm__ __volatile__ ("trap 0" + : "=r" (__ret), "=r" (__syscall) + : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) + : "r1", "r5", "r11", "r13", "r14", + "r15", "r16", "r17", "r18", "r19"); + return __ret; +} diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index b87a19f0d58..0a5d8e659aa 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -690,7 +690,7 @@ source "arch/x86_64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index f280d3665f4..26a01717cc1 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -784,36 +784,36 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name) if (!name) return -EFAULT; - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) + if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); - - err = __copy_to_user(&name->sysname,&system_utsname.sysname, + + err = __copy_to_user(&name->sysname,&utsname()->sysname, __OLD_UTS_LEN); err |= __put_user(0,name->sysname+__OLD_UTS_LEN); - err |= __copy_to_user(&name->nodename,&system_utsname.nodename, + err |= __copy_to_user(&name->nodename,&utsname()->nodename, __OLD_UTS_LEN); err |= __put_user(0,name->nodename+__OLD_UTS_LEN); - err |= __copy_to_user(&name->release,&system_utsname.release, + err |= __copy_to_user(&name->release,&utsname()->release, __OLD_UTS_LEN); err |= __put_user(0,name->release+__OLD_UTS_LEN); - err |= __copy_to_user(&name->version,&system_utsname.version, + err |= __copy_to_user(&name->version,&utsname()->version, __OLD_UTS_LEN); err |= __put_user(0,name->version+__OLD_UTS_LEN); - { - char *arch = "x86_64"; - if (personality(current->personality) == PER_LINUX32) - arch = "i686"; + { + char *arch = "x86_64"; + if (personality(current->personality) == PER_LINUX32) + arch = "i686"; - err |= __copy_to_user(&name->machine,arch,strlen(arch)+1); - } - - up_read(&uts_sem); - - err = err ? -EFAULT : 0; - - return err; + err |= __copy_to_user(&name->machine, arch, strlen(arch)+1); + } + + up_read(&uts_sem); + + err = err ? -EFAULT : 0; + + return err; } long sys32_uname(struct old_utsname __user * name) @@ -822,7 +822,7 @@ long sys32_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 2802524104f..b8285cf1a9c 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -1023,7 +1023,7 @@ ENDPROC(child_rip) * do_sys_execve asm fallback arguments: * rdi: name, rsi: argv, rdx: envp, fake frame on the stack */ -ENTRY(execve) +ENTRY(kernel_execve) CFI_STARTPROC FAKE_STACK_FRAME $0 SAVE_ALL @@ -1036,7 +1036,7 @@ ENTRY(execve) UNFAKE_STACK_FRAME ret CFI_ENDPROC -ENDPROC(execve) +ENDPROC(kernel_execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index ffc73ac7248..ac241567e68 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -270,20 +270,19 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; - struct kretprobe_instance *ri; + struct kretprobe_instance *ri; - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - - add_rp_inst(ri); - } else { - rp->nmissed++; - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } int __kprobes kprobe_handler(struct pt_regs *regs) @@ -405,14 +404,15 @@ no_kprobe: */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head, empty_rp; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -423,20 +423,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri); + recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) /* @@ -454,12 +454,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler * to run (and have re-enabled preemption) - */ - return 1; + */ + return 1; } /* diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 458006ae19f..de10cb8a2c9 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -294,9 +294,9 @@ void __show_regs(struct pt_regs * regs) print_modules(); printk("Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), - system_utsname.release, - (int)strcspn(system_utsname.version, " "), - system_utsname.version); + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); printk_address(regs->rip); printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index 6449ea8fe75..76bf7c241fe 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c @@ -148,7 +148,7 @@ asmlinkage long sys_uname(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, &system_utsname, sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c index 4688ba2db84..d9285d4d556 100644 --- a/arch/xtensa/kernel/syscalls.c +++ b/arch/xtensa/kernel/syscalls.c @@ -128,7 +128,7 @@ out: int sys_uname(struct old_utsname * name) { - if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) + if (name && !copy_to_user(name, utsname(), sizeof (*name))) return 0; return -EFAULT; } @@ -266,3 +266,23 @@ void system_call (struct pt_regs *regs) regs->areg[2] = res; do_syscall_trace(); } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + asm volatile ( + " mov a5, %2 \n" + " mov a4, %4 \n" + " mov a3, %3 \n" + " movi a2, %1 \n" + " syscall \n" + " mov %0, a2 \n" + : "=a" (__res) + : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp) + : "a2", "a3", "a4", "a5"); + return __res; +} diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 22d3c571a7b..5c947cae752 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c @@ -191,7 +191,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, } -static struct tty_operations serial_ops = { +static const struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, |