diff options
author | Steven J. Hill <sjhill@realitydiluted.com> | 2005-02-28 22:51:33 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:30:47 -0400 |
commit | 784f7b9d895893c6aa3ca471c1344a62fc29c285 (patch) | |
tree | 6a1be4fbbd1ed4b0df09e18878b01d43124e0622 /arch/mips/kernel | |
parent | 333d1f6794b341df11f286f5dca123c6dc64a770 (diff) |
Fix 'prctl' system call for IRIX. At this point IRIX 5.3 static binaries
are now working for 80% of the ones I have tried. The other ones that do
not work all fail in the same way with the same messages. Once that bug
is tracked down, we should be in good shape. Task locking still needs
some work.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/sysirix.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 7ae4af476974..ed7c0e3c2f85 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c | |||
@@ -73,32 +73,30 @@ asmlinkage int irix_sysmp(struct pt_regs *regs) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* The prctl commands. */ | 75 | /* The prctl commands. */ |
76 | #define PR_MAXPROCS 1 /* Tasks/user. */ | 76 | #define PR_MAXPROCS 1 /* Tasks/user. */ |
77 | #define PR_ISBLOCKED 2 /* If blocked, return 1. */ | 77 | #define PR_ISBLOCKED 2 /* If blocked, return 1. */ |
78 | #define PR_SETSTACKSIZE 3 /* Set largest task stack size. */ | 78 | #define PR_SETSTACKSIZE 3 /* Set largest task stack size. */ |
79 | #define PR_GETSTACKSIZE 4 /* Get largest task stack size. */ | 79 | #define PR_GETSTACKSIZE 4 /* Get largest task stack size. */ |
80 | #define PR_MAXPPROCS 5 /* Num parallel tasks. */ | 80 | #define PR_MAXPPROCS 5 /* Num parallel tasks. */ |
81 | #define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */ | 81 | #define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */ |
82 | #define PR_SETEXITSIG 8 /* When task exit's, set signal. */ | 82 | #define PR_SETEXITSIG 8 /* When task exit's, set signal. */ |
83 | #define PR_RESIDENT 9 /* Make task unswappable. */ | 83 | #define PR_RESIDENT 9 /* Make task unswappable. */ |
84 | #define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */ | 84 | #define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */ |
85 | #define PR_DETACHADDR 11 /* Disconnect a vma from a task. */ | 85 | #define PR_DETACHADDR 11 /* Disconnect a vma from a task. */ |
86 | #define PR_TERMCHILD 12 /* When parent sleeps with fishes, kill child. */ | 86 | #define PR_TERMCHILD 12 /* Kill child if the parent dies. */ |
87 | #define PR_GETSHMASK 13 /* Get the sproc() share mask. */ | 87 | #define PR_GETSHMASK 13 /* Get the sproc() share mask. */ |
88 | #define PR_GETNSHARE 14 /* Number of share group members. */ | 88 | #define PR_GETNSHARE 14 /* Number of share group members. */ |
89 | #define PR_COREPID 15 /* Add task pid to name when it core. */ | 89 | #define PR_COREPID 15 /* Add task pid to name when it core. */ |
90 | #define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */ | 90 | #define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */ |
91 | #define PR_PTHREADEXIT 17 /* Kill a pthread without prejudice. */ | 91 | #define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */ |
92 | 92 | ||
93 | asmlinkage int irix_prctl(struct pt_regs *regs) | 93 | asmlinkage int irix_prctl(unsigned option, ...) |
94 | { | 94 | { |
95 | unsigned long cmd; | 95 | va_list args; |
96 | int error = 0, base = 0; | 96 | int error = 0; |
97 | 97 | ||
98 | if (regs->regs[2] == 1000) | 98 | va_start(args, option); |
99 | base = 1; | 99 | switch (option) { |
100 | cmd = regs->regs[base + 4]; | ||
101 | switch (cmd) { | ||
102 | case PR_MAXPROCS: | 100 | case PR_MAXPROCS: |
103 | printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", | 101 | printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", |
104 | current->comm, current->pid); | 102 | current->comm, current->pid); |
@@ -111,7 +109,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs) | |||
111 | printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", | 109 | printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", |
112 | current->comm, current->pid); | 110 | current->comm, current->pid); |
113 | read_lock(&tasklist_lock); | 111 | read_lock(&tasklist_lock); |
114 | task = find_task_by_pid(regs->regs[base + 5]); | 112 | task = find_task_by_pid(va_arg(args, pid_t)); |
115 | error = -ESRCH; | 113 | error = -ESRCH; |
116 | if (error) | 114 | if (error) |
117 | error = (task->run_list.next != NULL); | 115 | error = (task->run_list.next != NULL); |
@@ -121,7 +119,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs) | |||
121 | } | 119 | } |
122 | 120 | ||
123 | case PR_SETSTACKSIZE: { | 121 | case PR_SETSTACKSIZE: { |
124 | long value = regs->regs[base + 5]; | 122 | long value = va_arg(args, long); |
125 | 123 | ||
126 | printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n", | 124 | printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n", |
127 | current->comm, current->pid, (unsigned long) value); | 125 | current->comm, current->pid, (unsigned long) value); |
@@ -222,17 +220,13 @@ asmlinkage int irix_prctl(struct pt_regs *regs) | |||
222 | error = -EINVAL; | 220 | error = -EINVAL; |
223 | break; | 221 | break; |
224 | 222 | ||
225 | case PR_PTHREADEXIT: | ||
226 | printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n", | ||
227 | current->comm, current->pid); | ||
228 | do_exit(regs->regs[base + 5]); | ||
229 | |||
230 | default: | 223 | default: |
231 | printk("irix_prctl[%s:%d]: Non-existant opcode %d\n", | 224 | printk("irix_prctl[%s:%d]: Non-existant opcode %d\n", |
232 | current->comm, current->pid, (int)cmd); | 225 | current->comm, current->pid, option); |
233 | error = -EINVAL; | 226 | error = -EINVAL; |
234 | break; | 227 | break; |
235 | } | 228 | } |
229 | va_end(args); | ||
236 | 230 | ||
237 | return error; | 231 | return error; |
238 | } | 232 | } |