aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven J. Hill <sjhill@realitydiluted.com>2005-02-28 22:51:33 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:30:47 -0400
commit784f7b9d895893c6aa3ca471c1344a62fc29c285 (patch)
tree6a1be4fbbd1ed4b0df09e18878b01d43124e0622
parent333d1f6794b341df11f286f5dca123c6dc64a770 (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>
-rw-r--r--arch/mips/kernel/sysirix.c60
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
93asmlinkage int irix_prctl(struct pt_regs *regs) 93asmlinkage 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}