Commit 74126cb0 authored by Richard Henderson's avatar Richard Henderson

More merging from entry-rewrite tree:

Implement sys_sethae, osf_getpriority, sys_getxuid, sys_getxgid, sys_getxpid,
sys_pipe, alpha_ni_syscall directly in assembly.

Bounce alpha_create_module, sys_ptrace through an assembly stub to pass
pt_regs by reference.
parent 2cef4ed8
...@@ -20,11 +20,22 @@ void foo(void) ...@@ -20,11 +20,22 @@ void foo(void)
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
BLANK(); BLANK();
DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
DEFINE(TASK_UID, offsetof(struct task_struct, uid));
DEFINE(TASK_EUID, offsetof(struct task_struct, euid));
DEFINE(TASK_GID, offsetof(struct task_struct, gid));
DEFINE(TASK_EGID, offsetof(struct task_struct, egid));
DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
BLANK();
DEFINE(PT_PTRACED, PT_PTRACED); DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
DEFINE(SIGCHLD, SIGCHLD); DEFINE(SIGCHLD, SIGCHLD);
BLANK(); BLANK();
DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache)); DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register)); DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register));
} }
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <asm/system.h>
#include <asm/cache.h>
#include <asm/asm_offsets.h> #include <asm/asm_offsets.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/pal.h>
#include <asm/errno.h>
#include <asm/unistd.h> #include <asm/unistd.h>
.text .text
...@@ -582,7 +582,7 @@ alpha_switch_to: ...@@ -582,7 +582,7 @@ alpha_switch_to:
lda $8, 0x3fff lda $8, 0x3fff
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
bic $sp, $8, $8 bic $sp, $8, $8
ret $31, ($26), 1 ret
.end alpha_switch_to .end alpha_switch_to
/* /*
...@@ -687,6 +687,7 @@ __kernel_execve: ...@@ -687,6 +687,7 @@ __kernel_execve:
.globl sys_fork .globl sys_fork
.ent sys_fork .ent sys_fork
sys_fork: sys_fork:
.prologue 0
mov $sp, $19 mov $sp, $19
bsr $1, do_switch_stack bsr $1, do_switch_stack
/* A fork is the same as clone(SIGCHLD, 0); */ /* A fork is the same as clone(SIGCHLD, 0); */
...@@ -695,37 +696,40 @@ sys_fork: ...@@ -695,37 +696,40 @@ sys_fork:
mov $31, $18 mov $31, $18
jsr $26, alpha_clone jsr $26, alpha_clone
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
ret $31, ($26), 1 ret
.end sys_fork .end sys_fork
.align 4 .align 4
.globl sys_clone .globl sys_clone
.ent sys_clone .ent sys_clone
sys_clone: sys_clone:
.prologue 0
mov $sp, $19 mov $sp, $19
bsr $1, do_switch_stack bsr $1, do_switch_stack
/* $16, $17, $18, $19 come from the user; $19 is used later /* $16, $17, $18, $19 come from the user; $19 is used later
via pt_regs->r19. */ via pt_regs->r19. */
jsr $26, alpha_clone jsr $26, alpha_clone
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
ret $31, ($26), 1 ret
.end sys_clone .end sys_clone
.align 4 .align 4
.globl sys_vfork .globl sys_vfork
.ent sys_vfork .ent sys_vfork
sys_vfork: sys_vfork:
.prologue 0
bsr $1, do_switch_stack bsr $1, do_switch_stack
mov $sp, $16 mov $sp, $16
jsr $26, alpha_vfork jsr $26, alpha_vfork
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
ret $31, ($26), 1 ret
.end sys_vfork .end sys_vfork
.align 4 .align 4
.globl sys_sigreturn .globl sys_sigreturn
.ent sys_sigreturn .ent sys_sigreturn
sys_sigreturn: sys_sigreturn:
.prologue 0
mov $sp, $17 mov $sp, $17
lda $18, -SWITCH_STACK_SIZE($sp) lda $18, -SWITCH_STACK_SIZE($sp)
lda $sp, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp)
...@@ -738,6 +742,7 @@ sys_sigreturn: ...@@ -738,6 +742,7 @@ sys_sigreturn:
.globl sys_rt_sigreturn .globl sys_rt_sigreturn
.ent sys_rt_sigreturn .ent sys_rt_sigreturn
sys_rt_sigreturn: sys_rt_sigreturn:
.prologue 0
mov $sp, $17 mov $sp, $17
lda $18, -SWITCH_STACK_SIZE($sp) lda $18, -SWITCH_STACK_SIZE($sp)
lda $sp, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp)
...@@ -750,6 +755,7 @@ sys_rt_sigreturn: ...@@ -750,6 +755,7 @@ sys_rt_sigreturn:
.globl sys_sigsuspend .globl sys_sigsuspend
.ent sys_sigsuspend .ent sys_sigsuspend
sys_sigsuspend: sys_sigsuspend:
.prologue 0
mov $sp, $17 mov $sp, $17
br $1, do_switch_stack br $1, do_switch_stack
mov $sp, $18 mov $sp, $18
...@@ -758,13 +764,14 @@ sys_sigsuspend: ...@@ -758,13 +764,14 @@ sys_sigsuspend:
jsr $26, do_sigsuspend jsr $26, do_sigsuspend
ldq $26, 0($sp) ldq $26, 0($sp)
lda $sp, SWITCH_STACK_SIZE+16($sp) lda $sp, SWITCH_STACK_SIZE+16($sp)
ret $31, ($26), 1 ret
.end sys_sigsuspend .end sys_sigsuspend
.align 4 .align 4
.globl sys_rt_sigsuspend .globl sys_rt_sigsuspend
.ent sys_rt_sigsuspend .ent sys_rt_sigsuspend
sys_rt_sigsuspend: sys_rt_sigsuspend:
.prologue 0
mov $sp, $18 mov $sp, $18
br $1, do_switch_stack br $1, do_switch_stack
mov $sp, $19 mov $sp, $19
...@@ -773,5 +780,141 @@ sys_rt_sigsuspend: ...@@ -773,5 +780,141 @@ sys_rt_sigsuspend:
jsr $26, do_rt_sigsuspend jsr $26, do_rt_sigsuspend
ldq $26, 0($sp) ldq $26, 0($sp)
lda $sp, SWITCH_STACK_SIZE+16($sp) lda $sp, SWITCH_STACK_SIZE+16($sp)
ret $31, ($26), 1 ret
.end sys_rt_sigsuspend .end sys_rt_sigsuspend
.align 4
.globl sys_sethae
.ent sys_sethae
sys_sethae:
.prologue 0
stq $16, 152($sp)
ret
.end sys_sethae
.align 4
.globl osf_getpriority
.ent osf_getpriority
osf_getpriority:
lda $sp, -16($sp)
stq $26, 0($sp)
.prologue 0
jsr $26, sys_getpriority
ldq $26, 0($sp)
blt $0, 1f
/* Return value is the unbiased priority, i.e. 20 - prio.
This does result in negative return values, so signal
no error by writing into the R0 slot. */
lda $1, 20
stq $31, 16($sp)
subl $1, $0, $0
unop
1: lda $sp, 16($sp)
ret
.end osf_getpriority
.align 4
.globl sys_getxuid
.ent sys_getxuid
sys_getxuid:
.prologue 0
ldq $2, TI_TASK($8)
ldl $0, TASK_UID($2)
ldl $1, TASK_EUID($2)
stq $1, 80($sp)
ret
.end sys_getxuid
.align 4
.globl sys_getxgid
.ent sys_getxgid
sys_getxgid:
.prologue 0
ldq $2, TI_TASK($8)
ldl $0, TASK_GID($2)
ldl $1, TASK_EGID($2)
stq $1, 80($sp)
ret
.end sys_getxgid
.align 4
.globl sys_getxpid
.ent sys_getxpid
sys_getxpid:
.prologue 0
ldq $2, TI_TASK($8)
/* See linux/kernel/timer.c sys_getppid for discussion
about this loop. */
ldq $3, TASK_REAL_PARENT($2)
1: ldl $1, TASK_TGID($3)
#if CONFIG_SMP
mov $3, $4
mb
ldq $3, TASK_REAL_PARENT($2)
cmpeq $3, $4, $4
beq $4, 1b
#endif
stq $1, 80($sp)
ldl $0, TASK_TGID($2)
ret
.end sys_getxpid
.align 4
.globl sys_pipe
.ent sys_pipe
sys_pipe:
lda $sp, -16($sp)
stq $26, 0($sp)
.prologue 0
lda $16, 8($sp)
jsr $26, do_pipe
ldq $26, 0($sp)
bne $0, 1f
/* The return values are in $0 and $20. */
ldl $1, 12($sp)
ldl $0, 8($sp)
stq $1, 80+16($sp)
1: lda $sp, 16($sp)
ret
.end sys_pipe
.align 4
.globl alpha_create_module
.ent alpha_create_module
alpha_create_module:
.prologue 0
mov $sp, $18
jmp $31, do_alpha_create_module
.end alpha_create_module
.align 4
.globl sys_ptrace
.ent sys_ptrace
sys_ptrace:
.prologue 0
mov $sp, $20
jmp $31, do_sys_ptrace
.end sys_ptrace
.align 4
.globl alpha_ni_syscall
.ent alpha_ni_syscall
alpha_ni_syscall:
.prologue 0
/* Special because it also implements overflow handling via
syscall number 0. And if you recall, zero is a special
trigger for "not an error". Store large non-zero there. */
lda $0, -ENOSYS
unop
stq $0, 0($sp)
ret
.end alpha_ni_syscall
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
extern int do_pipe(int *); extern int do_pipe(int *);
extern asmlinkage unsigned long sys_brk(unsigned long); extern asmlinkage unsigned long sys_brk(unsigned long);
extern int sys_getpriority(int, int);
extern asmlinkage unsigned long sys_create_module(char *, unsigned long); extern asmlinkage unsigned long sys_create_module(char *, unsigned long);
/* /*
...@@ -172,68 +171,9 @@ osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, ...@@ -172,68 +171,9 @@ osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
#undef ROUND_UP #undef ROUND_UP
#undef NAME_OFFSET #undef NAME_OFFSET
/*
* Alpha syscall convention has no problem returning negative
* values:
*/
asmlinkage int
osf_getpriority(int which, int who,
int a2, int a3, int a4, int a5, struct pt_regs regs)
{
extern int sys_getpriority(int, int);
int prio;
/*
* We don't need to acquire the kernel lock here, because
* all of these operations are local. sys_getpriority
* will get the lock as required..
*/
prio = sys_getpriority(which, who);
if (prio >= 0) {
regs.r0 = 0; /* special return: no errors */
prio = 20 - prio;
}
return prio;
}
/*
* No need to acquire the kernel lock, we're local..
*/
asmlinkage unsigned long
sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->euid;
return tsk->uid;
}
asmlinkage unsigned long
sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->egid;
return tsk->gid;
}
asmlinkage unsigned long
sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct *tsk = current;
/*
* This isn't strictly "local" any more and we should actually
* acquire the kernel lock. The "p_opptr" pointer might change
* if the parent goes away (or due to ptrace). But any race
* isn't actually going to matter, as if the parent happens
* to change we can happily return either of the pids.
*/
(&regs)->r20 = tsk->real_parent->tgid;
return tsk->tgid;
}
asmlinkage unsigned long asmlinkage unsigned long
osf_mmap(unsigned long addr, unsigned long len, unsigned long prot, osf_mmap(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long off) unsigned long flags, unsigned long fd, unsigned long off)
{ {
struct file *file = NULL; struct file *file = NULL;
unsigned long ret = -EBADF; unsigned long ret = -EBADF;
...@@ -502,19 +442,6 @@ sys_getdtablesize(void) ...@@ -502,19 +442,6 @@ sys_getdtablesize(void)
return NR_OPEN; return NR_OPEN;
} }
asmlinkage int
sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
int fd[2], error;
error = do_pipe(fd);
if (!error) {
regs.r20 = fd[1];
error = fd[0];
}
return error;
}
/* /*
* For compatibility with OSF/1 only. Use utsname(2) instead. * For compatibility with OSF/1 only. Use utsname(2) instead.
*/ */
...@@ -723,8 +650,8 @@ osf_sigstack(struct sigstack *uss, struct sigstack *uoss) ...@@ -723,8 +650,8 @@ osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
*/ */
asmlinkage unsigned long asmlinkage unsigned long
alpha_create_module(char *module_name, unsigned long size, do_alpha_create_module(char *module_name, unsigned long size,
int a3, int a4, int a5, int a6, struct pt_regs regs) struct pt_regs *regs)
{ {
long retval; long retval;
...@@ -735,7 +662,7 @@ alpha_create_module(char *module_name, unsigned long size, ...@@ -735,7 +662,7 @@ alpha_create_module(char *module_name, unsigned long size,
the error number is a small negative number, while the address the error number is a small negative number, while the address
is always negative but much larger. */ is always negative but much larger. */
if (retval + 1000 < 0) if (retval + 1000 < 0)
regs.r0 = 0; regs->r0 = 0;
unlock_kernel(); unlock_kernel();
return retval; return retval;
......
...@@ -42,18 +42,6 @@ ...@@ -42,18 +42,6 @@
#include "proto.h" #include "proto.h"
#include "pci_impl.h" #include "pci_impl.h"
/*
* No need to acquire the kernel lock, we're entirely local..
*/
asmlinkage int
sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
(&regs)->hae = hae;
return 0;
}
void default_idle(void) void default_idle(void)
{ {
barrier(); barrier();
......
...@@ -249,8 +249,8 @@ void ptrace_disable(struct task_struct *child) ...@@ -249,8 +249,8 @@ void ptrace_disable(struct task_struct *child)
} }
asmlinkage long asmlinkage long
sys_ptrace(long request, long pid, long addr, long data, do_sys_ptrace(long request, long pid, long addr, long data,
int a4, int a5, struct pt_regs regs) struct pt_regs *regs)
{ {
struct task_struct *child; struct task_struct *child;
long ret; long ret;
...@@ -307,14 +307,14 @@ sys_ptrace(long request, long pid, long addr, long data, ...@@ -307,14 +307,14 @@ sys_ptrace(long request, long pid, long addr, long data,
if (copied != sizeof(tmp)) if (copied != sizeof(tmp))
goto out; goto out;
regs.r0 = 0; /* special return: no errors */ regs->r0 = 0; /* special return: no errors */
ret = tmp; ret = tmp;
goto out; goto out;
} }
/* Read register number ADDR. */ /* Read register number ADDR. */
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
regs.r0 = 0; /* special return: no errors */ regs->r0 = 0; /* special return: no errors */
ret = get_reg(child, addr); ret = get_reg(child, addr);
DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
goto out; goto out;
......
...@@ -1078,22 +1078,6 @@ do_entUnaUser(void * va, unsigned long opcode, ...@@ -1078,22 +1078,6 @@ do_entUnaUser(void * va, unsigned long opcode,
return; return;
} }
/*
* Unimplemented system calls.
*/
asmlinkage long
alpha_ni_syscall(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
/* We only get here for OSF system calls, minus #112;
the rest go to sys_ni_syscall. */
#if 0
printk("<sc %ld(%lx,%lx,%lx)>", regs.r0, a0, a1, a2);
#endif
return -ENOSYS;
}
void void
trap_init(void) trap_init(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment