diff options
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/Kconfig | 4 | ||||
-rw-r--r-- | arch/alpha/include/asm/Kbuild | 3 | ||||
-rw-r--r-- | arch/alpha/include/asm/exec.h | 6 | ||||
-rw-r--r-- | arch/alpha/include/asm/module.h | 10 | ||||
-rw-r--r-- | arch/alpha/include/asm/processor.h | 3 | ||||
-rw-r--r-- | arch/alpha/include/asm/thread_info.h | 3 | ||||
-rw-r--r-- | arch/alpha/include/asm/unistd.h | 1 | ||||
-rw-r--r-- | arch/alpha/include/uapi/asm/Kbuild | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/alpha_ksyms.c | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/entry.S | 155 | ||||
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 33 | ||||
-rw-r--r-- | arch/alpha/kernel/pci-sysfs.c | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/pci.c | 6 | ||||
-rw-r--r-- | arch/alpha/kernel/process.c | 85 | ||||
-rw-r--r-- | arch/alpha/kernel/ptrace.c | 32 | ||||
-rw-r--r-- | arch/alpha/kernel/signal.c | 48 | ||||
-rw-r--r-- | arch/alpha/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/alpha/kernel/srmcons.c | 1 |
18 files changed, 144 insertions, 255 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 9944ded..5dd7f5d 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -20,6 +20,10 @@ config ALPHA select GENERIC_CMOS_UPDATE select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index e423def..64ffc9e 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -1,5 +1,7 @@ include include/asm-generic/Kbuild.asm +generic-y += clkdev.h + header-y += compiler.h header-y += console.h header-y += fpu.h @@ -8,3 +10,4 @@ header-y += pal.h header-y += reg.h header-y += regdef.h header-y += sysinfo.h +generic-y += exec.h diff --git a/arch/alpha/include/asm/exec.h b/arch/alpha/include/asm/exec.h deleted file mode 100644 index 4a5a41f..0000000 --- a/arch/alpha/include/asm/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ALPHA_EXEC_H -#define __ALPHA_EXEC_H - -#define arch_align_stack(x) (x) - -#endif /* __ALPHA_EXEC_H */ diff --git a/arch/alpha/include/asm/module.h b/arch/alpha/include/asm/module.h index 7b63743..9cd13b5 100644 --- a/arch/alpha/include/asm/module.h +++ b/arch/alpha/include/asm/module.h @@ -1,19 +1,13 @@ #ifndef _ALPHA_MODULE_H #define _ALPHA_MODULE_H +#include <asm-generic/module.h> + struct mod_arch_specific { unsigned int gotsecindex; }; -#define Elf_Sym Elf64_Sym -#define Elf_Shdr Elf64_Shdr -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Phdr Elf64_Phdr -#define Elf_Dyn Elf64_Dyn -#define Elf_Rel Elf64_Rel -#define Elf_Rela Elf64_Rela - #define ARCH_SHF_SMALL SHF_ALPHA_GPREL #ifdef MODULE diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h index e37b887..6cb7fe8 100644 --- a/arch/alpha/include/asm/processor.h +++ b/arch/alpha/include/asm/processor.h @@ -49,9 +49,6 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long); /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Create a kernel thread without removing it from tasklists. */ -extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 28335bd..4554ecb 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -84,7 +84,6 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) -#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) /* Work to do on interrupt/exception return. */ @@ -117,5 +116,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); (int __user *)(value)); \ }) +#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) + #endif /* __KERNEL__ */ #endif /* _ALPHA_THREAD_INFO_H */ diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index a31a78e..7826e22 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -481,6 +481,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_RT_SIGSUSPEND +#define __ARCH_WANT_SYS_EXECVE /* "Conditional" syscalls. What we want is diff --git a/arch/alpha/include/uapi/asm/Kbuild b/arch/alpha/include/uapi/asm/Kbuild new file mode 100644 index 0000000..baebb3d --- /dev/null +++ b/arch/alpha/include/uapi/asm/Kbuild @@ -0,0 +1,3 @@ +# UAPI Header export list +include include/uapi/asm-generic/Kbuild.asm + diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 15fa821..89566b3 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -50,9 +50,6 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s); EXPORT_SYMBOL(alpha_write_fp_reg); EXPORT_SYMBOL(alpha_write_fp_reg_s); -/* entry.S */ -EXPORT_SYMBOL(kernel_thread); - /* Networking helper routines. */ EXPORT_SYMBOL(csum_tcpudp_magic); EXPORT_SYMBOL(ip_compute_csum); diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index ec0da05..a760783 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -311,7 +311,7 @@ entSys: .align 4 ret_from_sys_call: - cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ + cmovne $26, 0, $18 /* $18 = 0 => non-restartable */ ldq $0, SP_OFF($sp) and $0, 8, $0 beq $0, ret_to_kernel @@ -320,8 +320,8 @@ ret_to_user: sampling and the rti. */ lda $16, 7 call_pal PAL_swpipl - ldl $5, TI_FLAGS($8) - and $5, _TIF_WORK_MASK, $2 + ldl $17, TI_FLAGS($8) + and $17, _TIF_WORK_MASK, $2 bne $2, work_pending restore_all: RESTORE_ALL @@ -341,10 +341,10 @@ $syscall_error: * frame to indicate that a negative return value wasn't an * error number.. */ - ldq $19, 0($sp) /* old syscall nr (zero if success) */ - beq $19, $ret_success + ldq $18, 0($sp) /* old syscall nr (zero if success) */ + beq $18, $ret_success - ldq $20, 72($sp) /* .. and this a3 */ + ldq $19, 72($sp) /* .. and this a3 */ subq $31, $0, $0 /* with error in v0 */ addq $31, 1, $1 /* set a3 for errno return */ stq $0, 0($sp) @@ -362,51 +362,35 @@ $ret_success: * Do all cleanup when returning from all interrupts and system calls. * * Arguments: - * $5: TI_FLAGS. * $8: current. - * $19: The old syscall number, or zero if this is not a return + * $17: TI_FLAGS. + * $18: The old syscall number, or zero if this is not a return * from a syscall that errored and is possibly restartable. - * $20: The old a3 value + * $19: The old a3 value */ .align 4 .ent work_pending work_pending: - and $5, _TIF_NEED_RESCHED, $2 - beq $2, $work_notifysig + and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2 + bne $2, $work_notifysig $work_resched: - subq $sp, 16, $sp - stq $19, 0($sp) /* save syscall nr */ - stq $20, 8($sp) /* and error indication (a3) */ + /* + * We can get here only if we returned from syscall without SIGPENDING + * or got through work_notifysig already. Either case means no syscall + * restarts for us, so let $18 and $19 burn. + */ jsr $26, schedule - ldq $19, 0($sp) - ldq $20, 8($sp) - addq $sp, 16, $sp - /* Make sure need_resched and sigpending don't change between - sampling and the rti. */ - lda $16, 7 - call_pal PAL_swpipl - ldl $5, TI_FLAGS($8) - and $5, _TIF_WORK_MASK, $2 - beq $2, restore_all - and $5, _TIF_NEED_RESCHED, $2 - bne $2, $work_resched + mov 0, $18 + br ret_to_user $work_notifysig: mov $sp, $16 bsr $1, do_switch_stack - mov $sp, $17 - mov $5, $18 - mov $19, $9 /* save old syscall number */ - mov $20, $10 /* save old a3 */ - and $5, _TIF_SIGPENDING, $2 - cmovne $2, 0, $9 /* we don't want double syscall restarts */ - jsr $26, do_notify_resume - mov $9, $19 - mov $10, $20 + jsr $26, do_work_pending bsr $1, undo_switch_stack - br ret_to_user + br restore_all .end work_pending /* @@ -418,11 +402,10 @@ $work_notifysig: strace: /* set up signal stack, call syscall_trace */ bsr $1, do_switch_stack - jsr $26, syscall_trace + jsr $26, syscall_trace_enter /* returns the syscall number */ bsr $1, undo_switch_stack - /* get the system call number and the arguments back.. */ - ldq $0, 0($sp) + /* get the arguments back.. */ ldq $16, SP_OFF+24($sp) ldq $17, SP_OFF+32($sp) ldq $18, SP_OFF+40($sp) @@ -449,15 +432,15 @@ $strace_success: stq $0, 0($sp) /* save return value */ bsr $1, do_switch_stack - jsr $26, syscall_trace + jsr $26, syscall_trace_leave bsr $1, undo_switch_stack br $31, ret_from_sys_call .align 3 $strace_error: - ldq $19, 0($sp) /* old syscall nr (zero if success) */ - beq $19, $strace_success - ldq $20, 72($sp) /* .. and this a3 */ + ldq $18, 0($sp) /* old syscall nr (zero if success) */ + beq $18, $strace_success + ldq $19, 72($sp) /* .. and this a3 */ subq $31, $0, $0 /* with error in v0 */ addq $31, 1, $1 /* set a3 for errno return */ @@ -465,11 +448,11 @@ $strace_error: stq $1, 72($sp) /* a3 for return */ bsr $1, do_switch_stack - mov $19, $9 /* save old syscall number */ - mov $20, $10 /* save old a3 */ - jsr $26, syscall_trace - mov $9, $19 - mov $10, $20 + mov $18, $9 /* save old syscall number */ + mov $19, $10 /* save old a3 */ + jsr $26, syscall_trace_leave + mov $9, $18 + mov $10, $19 bsr $1, undo_switch_stack mov $31, $26 /* tell "ret_from_sys_call" we can restart */ @@ -609,59 +592,20 @@ ret_from_fork: .end ret_from_fork /* - * kernel_thread(fn, arg, clone_flags) + * ... and new kernel threads - here */ .align 4 - .globl kernel_thread - .ent kernel_thread -kernel_thread: - /* We can be called from a module. */ - ldgp $gp, 0($27) - .prologue 1 - subq $sp, SP_OFF+6*8, $sp - br $1, 2f /* load start address */ - - /* We've now "returned" from a fake system call. */ - unop - blt $0, 1f /* error? */ - ldi $1, 0x3fff - beq $20, 1f /* parent or child? */ - - bic $sp, $1, $8 /* in child. */ - jsr $26, ($27) - ldgp $gp, 0($26) - mov $0, $16 - mov $31, $26 - jmp $31, sys_exit - -1: ret /* in parent. */ - - .align 4 -2: /* Fake a system call stack frame, as we can't do system calls - from kernel space. Note that we store FN and ARG as they - need to be set up in the child for the call. Also store $8 - and $26 for use in the parent. */ - stq $31, SP_OFF($sp) /* ps */ - stq $1, SP_OFF+8($sp) /* pc */ - stq $gp, SP_OFF+16($sp) /* gp */ - stq $16, 136($sp) /* $27; FN for child */ - stq $17, SP_OFF+24($sp) /* $16; ARG for child */ - stq $8, 64($sp) /* $8 */ - stq $26, 128($sp) /* $26 */ - /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */ - ldq $2, alpha_mv+HAE_CACHE - stq $2, 152($sp) /* HAE */ - - /* Shuffle FLAGS to the front; add CLONE_VM. */ - ldi $1, CLONE_VM|CLONE_UNTRACED - or $18, $1, $16 - bsr $26, sys_clone - - /* We don't actually care for a3 success widgetry in the kernel. - Not for positive errno values. */ - stq $0, 0($sp) /* $0 */ - br ret_to_kernel -.end kernel_thread + .globl ret_from_kernel_thread + .ent ret_from_kernel_thread +ret_from_kernel_thread: + mov $17, $16 + jsr $26, schedule_tail + mov $9, $27 + mov $10, $16 + jsr $26, ($9) + mov $31, $19 /* to disable syscall restarts */ + br $31, ret_to_user +.end ret_from_kernel_thread /* @@ -722,7 +666,7 @@ sys_sigreturn: lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_sigreturn bne $9, 1f - jsr $26, syscall_trace + jsr $26, syscall_trace_leave 1: br $1, undo_switch_stack br ret_from_sys_call .end sys_sigreturn @@ -739,21 +683,12 @@ sys_rt_sigreturn: lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_rt_sigreturn bne $9, 1f - jsr $26, syscall_trace + jsr $26, syscall_trace_leave 1: br $1, undo_switch_stack br ret_from_sys_call .end sys_rt_sigreturn .align 4 - .globl sys_execve - .ent sys_execve -sys_execve: - .prologue 0 - mov $sp, $19 - jmp $31, do_sys_execve -.end sys_execve - - .align 4 .globl alpha_ni_syscall .ent alpha_ni_syscall alpha_ni_syscall: diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index bc1acdd..9eb0905 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -145,27 +145,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd, long __user *, basep) { int error; - struct file *file; + struct fd arg = fdget(fd); struct osf_dirent_callback buf; - error = -EBADF; - file = fget(fd); - if (!file) - goto out; + if (!arg.file) + return -EBADF; buf.dirent = dirent; buf.basep = basep; buf.count = count; buf.error = 0; - error = vfs_readdir(file, osf_filldir, &buf); + error = vfs_readdir(arg.file, osf_filldir, &buf); if (error >= 0) error = buf.error; if (count != buf.count) error = count - buf.count; - fput(file); - out: + fdput(arg); return error; } @@ -278,8 +275,8 @@ linux_to_osf_stat(struct kstat *lstat, struct osf_stat __user *osf_stat) tmp.st_dev = lstat->dev; tmp.st_mode = lstat->mode; tmp.st_nlink = lstat->nlink; - tmp.st_uid = lstat->uid; - tmp.st_gid = lstat->gid; + tmp.st_uid = from_kuid_munged(current_user_ns(), lstat->uid); + tmp.st_gid = from_kgid_munged(current_user_ns(), lstat->gid); tmp.st_rdev = lstat->rdev; tmp.st_ldev = lstat->rdev; tmp.st_size = lstat->size; @@ -452,7 +449,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) { int retval; struct cdfs_args tmp; - char *devname; + struct filename *devname; retval = -EFAULT; if (copy_from_user(&tmp, args, sizeof(tmp))) @@ -461,7 +458,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) retval = PTR_ERR(devname); if (IS_ERR(devname)) goto out; - retval = do_mount(devname, dirname, "ext2", flags, NULL); + retval = do_mount(devname->name, dirname, "ext2", flags, NULL); putname(devname); out: return retval; @@ -472,7 +469,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) { int retval; struct cdfs_args tmp; - char *devname; + struct filename *devname; retval = -EFAULT; if (copy_from_user(&tmp, args, sizeof(tmp))) @@ -481,7 +478,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) retval = PTR_ERR(devname); if (IS_ERR(devname)) goto out; - retval = do_mount(devname, dirname, "iso9660", flags, NULL); + retval = do_mount(devname->name, dirname, "iso9660", flags, NULL); putname(devname); out: return retval; @@ -502,7 +499,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path, int, flag, void __user *, data) { int retval; - char *name; + struct filename *name; name = getname(path); retval = PTR_ERR(name); @@ -510,13 +507,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path, goto out; switch (typenr) { case 1: - retval = osf_ufs_mount(name, data, flag); + retval = osf_ufs_mount(name->name, data, flag); break; case 6: - retval = osf_cdfs_mount(name, data, flag); + retval = osf_cdfs_mount(name->name, data, flag); break; case 9: - retval = osf_procfs_mount(name, data, flag); + retval = osf_procfs_mount(name->name, data, flag); break; default: retval = -EINVAL; diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 53649c7..b51f7b4 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -26,7 +26,7 @@ static int hose_mmap_page_range(struct pci_controller *hose, base = sparse ? hose->sparse_io_base : hose->dense_io_base; vma->vm_pgoff += base >> PAGE_SHIFT; - vma->vm_flags |= (VM_IO | VM_RESERVED); + vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 9816d5a..ef75714 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -256,12 +256,6 @@ pcibios_fixup_bus(struct pci_bus *bus) } } -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index d6fde98..4054e0f 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -28,6 +28,7 @@ #include <linux/tty.h> #include <linux/console.h> #include <linux/slab.h> +#include <linux/rcupdate.h> #include <asm/reg.h> #include <asm/uaccess.h> @@ -54,9 +55,12 @@ cpu_idle(void) /* FIXME -- EV6 and LCA45 know how to power down the CPU. */ + rcu_idle_enter(); while (!need_resched()) cpu_relax(); - schedule(); + + rcu_idle_exit(); + schedule_preempt_disabled(); } } @@ -259,33 +263,35 @@ alpha_vfork(struct pt_regs *regs) /* * Copy an alpha thread.. - * - * Note the "stack_offset" stuff: when returning to kernel mode, we need - * to have some extra stack-space for the kernel stack that still exists - * after the "ret_from_fork". When returning to user mode, we only want - * the space needed by the syscall stack frame (ie "struct pt_regs"). - * Use the passed "regs" pointer to determine how much space we need - * for a kernel fork(). */ int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long unused, + unsigned long arg, struct task_struct * p, struct pt_regs * regs) { extern void ret_from_fork(void); + extern void ret_from_kernel_thread(void); struct thread_info *childti = task_thread_info(p); - struct pt_regs * childregs; - struct switch_stack * childstack, *stack; - unsigned long stack_offset, settls; - - stack_offset = PAGE_SIZE - sizeof(struct pt_regs); - if (!(regs->ps & 8)) - stack_offset = (PAGE_SIZE-1) & (unsigned long) regs; - childregs = (struct pt_regs *) - (stack_offset + PAGE_SIZE + task_stack_page(p)); - + struct pt_regs *childregs = task_pt_regs(p); + struct switch_stack *childstack, *stack; + unsigned long settls; + + childstack = ((struct switch_stack *) childregs) - 1; + if (unlikely(!regs)) { + /* kernel thread */ + memset(childstack, 0, + sizeof(struct switch_stack) + sizeof(struct pt_regs)); + childstack->r26 = (unsigned long) ret_from_kernel_thread; + childstack->r9 = usp; /* function */ + childstack->r10 = arg; + childregs->hae = alpha_mv.hae_cache, + childti->pcb.usp = 0; + childti->pcb.ksp = (unsigned long) childstack; + childti->pcb.flags = 1; /* set FEN, clear everything else */ + return 0; + } *childregs = *regs; settls = regs->r20; childregs->r0 = 0; @@ -293,7 +299,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp, childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */ regs->r20 = 0; stack = ((struct switch_stack *) regs) - 1; - childstack = ((struct switch_stack *) childregs) - 1; *childstack = *stack; childstack->r26 = (unsigned long) ret_from_fork; childti->pcb.usp = usp; @@ -382,27 +387,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) EXPORT_SYMBOL(dump_elf_task_fp); /* - * sys_execve() executes a new program. - */ -asmlinkage int -do_sys_execve(const char __user *ufilename, - const char __user *const __user *argv, - const char __user *const __user *envp, struct pt_regs *regs) -{ - int error; - char *filename; - - filename = getname(ufilename); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, argv, envp, regs); - putname(filename); -out: - return error; -} - -/* * Return saved PC of a blocked thread. This assumes the frame * pointer is the 6th saved long on the kernel stack and that the * saved return address is the first long in the frame. This all @@ -455,22 +439,3 @@ get_wchan(struct task_struct *p) } return pc; } - -int kernel_execve(const char *path, const char *const argv[], const char *const envp[]) -{ - /* Avoid the HAE being gratuitously wrong, which would cause us - to do the whole turn off interrupts thing and restore it. */ - struct pt_regs regs = {.hae = alpha_mv.hae_cache}; - int err = do_execve(path, argv, envp, ®s); - if (!err) { - struct pt_regs *p = current_pt_regs(); - /* copy regs to normal position and off to userland we go... */ - *p = regs; - __asm__ __volatile__ ( - "mov %0, $sp;" - "br $31, ret_from_sys_call" - : : "r"(p)); - } - return err; -} -EXPORT_SYMBOL(kernel_execve); diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 54616f4..2a4a80f 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -13,6 +13,7 @@ #include <linux/user.h> #include <linux/security.h> #include <linux/signal.h> +#include <linux/tracehook.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -312,25 +313,18 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } +asmlinkage unsigned long syscall_trace_enter(void) +{ + unsigned long ret = 0; + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(current_pt_regs())) + ret = -1UL; + return ret ?: current_pt_regs()->r0; +} + asmlinkage void -syscall_trace(void) +syscall_trace_leave(void) { - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - if (!(current->ptrace & PT_PTRACED)) - return; - /* The 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * This isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(current_pt_regs(), 0); } diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index a8c97d4..32575f8 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -298,8 +298,9 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, - struct switch_stack *sw, unsigned long mask, unsigned long sp) + unsigned long mask, unsigned long sp) { + struct switch_stack *sw = (struct switch_stack *)regs - 1; long i, err = 0; err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); @@ -354,7 +355,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, - struct pt_regs *regs, struct switch_stack * sw) + struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct sigframe __user *frame; @@ -364,7 +365,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return -EFAULT; - err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); + err |= setup_sigcontext(&frame->sc, regs, set->sig[0], oldsp); if (err) return -EFAULT; @@ -401,7 +402,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) + sigset_t *set, struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct rt_sigframe __user *frame; @@ -420,7 +421,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], oldsp); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); if (err) @@ -464,15 +465,15 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, */ static inline void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, - struct pt_regs * regs, struct switch_stack *sw) + struct pt_regs * regs) { sigset_t *oldset = sigmask_to_save(); int ret; if (ka->sa.sa_flags & SA_SIGINFO) - ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); + ret = setup_rt_frame(sig, ka, info, oldset, regs); else - ret = setup_frame(sig, ka, oldset, regs, sw); + ret = setup_frame(sig, ka, oldset, regs); if (ret) { force_sigsegv(sig, current); @@ -519,8 +520,7 @@ syscall_restart(unsigned long r0, unsigned long r19, * all (if we get here from anything but a syscall return, it will be 0) */ static void -do_signal(struct pt_regs * regs, struct switch_stack * sw, - unsigned long r0, unsigned long r19) +do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; @@ -537,7 +537,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw, /* Whee! Actually deliver the signal. */ if (r0) syscall_restart(r0, r19, regs, &ka); - handle_signal(signr, &ka, &info, regs, sw); + handle_signal(signr, &ka, &info, regs); if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ return; @@ -568,15 +568,23 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw, } void -do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, - unsigned long thread_info_flags, +do_work_pending(struct pt_regs *regs, unsigned long thread_flags, unsigned long r0, unsigned long r19) { - if (thread_info_flags & _TIF_SIGPENDING) - do_signal(regs, sw, r0, r19); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - } + do { + if (thread_flags & _TIF_NEED_RESCHED) { + schedule(); + } else { + local_irq_enable(); + if (thread_flags & _TIF_SIGPENDING) { + do_signal(regs, r0, r19); + r0 = 0; + } else { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + } + } + local_irq_disable(); + thread_flags = current_thread_info()->flags; + } while (thread_flags & _TIF_WORK_MASK); } diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 35ddc02..a41ad90 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -166,6 +166,7 @@ smp_callin(void) DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", cpuid, current, current->active_mm)); + preempt_disable(); /* Do nothing. */ cpu_idle(); } diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 3ea8094..5d58652 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -223,6 +223,7 @@ srmcons_init(void) driver->subtype = SYSTEM_TYPE_SYSCONS; driver->init_termios = tty_std_termios; tty_set_operations(driver, &srmcons_ops); + tty_port_link_device(&srmcons_singleton.port, driver, 0); err = tty_register_driver(driver); if (err) { put_tty_driver(driver); |