diff options
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/Makefile | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 419 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 61 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal.c | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal32.c | 300 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 41 | ||||
-rw-r--r-- | arch/sparc64/kernel/sunos_ioctl32.c | 275 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 38 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 1359 | ||||
-rw-r--r-- | arch/sparc64/kernel/systbls.S | 122 | ||||
-rw-r--r-- | arch/sparc64/kernel/systbls.h | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/ttable.S | 14 |
12 files changed, 15 insertions, 2626 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 459462e80a12..63c6ae0dd273 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -21,7 +21,6 @@ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \ | |||
21 | obj-$(CONFIG_PCI_MSI) += pci_msi.o | 21 | obj-$(CONFIG_PCI_MSI) += pci_msi.o |
22 | obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o | 22 | obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o |
23 | obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o | 23 | obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o |
24 | obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o | ||
25 | obj-$(CONFIG_MODULES) += module.o | 24 | obj-$(CONFIG_MODULES) += module.o |
26 | obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o | 25 | obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o |
27 | obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o | 26 | obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o |
@@ -30,11 +29,3 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o | |||
30 | obj-$(CONFIG_AUDIT) += audit.o | 29 | obj-$(CONFIG_AUDIT) += audit.o |
31 | obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o | 30 | obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o |
32 | obj-y += $(obj-yy) | 31 | obj-y += $(obj-yy) |
33 | |||
34 | ifdef CONFIG_SUNOS_EMUL | ||
35 | obj-y += sys_sunos32.o sunos_ioctl32.o | ||
36 | else | ||
37 | ifdef CONFIG_SOLARIS_EMUL | ||
38 | obj-y += sys_sunos32.o sunos_ioctl32.o | ||
39 | endif | ||
40 | endif | ||
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c deleted file mode 100644 index 9877f2d7672d..000000000000 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ /dev/null | |||
@@ -1,419 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/binfmt_aout.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992, 1996 Linus Torvalds | ||
5 | * | ||
6 | * Hacked a bit by DaveM to make it work with 32-bit SunOS | ||
7 | * binaries on the sparc64 port. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | |||
12 | #include <linux/sched.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <linux/mman.h> | ||
16 | #include <linux/a.out.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/signal.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/stat.h> | ||
23 | #include <linux/fcntl.h> | ||
24 | #include <linux/ptrace.h> | ||
25 | #include <linux/user.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/binfmts.h> | ||
28 | #include <linux/personality.h> | ||
29 | #include <linux/init.h> | ||
30 | |||
31 | #include <asm/system.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <asm/pgalloc.h> | ||
34 | #include <asm/mmu_context.h> | ||
35 | #include <asm/a.out-core.h> | ||
36 | |||
37 | static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs); | ||
38 | static int load_aout32_library(struct file*); | ||
39 | static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | ||
40 | |||
41 | static struct linux_binfmt aout32_format = { | ||
42 | .module = THIS_MODULE, | ||
43 | .load_binary = load_aout32_binary, | ||
44 | .load_shlib = load_aout32_library, | ||
45 | .core_dump = aout32_core_dump, | ||
46 | .min_coredump = PAGE_SIZE, | ||
47 | }; | ||
48 | |||
49 | static void set_brk(unsigned long start, unsigned long end) | ||
50 | { | ||
51 | start = PAGE_ALIGN(start); | ||
52 | end = PAGE_ALIGN(end); | ||
53 | if (end <= start) | ||
54 | return; | ||
55 | down_write(¤t->mm->mmap_sem); | ||
56 | do_brk(start, end - start); | ||
57 | up_write(¤t->mm->mmap_sem); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * These are the only things you should do on a core-file: use only these | ||
62 | * macros to write out all the necessary info. | ||
63 | */ | ||
64 | |||
65 | static int dump_write(struct file *file, const void *addr, int nr) | ||
66 | { | ||
67 | return file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
68 | } | ||
69 | |||
70 | #define DUMP_WRITE(addr, nr) \ | ||
71 | if (!dump_write(file, (void *)(addr), (nr))) \ | ||
72 | goto end_coredump; | ||
73 | |||
74 | #define DUMP_SEEK(offset) \ | ||
75 | if (file->f_op->llseek) { \ | ||
76 | if (file->f_op->llseek(file,(offset),0) != (offset)) \ | ||
77 | goto end_coredump; \ | ||
78 | } else file->f_pos = (offset) | ||
79 | |||
80 | /* | ||
81 | * Routine writes a core dump image in the current directory. | ||
82 | * Currently only a stub-function. | ||
83 | * | ||
84 | * Note that setuid/setgid files won't make a core-dump if the uid/gid | ||
85 | * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable" | ||
86 | * field, which also makes sure the core-dumps won't be recursive if the | ||
87 | * dumping of the process results in another error.. | ||
88 | */ | ||
89 | |||
90 | static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | ||
91 | { | ||
92 | mm_segment_t fs; | ||
93 | int has_dumped = 0; | ||
94 | unsigned long dump_start, dump_size; | ||
95 | struct user dump; | ||
96 | # define START_DATA(u) (u.u_tsize) | ||
97 | # define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1)) | ||
98 | |||
99 | fs = get_fs(); | ||
100 | set_fs(KERNEL_DS); | ||
101 | has_dumped = 1; | ||
102 | current->flags |= PF_DUMPCORE; | ||
103 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | ||
104 | dump.signal = signr; | ||
105 | aout_dump_thread(regs, &dump); | ||
106 | |||
107 | /* If the size of the dump file exceeds the rlimit, then see what would happen | ||
108 | if we wrote the stack, but not the data area. */ | ||
109 | if (dump.u_dsize + dump.u_ssize > limit) | ||
110 | dump.u_dsize = 0; | ||
111 | |||
112 | /* Make sure we have enough room to write the stack and data areas. */ | ||
113 | if (dump.u_ssize > limit) | ||
114 | dump.u_ssize = 0; | ||
115 | |||
116 | /* make sure we actually have a data and stack area to dump */ | ||
117 | set_fs(USER_DS); | ||
118 | if (!access_ok(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize)) | ||
119 | dump.u_dsize = 0; | ||
120 | if (!access_ok(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize)) | ||
121 | dump.u_ssize = 0; | ||
122 | |||
123 | set_fs(KERNEL_DS); | ||
124 | /* struct user */ | ||
125 | DUMP_WRITE(&dump,sizeof(dump)); | ||
126 | /* now we start writing out the user space info */ | ||
127 | set_fs(USER_DS); | ||
128 | /* Dump the data area */ | ||
129 | if (dump.u_dsize != 0) { | ||
130 | dump_start = START_DATA(dump); | ||
131 | dump_size = dump.u_dsize; | ||
132 | DUMP_WRITE(dump_start,dump_size); | ||
133 | } | ||
134 | /* Now prepare to dump the stack area */ | ||
135 | if (dump.u_ssize != 0) { | ||
136 | dump_start = START_STACK(dump); | ||
137 | dump_size = dump.u_ssize; | ||
138 | DUMP_WRITE(dump_start,dump_size); | ||
139 | } | ||
140 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ | ||
141 | set_fs(KERNEL_DS); | ||
142 | DUMP_WRITE(current,sizeof(*current)); | ||
143 | end_coredump: | ||
144 | set_fs(fs); | ||
145 | return has_dumped; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * create_aout32_tables() parses the env- and arg-strings in new user | ||
150 | * memory and creates the pointer tables from them, and puts their | ||
151 | * addresses on the "stack", returning the new stack pointer value. | ||
152 | */ | ||
153 | |||
154 | static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bprm) | ||
155 | { | ||
156 | u32 __user *argv; | ||
157 | u32 __user *envp; | ||
158 | u32 __user *sp; | ||
159 | int argc = bprm->argc; | ||
160 | int envc = bprm->envc; | ||
161 | |||
162 | sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p); | ||
163 | |||
164 | /* This imposes the proper stack alignment for a new process. */ | ||
165 | sp = (u32 __user *) (((unsigned long) sp) & ~7); | ||
166 | if ((envc+argc+3)&1) | ||
167 | --sp; | ||
168 | |||
169 | sp -= envc+1; | ||
170 | envp = sp; | ||
171 | sp -= argc+1; | ||
172 | argv = sp; | ||
173 | put_user(argc,--sp); | ||
174 | current->mm->arg_start = (unsigned long) p; | ||
175 | while (argc-->0) { | ||
176 | char c; | ||
177 | put_user(((u32)(unsigned long)(p)),argv++); | ||
178 | do { | ||
179 | get_user(c,p++); | ||
180 | } while (c); | ||
181 | } | ||
182 | put_user(0,argv); | ||
183 | current->mm->arg_end = current->mm->env_start = (unsigned long) p; | ||
184 | while (envc-->0) { | ||
185 | char c; | ||
186 | put_user(((u32)(unsigned long)(p)),envp++); | ||
187 | do { | ||
188 | get_user(c,p++); | ||
189 | } while (c); | ||
190 | } | ||
191 | put_user(0,envp); | ||
192 | current->mm->env_end = (unsigned long) p; | ||
193 | return sp; | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * These are the functions used to load a.out style executables and shared | ||
198 | * libraries. There is no binary dependent code anywhere else. | ||
199 | */ | ||
200 | |||
201 | static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) | ||
202 | { | ||
203 | struct exec ex; | ||
204 | unsigned long error; | ||
205 | unsigned long fd_offset; | ||
206 | unsigned long rlim; | ||
207 | unsigned long orig_thr_flags; | ||
208 | int retval; | ||
209 | |||
210 | ex = *((struct exec *) bprm->buf); /* exec-header */ | ||
211 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && | ||
212 | N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || | ||
213 | N_TRSIZE(ex) || N_DRSIZE(ex) || | ||
214 | bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { | ||
215 | return -ENOEXEC; | ||
216 | } | ||
217 | |||
218 | fd_offset = N_TXTOFF(ex); | ||
219 | |||
220 | /* Check initial limits. This avoids letting people circumvent | ||
221 | * size limits imposed on them by creating programs with large | ||
222 | * arrays in the data or bss. | ||
223 | */ | ||
224 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
225 | if (rlim >= RLIM_INFINITY) | ||
226 | rlim = ~0; | ||
227 | if (ex.a_data + ex.a_bss > rlim) | ||
228 | return -ENOMEM; | ||
229 | |||
230 | /* Flush all traces of the currently running executable */ | ||
231 | retval = flush_old_exec(bprm); | ||
232 | if (retval) | ||
233 | return retval; | ||
234 | |||
235 | /* OK, This is the point of no return */ | ||
236 | set_personality(PER_SUNOS); | ||
237 | |||
238 | current->mm->end_code = ex.a_text + | ||
239 | (current->mm->start_code = N_TXTADDR(ex)); | ||
240 | current->mm->end_data = ex.a_data + | ||
241 | (current->mm->start_data = N_DATADDR(ex)); | ||
242 | current->mm->brk = ex.a_bss + | ||
243 | (current->mm->start_brk = N_BSSADDR(ex)); | ||
244 | current->mm->free_area_cache = current->mm->mmap_base; | ||
245 | current->mm->cached_hole_size = 0; | ||
246 | |||
247 | current->mm->mmap = NULL; | ||
248 | compute_creds(bprm); | ||
249 | current->flags &= ~PF_FORKNOEXEC; | ||
250 | if (N_MAGIC(ex) == NMAGIC) { | ||
251 | loff_t pos = fd_offset; | ||
252 | /* Fuck me plenty... */ | ||
253 | down_write(¤t->mm->mmap_sem); | ||
254 | error = do_brk(N_TXTADDR(ex), ex.a_text); | ||
255 | up_write(¤t->mm->mmap_sem); | ||
256 | bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), | ||
257 | ex.a_text, &pos); | ||
258 | down_write(¤t->mm->mmap_sem); | ||
259 | error = do_brk(N_DATADDR(ex), ex.a_data); | ||
260 | up_write(¤t->mm->mmap_sem); | ||
261 | bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex), | ||
262 | ex.a_data, &pos); | ||
263 | goto beyond_if; | ||
264 | } | ||
265 | |||
266 | if (N_MAGIC(ex) == OMAGIC) { | ||
267 | loff_t pos = fd_offset; | ||
268 | down_write(¤t->mm->mmap_sem); | ||
269 | do_brk(N_TXTADDR(ex) & PAGE_MASK, | ||
270 | ex.a_text+ex.a_data + PAGE_SIZE - 1); | ||
271 | up_write(¤t->mm->mmap_sem); | ||
272 | bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), | ||
273 | ex.a_text+ex.a_data, &pos); | ||
274 | } else { | ||
275 | static unsigned long error_time; | ||
276 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && | ||
277 | (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ) | ||
278 | { | ||
279 | printk(KERN_NOTICE "executable not page aligned\n"); | ||
280 | error_time = jiffies; | ||
281 | } | ||
282 | |||
283 | if (!bprm->file->f_op->mmap) { | ||
284 | loff_t pos = fd_offset; | ||
285 | down_write(¤t->mm->mmap_sem); | ||
286 | do_brk(0, ex.a_text+ex.a_data); | ||
287 | up_write(¤t->mm->mmap_sem); | ||
288 | bprm->file->f_op->read(bprm->file, | ||
289 | (char __user *)N_TXTADDR(ex), | ||
290 | ex.a_text+ex.a_data, &pos); | ||
291 | goto beyond_if; | ||
292 | } | ||
293 | |||
294 | down_write(¤t->mm->mmap_sem); | ||
295 | error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, | ||
296 | PROT_READ | PROT_EXEC, | ||
297 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | ||
298 | fd_offset); | ||
299 | up_write(¤t->mm->mmap_sem); | ||
300 | |||
301 | if (error != N_TXTADDR(ex)) { | ||
302 | send_sig(SIGKILL, current, 0); | ||
303 | return error; | ||
304 | } | ||
305 | |||
306 | down_write(¤t->mm->mmap_sem); | ||
307 | error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | ||
308 | PROT_READ | PROT_WRITE | PROT_EXEC, | ||
309 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | ||
310 | fd_offset + ex.a_text); | ||
311 | up_write(¤t->mm->mmap_sem); | ||
312 | if (error != N_DATADDR(ex)) { | ||
313 | send_sig(SIGKILL, current, 0); | ||
314 | return error; | ||
315 | } | ||
316 | } | ||
317 | beyond_if: | ||
318 | set_binfmt(&aout32_format); | ||
319 | |||
320 | set_brk(current->mm->start_brk, current->mm->brk); | ||
321 | |||
322 | /* Make sure STACK_TOP returns the right thing. */ | ||
323 | orig_thr_flags = current_thread_info()->flags; | ||
324 | current_thread_info()->flags |= _TIF_32BIT; | ||
325 | |||
326 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | ||
327 | if (retval < 0) { | ||
328 | current_thread_info()->flags = orig_thr_flags; | ||
329 | |||
330 | /* Someone check-me: is this error path enough? */ | ||
331 | send_sig(SIGKILL, current, 0); | ||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | current->mm->start_stack = | ||
336 | (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm); | ||
337 | tsb_context_switch(current->mm); | ||
338 | |||
339 | start_thread32(regs, ex.a_entry, current->mm->start_stack); | ||
340 | if (current->ptrace & PT_PTRACED) | ||
341 | send_sig(SIGTRAP, current, 0); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | /* N.B. Move to .h file and use code in fs/binfmt_aout.c? */ | ||
346 | static int load_aout32_library(struct file *file) | ||
347 | { | ||
348 | struct inode * inode; | ||
349 | unsigned long bss, start_addr, len; | ||
350 | unsigned long error; | ||
351 | int retval; | ||
352 | struct exec ex; | ||
353 | |||
354 | inode = file->f_path.dentry->d_inode; | ||
355 | |||
356 | retval = -ENOEXEC; | ||
357 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); | ||
358 | if (error != sizeof(ex)) | ||
359 | goto out; | ||
360 | |||
361 | /* We come in here for the regular a.out style of shared libraries */ | ||
362 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || | ||
363 | N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || | ||
364 | inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { | ||
365 | goto out; | ||
366 | } | ||
367 | |||
368 | if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && | ||
369 | (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) { | ||
370 | printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n"); | ||
371 | goto out; | ||
372 | } | ||
373 | |||
374 | if (N_FLAGS(ex)) | ||
375 | goto out; | ||
376 | |||
377 | /* For QMAGIC, the starting address is 0x20 into the page. We mask | ||
378 | this off to get the starting address for the page */ | ||
379 | |||
380 | start_addr = ex.a_entry & 0xfffff000; | ||
381 | |||
382 | /* Now use mmap to map the library into memory. */ | ||
383 | down_write(¤t->mm->mmap_sem); | ||
384 | error = do_mmap(file, start_addr, ex.a_text + ex.a_data, | ||
385 | PROT_READ | PROT_WRITE | PROT_EXEC, | ||
386 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, | ||
387 | N_TXTOFF(ex)); | ||
388 | up_write(¤t->mm->mmap_sem); | ||
389 | retval = error; | ||
390 | if (error != start_addr) | ||
391 | goto out; | ||
392 | |||
393 | len = PAGE_ALIGN(ex.a_text + ex.a_data); | ||
394 | bss = ex.a_text + ex.a_data + ex.a_bss; | ||
395 | if (bss > len) { | ||
396 | down_write(¤t->mm->mmap_sem); | ||
397 | error = do_brk(start_addr + len, bss - len); | ||
398 | up_write(¤t->mm->mmap_sem); | ||
399 | retval = error; | ||
400 | if (error != start_addr + len) | ||
401 | goto out; | ||
402 | } | ||
403 | retval = 0; | ||
404 | out: | ||
405 | return retval; | ||
406 | } | ||
407 | |||
408 | static int __init init_aout32_binfmt(void) | ||
409 | { | ||
410 | return register_binfmt(&aout32_format); | ||
411 | } | ||
412 | |||
413 | static void __exit exit_aout32_binfmt(void) | ||
414 | { | ||
415 | unregister_binfmt(&aout32_format); | ||
416 | } | ||
417 | |||
418 | module_init(init_aout32_binfmt); | ||
419 | module_exit(exit_aout32_binfmt); | ||
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 49eca4b1cf25..fb43c76bdc26 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -1353,63 +1353,6 @@ breakpoint_trap: | |||
1353 | ba,pt %xcc, rtrap | 1353 | ba,pt %xcc, rtrap |
1354 | nop | 1354 | nop |
1355 | 1355 | ||
1356 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | ||
1357 | defined(CONFIG_SOLARIS_EMUL_MODULE) | ||
1358 | /* SunOS uses syscall zero as the 'indirect syscall' it looks | ||
1359 | * like indir_syscall(scall_num, arg0, arg1, arg2...); etc. | ||
1360 | * This is complete brain damage. | ||
1361 | */ | ||
1362 | .globl sunos_indir | ||
1363 | sunos_indir: | ||
1364 | srl %o0, 0, %o0 | ||
1365 | mov %o7, %l4 | ||
1366 | cmp %o0, NR_SYSCALLS | ||
1367 | blu,a,pt %icc, 1f | ||
1368 | sll %o0, 0x2, %o0 | ||
1369 | sethi %hi(sunos_nosys), %l6 | ||
1370 | b,pt %xcc, 2f | ||
1371 | or %l6, %lo(sunos_nosys), %l6 | ||
1372 | 1: sethi %hi(sunos_sys_table), %l7 | ||
1373 | or %l7, %lo(sunos_sys_table), %l7 | ||
1374 | lduw [%l7 + %o0], %l6 | ||
1375 | 2: mov %o1, %o0 | ||
1376 | mov %o2, %o1 | ||
1377 | mov %o3, %o2 | ||
1378 | mov %o4, %o3 | ||
1379 | mov %o5, %o4 | ||
1380 | call %l6 | ||
1381 | mov %l4, %o7 | ||
1382 | |||
1383 | .globl sunos_getpid | ||
1384 | sunos_getpid: | ||
1385 | call sys_getppid | ||
1386 | nop | ||
1387 | call sys_getpid | ||
1388 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] | ||
1389 | b,pt %xcc, ret_sys_call | ||
1390 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
1391 | |||
1392 | /* SunOS getuid() returns uid in %o0 and euid in %o1 */ | ||
1393 | .globl sunos_getuid | ||
1394 | sunos_getuid: | ||
1395 | call sys32_geteuid16 | ||
1396 | nop | ||
1397 | call sys32_getuid16 | ||
1398 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] | ||
1399 | b,pt %xcc, ret_sys_call | ||
1400 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
1401 | |||
1402 | /* SunOS getgid() returns gid in %o0 and egid in %o1 */ | ||
1403 | .globl sunos_getgid | ||
1404 | sunos_getgid: | ||
1405 | call sys32_getegid16 | ||
1406 | nop | ||
1407 | call sys32_getgid16 | ||
1408 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] | ||
1409 | b,pt %xcc, ret_sys_call | ||
1410 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
1411 | #endif | ||
1412 | |||
1413 | /* SunOS's execv() call only specifies the argv argument, the | 1356 | /* SunOS's execv() call only specifies the argv argument, the |
1414 | * environment settings are the same as the calling processes. | 1357 | * environment settings are the same as the calling processes. |
1415 | */ | 1358 | */ |
@@ -1591,7 +1534,7 @@ linux_syscall_trace: | |||
1591 | mov %i4, %o4 | 1534 | mov %i4, %o4 |
1592 | 1535 | ||
1593 | 1536 | ||
1594 | /* Linux 32-bit and SunOS system calls enter here... */ | 1537 | /* Linux 32-bit system calls enter here... */ |
1595 | .align 32 | 1538 | .align 32 |
1596 | .globl linux_sparc_syscall32 | 1539 | .globl linux_sparc_syscall32 |
1597 | linux_sparc_syscall32: | 1540 | linux_sparc_syscall32: |
@@ -1614,7 +1557,7 @@ linux_sparc_syscall32: | |||
1614 | srl %i3, 0, %o3 ! IEU0 | 1557 | srl %i3, 0, %o3 ! IEU0 |
1615 | ba,a,pt %xcc, 3f | 1558 | ba,a,pt %xcc, 3f |
1616 | 1559 | ||
1617 | /* Linux native and SunOS system calls enter here... */ | 1560 | /* Linux native system calls enter here... */ |
1618 | .align 32 | 1561 | .align 32 |
1619 | .globl linux_sparc_syscall, ret_sys_call | 1562 | .globl linux_sparc_syscall, ret_sys_call |
1620 | linux_sparc_syscall: | 1563 | linux_sparc_syscall: |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 9d51956e8e2f..1c47009eb5ec 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
28 | #include <asm/svr4.h> | ||
29 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
30 | #include <asm/fpumacro.h> | 29 | #include <asm/fpumacro.h> |
31 | #include <asm/uctx.h> | 30 | #include <asm/uctx.h> |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 8c1c121330fb..74e0512f135c 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
26 | #include <asm/svr4.h> | ||
27 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
28 | #include <asm/psrcompat.h> | 27 | #include <asm/psrcompat.h> |
29 | #include <asm/fpumacro.h> | 28 | #include <asm/fpumacro.h> |
@@ -798,281 +797,6 @@ sigsegv: | |||
798 | force_sigsegv(signo, current); | 797 | force_sigsegv(signo, current); |
799 | } | 798 | } |
800 | 799 | ||
801 | /* Setup a Solaris stack frame */ | ||
802 | static void | ||
803 | setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, | ||
804 | struct pt_regs *regs, int signr, sigset_t *oldset) | ||
805 | { | ||
806 | svr4_signal_frame_t __user *sfp; | ||
807 | svr4_gregset_t __user *gr; | ||
808 | svr4_siginfo_t __user *si; | ||
809 | svr4_mcontext_t __user *mc; | ||
810 | svr4_gwindows_t __user *gw; | ||
811 | svr4_ucontext_t __user *uc; | ||
812 | svr4_sigset_t setv; | ||
813 | unsigned int psr; | ||
814 | int i, err; | ||
815 | |||
816 | synchronize_user_stack(); | ||
817 | save_and_clear_fpu(); | ||
818 | |||
819 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | ||
820 | sfp = (svr4_signal_frame_t __user *) | ||
821 | get_sigframe(sa, regs, | ||
822 | sizeof(struct reg_window32) + SVR4_SF_ALIGNED); | ||
823 | |||
824 | if (invalid_frame_pointer(sfp, sizeof(*sfp))) | ||
825 | do_exit(SIGILL); | ||
826 | |||
827 | /* Start with a clean frame pointer and fill it */ | ||
828 | err = clear_user(sfp, sizeof(*sfp)); | ||
829 | |||
830 | /* Setup convenience variables */ | ||
831 | si = &sfp->si; | ||
832 | uc = &sfp->uc; | ||
833 | gw = &sfp->gw; | ||
834 | mc = &uc->mcontext; | ||
835 | gr = &mc->greg; | ||
836 | |||
837 | /* FIXME: where am I supposed to put this? | ||
838 | * sc->sigc_onstack = old_status; | ||
839 | * anyways, it does not look like it is used for anything at all. | ||
840 | */ | ||
841 | setv.sigbits[0] = oldset->sig[0]; | ||
842 | setv.sigbits[1] = (oldset->sig[0] >> 32); | ||
843 | if (_NSIG_WORDS >= 2) { | ||
844 | setv.sigbits[2] = oldset->sig[1]; | ||
845 | setv.sigbits[3] = (oldset->sig[1] >> 32); | ||
846 | err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t)); | ||
847 | } else | ||
848 | err |= __copy_to_user(&uc->sigmask, &setv, | ||
849 | 2 * sizeof(unsigned int)); | ||
850 | |||
851 | /* Store registers */ | ||
852 | if (test_thread_flag(TIF_32BIT)) { | ||
853 | regs->tpc &= 0xffffffff; | ||
854 | regs->tnpc &= 0xffffffff; | ||
855 | } | ||
856 | err |= __put_user(regs->tpc, &((*gr)[SVR4_PC])); | ||
857 | err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC])); | ||
858 | psr = tstate_to_psr(regs->tstate); | ||
859 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | ||
860 | psr |= PSR_EF; | ||
861 | err |= __put_user(psr, &((*gr)[SVR4_PSR])); | ||
862 | err |= __put_user(regs->y, &((*gr)[SVR4_Y])); | ||
863 | |||
864 | /* Copy g[1..7] and o[0..7] registers */ | ||
865 | for (i = 0; i < 7; i++) | ||
866 | err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); | ||
867 | for (i = 0; i < 8; i++) | ||
868 | err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); | ||
869 | |||
870 | /* Setup sigaltstack */ | ||
871 | err |= __put_user(current->sas_ss_sp, &uc->stack.sp); | ||
872 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags); | ||
873 | err |= __put_user(current->sas_ss_size, &uc->stack.size); | ||
874 | |||
875 | /* Save the currently window file: */ | ||
876 | |||
877 | /* 1. Link sfp->uc->gwins to our windows */ | ||
878 | err |= __put_user(ptr_to_compat(gw), &mc->gwin); | ||
879 | |||
880 | /* 2. Number of windows to restore at setcontext (): */ | ||
881 | err |= __put_user(get_thread_wsaved(), &gw->count); | ||
882 | |||
883 | /* 3. We just pay attention to the gw->count field on setcontext */ | ||
884 | set_thread_wsaved(0); /* So process is allowed to execute. */ | ||
885 | |||
886 | /* Setup the signal information. Solaris expects a bunch of | ||
887 | * information to be passed to the signal handler, we don't provide | ||
888 | * that much currently, should use siginfo. | ||
889 | */ | ||
890 | err |= __put_user(signr, &si->siginfo.signo); | ||
891 | err |= __put_user(SVR4_SINOINFO, &si->siginfo.code); | ||
892 | if (err) | ||
893 | goto sigsegv; | ||
894 | |||
895 | regs->u_regs[UREG_FP] = (unsigned long) sfp; | ||
896 | regs->tpc = (unsigned long) sa->sa_handler; | ||
897 | regs->tnpc = (regs->tpc + 4); | ||
898 | if (test_thread_flag(TIF_32BIT)) { | ||
899 | regs->tpc &= 0xffffffff; | ||
900 | regs->tnpc &= 0xffffffff; | ||
901 | } | ||
902 | |||
903 | /* Arguments passed to signal handler */ | ||
904 | if (regs->u_regs[14]){ | ||
905 | struct reg_window32 __user *rw = (struct reg_window32 __user *) | ||
906 | (regs->u_regs[14] & 0x00000000ffffffffUL); | ||
907 | |||
908 | err |= __put_user(signr, &rw->ins[0]); | ||
909 | err |= __put_user((u64)si, &rw->ins[1]); | ||
910 | err |= __put_user((u64)uc, &rw->ins[2]); | ||
911 | err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */ | ||
912 | if (err) | ||
913 | goto sigsegv; | ||
914 | |||
915 | regs->u_regs[UREG_I0] = signr; | ||
916 | regs->u_regs[UREG_I1] = (u32)(u64) si; | ||
917 | regs->u_regs[UREG_I2] = (u32)(u64) uc; | ||
918 | } | ||
919 | return; | ||
920 | |||
921 | sigsegv: | ||
922 | force_sigsegv(signr, current); | ||
923 | } | ||
924 | |||
925 | asmlinkage int | ||
926 | svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs) | ||
927 | { | ||
928 | svr4_gregset_t __user *gr; | ||
929 | svr4_mcontext_t __user *mc; | ||
930 | svr4_sigset_t setv; | ||
931 | int i, err; | ||
932 | u32 psr; | ||
933 | |||
934 | synchronize_user_stack(); | ||
935 | save_and_clear_fpu(); | ||
936 | |||
937 | if (get_thread_wsaved()) | ||
938 | do_exit(SIGSEGV); | ||
939 | |||
940 | err = clear_user(uc, sizeof(*uc)); | ||
941 | |||
942 | /* Setup convenience variables */ | ||
943 | mc = &uc->mcontext; | ||
944 | gr = &mc->greg; | ||
945 | |||
946 | setv.sigbits[0] = current->blocked.sig[0]; | ||
947 | setv.sigbits[1] = (current->blocked.sig[0] >> 32); | ||
948 | if (_NSIG_WORDS >= 2) { | ||
949 | setv.sigbits[2] = current->blocked.sig[1]; | ||
950 | setv.sigbits[3] = (current->blocked.sig[1] >> 32); | ||
951 | err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t)); | ||
952 | } else | ||
953 | err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); | ||
954 | |||
955 | /* Store registers */ | ||
956 | if (test_thread_flag(TIF_32BIT)) { | ||
957 | regs->tpc &= 0xffffffff; | ||
958 | regs->tnpc &= 0xffffffff; | ||
959 | } | ||
960 | err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]); | ||
961 | err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]); | ||
962 | |||
963 | psr = tstate_to_psr(regs->tstate) & ~PSR_EF; | ||
964 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | ||
965 | psr |= PSR_EF; | ||
966 | err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]); | ||
967 | |||
968 | err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]); | ||
969 | |||
970 | /* Copy g[1..7] and o[0..7] registers */ | ||
971 | for (i = 0; i < 7; i++) | ||
972 | err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); | ||
973 | for (i = 0; i < 8; i++) | ||
974 | err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); | ||
975 | |||
976 | /* Setup sigaltstack */ | ||
977 | err |= __put_user(current->sas_ss_sp, &uc->stack.sp); | ||
978 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags); | ||
979 | err |= __put_user(current->sas_ss_size, &uc->stack.size); | ||
980 | |||
981 | /* The register file is not saved | ||
982 | * we have already stuffed all of it with sync_user_stack | ||
983 | */ | ||
984 | return (err ? -EFAULT : 0); | ||
985 | } | ||
986 | |||
987 | |||
988 | /* Set the context for a svr4 application, this is Solaris way to sigreturn */ | ||
989 | asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs) | ||
990 | { | ||
991 | svr4_gregset_t __user *gr; | ||
992 | mm_segment_t old_fs; | ||
993 | u32 pc, npc, psr, u_ss_sp; | ||
994 | sigset_t set; | ||
995 | svr4_sigset_t setv; | ||
996 | int i, err; | ||
997 | stack_t st; | ||
998 | |||
999 | /* Fixme: restore windows, or is this already taken care of in | ||
1000 | * svr4_setup_frame when sync_user_windows is done? | ||
1001 | */ | ||
1002 | flush_user_windows(); | ||
1003 | |||
1004 | if (get_thread_wsaved()) | ||
1005 | goto sigsegv; | ||
1006 | |||
1007 | if (((unsigned long) c) & 3){ | ||
1008 | printk("Unaligned structure passed\n"); | ||
1009 | goto sigsegv; | ||
1010 | } | ||
1011 | |||
1012 | if (!__access_ok(c, sizeof(*c))) { | ||
1013 | /* Miguel, add nice debugging msg _here_. ;-) */ | ||
1014 | goto sigsegv; | ||
1015 | } | ||
1016 | |||
1017 | /* Check for valid PC and nPC */ | ||
1018 | gr = &c->mcontext.greg; | ||
1019 | err = __get_user(pc, &((*gr)[SVR4_PC])); | ||
1020 | err |= __get_user(npc, &((*gr)[SVR4_NPC])); | ||
1021 | if ((pc | npc) & 3) | ||
1022 | goto sigsegv; | ||
1023 | |||
1024 | /* Retrieve information from passed ucontext */ | ||
1025 | /* note that nPC is ored a 1, this is used to inform entry.S */ | ||
1026 | /* that we don't want it to mess with our PC and nPC */ | ||
1027 | |||
1028 | err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t)); | ||
1029 | set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32); | ||
1030 | if (_NSIG_WORDS >= 2) | ||
1031 | set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32); | ||
1032 | |||
1033 | err |= __get_user(u_ss_sp, &c->stack.sp); | ||
1034 | st.ss_sp = compat_ptr(u_ss_sp); | ||
1035 | err |= __get_user(st.ss_flags, &c->stack.flags); | ||
1036 | err |= __get_user(st.ss_size, &c->stack.size); | ||
1037 | if (err) | ||
1038 | goto sigsegv; | ||
1039 | |||
1040 | /* It is more difficult to avoid calling this function than to | ||
1041 | call it and ignore errors. */ | ||
1042 | old_fs = get_fs(); | ||
1043 | set_fs(KERNEL_DS); | ||
1044 | do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]); | ||
1045 | set_fs(old_fs); | ||
1046 | |||
1047 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
1048 | spin_lock_irq(¤t->sighand->siglock); | ||
1049 | current->blocked = set; | ||
1050 | recalc_sigpending(); | ||
1051 | spin_unlock_irq(¤t->sighand->siglock); | ||
1052 | regs->tpc = pc; | ||
1053 | regs->tnpc = npc | 1; | ||
1054 | if (test_thread_flag(TIF_32BIT)) { | ||
1055 | regs->tpc &= 0xffffffff; | ||
1056 | regs->tnpc &= 0xffffffff; | ||
1057 | } | ||
1058 | err |= __get_user(regs->y, &((*gr)[SVR4_Y])); | ||
1059 | err |= __get_user(psr, &((*gr)[SVR4_PSR])); | ||
1060 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); | ||
1061 | regs->tstate |= psr_to_tstate_icc(psr); | ||
1062 | |||
1063 | /* Restore g[1..7] and o[0..7] registers */ | ||
1064 | for (i = 0; i < 7; i++) | ||
1065 | err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); | ||
1066 | for (i = 0; i < 8; i++) | ||
1067 | err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); | ||
1068 | if (err) | ||
1069 | goto sigsegv; | ||
1070 | |||
1071 | return -EINTR; | ||
1072 | sigsegv: | ||
1073 | return -EFAULT; | ||
1074 | } | ||
1075 | |||
1076 | static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 800 | static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, |
1077 | unsigned long signr, sigset_t *oldset, | 801 | unsigned long signr, sigset_t *oldset, |
1078 | siginfo_t *info) | 802 | siginfo_t *info) |
@@ -1216,20 +940,14 @@ sigsegv: | |||
1216 | 940 | ||
1217 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | 941 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, |
1218 | siginfo_t *info, | 942 | siginfo_t *info, |
1219 | sigset_t *oldset, struct pt_regs *regs, | 943 | sigset_t *oldset, struct pt_regs *regs) |
1220 | int svr4_signal) | ||
1221 | { | 944 | { |
1222 | if (svr4_signal) | 945 | if (ka->sa.sa_flags & SA_SIGINFO) |
1223 | setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, | 946 | setup_rt_frame32(ka, regs, signr, oldset, info); |
1224 | regs, signr, oldset); | 947 | else if (test_thread_flag(TIF_NEWSIGNALS)) |
1225 | else { | 948 | new_setup_frame32(ka, regs, signr, oldset); |
1226 | if (ka->sa.sa_flags & SA_SIGINFO) | 949 | else |
1227 | setup_rt_frame32(ka, regs, signr, oldset, info); | 950 | setup_frame32(&ka->sa, regs, signr, oldset, info); |
1228 | else if (test_thread_flag(TIF_NEWSIGNALS)) | ||
1229 | new_setup_frame32(ka, regs, signr, oldset); | ||
1230 | else | ||
1231 | setup_frame32(&ka->sa, regs, signr, oldset, info); | ||
1232 | } | ||
1233 | spin_lock_irq(¤t->sighand->siglock); | 951 | spin_lock_irq(¤t->sighand->siglock); |
1234 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 952 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1235 | if (!(ka->sa.sa_flags & SA_NOMASK)) | 953 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
@@ -1270,7 +988,6 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
1270 | struct signal_deliver_cookie cookie; | 988 | struct signal_deliver_cookie cookie; |
1271 | struct k_sigaction ka; | 989 | struct k_sigaction ka; |
1272 | int signr; | 990 | int signr; |
1273 | int svr4_signal = current->personality == PER_SVR4; | ||
1274 | 991 | ||
1275 | cookie.restart_syscall = restart_syscall; | 992 | cookie.restart_syscall = restart_syscall; |
1276 | cookie.orig_i0 = orig_i0; | 993 | cookie.orig_i0 = orig_i0; |
@@ -1279,8 +996,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
1279 | if (signr > 0) { | 996 | if (signr > 0) { |
1280 | if (cookie.restart_syscall) | 997 | if (cookie.restart_syscall) |
1281 | syscall_restart32(orig_i0, regs, &ka.sa); | 998 | syscall_restart32(orig_i0, regs, &ka.sa); |
1282 | handle_signal32(signr, &ka, &info, oldset, | 999 | handle_signal32(signr, &ka, &info, oldset, regs); |
1283 | regs, svr4_signal); | ||
1284 | 1000 | ||
1285 | /* a signal was successfully delivered; the saved | 1001 | /* a signal was successfully delivered; the saved |
1286 | * sigmask will have been stored in the signal frame, | 1002 | * sigmask will have been stored in the signal frame, |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 051b8d9cb989..38736460b8db 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -33,13 +33,11 @@ | |||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
35 | #include <asm/idprom.h> | 35 | #include <asm/idprom.h> |
36 | #include <asm/svr4.h> | ||
37 | #include <asm/elf.h> | 36 | #include <asm/elf.h> |
38 | #include <asm/head.h> | 37 | #include <asm/head.h> |
39 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
40 | #include <asm/mostek.h> | 39 | #include <asm/mostek.h> |
41 | #include <asm/ptrace.h> | 40 | #include <asm/ptrace.h> |
42 | #include <asm/user.h> | ||
43 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
44 | #include <asm/checksum.h> | 42 | #include <asm/checksum.h> |
45 | #include <asm/fpumacro.h> | 43 | #include <asm/fpumacro.h> |
@@ -73,13 +71,8 @@ extern __kernel_size_t strlen(const char *); | |||
73 | extern void linux_sparc_syscall(void); | 71 | extern void linux_sparc_syscall(void); |
74 | extern void rtrap(void); | 72 | extern void rtrap(void); |
75 | extern void show_regs(struct pt_regs *); | 73 | extern void show_regs(struct pt_regs *); |
76 | extern void solaris_syscall(void); | ||
77 | extern void syscall_trace(struct pt_regs *, int); | 74 | extern void syscall_trace(struct pt_regs *, int); |
78 | extern u32 sunos_sys_table[], sys_call_table32[]; | ||
79 | extern void tl0_solaris(void); | ||
80 | extern void sys_sigsuspend(void); | 75 | extern void sys_sigsuspend(void); |
81 | extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs); | ||
82 | extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs); | ||
83 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); | 76 | extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); |
84 | extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); | 77 | extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); |
85 | extern long sparc32_open(const char __user * filename, int flags, int mode); | 78 | extern long sparc32_open(const char __user * filename, int flags, int mode); |
@@ -90,8 +83,6 @@ extern int __ashrdi3(int, int); | |||
90 | 83 | ||
91 | extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); | 84 | extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); |
92 | 85 | ||
93 | extern unsigned int sys_call_table[]; | ||
94 | |||
95 | extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); | 86 | extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); |
96 | extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, | 87 | extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, |
97 | unsigned long *); | 88 | unsigned long *); |
@@ -213,11 +204,6 @@ EXPORT_SYMBOL(pci_dma_supported); | |||
213 | /* I/O device mmaping on Sparc64. */ | 204 | /* I/O device mmaping on Sparc64. */ |
214 | EXPORT_SYMBOL(io_remap_pfn_range); | 205 | EXPORT_SYMBOL(io_remap_pfn_range); |
215 | 206 | ||
216 | #if defined(CONFIG_COMPAT) && defined(CONFIG_NET) | ||
217 | /* Solaris/SunOS binary compatibility */ | ||
218 | EXPORT_SYMBOL(verify_compat_iovec); | ||
219 | #endif | ||
220 | |||
221 | EXPORT_SYMBOL(dump_fpu); | 207 | EXPORT_SYMBOL(dump_fpu); |
222 | EXPORT_SYMBOL(put_fs_struct); | 208 | EXPORT_SYMBOL(put_fs_struct); |
223 | 209 | ||
@@ -254,30 +240,6 @@ EXPORT_SYMBOL(strlen); | |||
254 | EXPORT_SYMBOL(__strlen_user); | 240 | EXPORT_SYMBOL(__strlen_user); |
255 | EXPORT_SYMBOL(__strnlen_user); | 241 | EXPORT_SYMBOL(__strnlen_user); |
256 | 242 | ||
257 | #ifdef CONFIG_SOLARIS_EMUL_MODULE | ||
258 | EXPORT_SYMBOL(linux_sparc_syscall); | ||
259 | EXPORT_SYMBOL(rtrap); | ||
260 | EXPORT_SYMBOL(show_regs); | ||
261 | EXPORT_SYMBOL(solaris_syscall); | ||
262 | EXPORT_SYMBOL(syscall_trace); | ||
263 | EXPORT_SYMBOL(sunos_sys_table); | ||
264 | EXPORT_SYMBOL(sys_call_table32); | ||
265 | EXPORT_SYMBOL(tl0_solaris); | ||
266 | EXPORT_SYMBOL(sys_sigsuspend); | ||
267 | EXPORT_SYMBOL(sys_getppid); | ||
268 | EXPORT_SYMBOL(sys_getpid); | ||
269 | EXPORT_SYMBOL(sys_geteuid); | ||
270 | EXPORT_SYMBOL(sys_getuid); | ||
271 | EXPORT_SYMBOL(sys_getegid); | ||
272 | EXPORT_SYMBOL(sysctl_nr_open); | ||
273 | EXPORT_SYMBOL(sys_getgid); | ||
274 | EXPORT_SYMBOL(svr4_getcontext); | ||
275 | EXPORT_SYMBOL(svr4_setcontext); | ||
276 | EXPORT_SYMBOL(compat_sys_ioctl); | ||
277 | EXPORT_SYMBOL(sys_ioctl); | ||
278 | EXPORT_SYMBOL(sparc32_open); | ||
279 | #endif | ||
280 | |||
281 | /* Special internal versions of library functions. */ | 243 | /* Special internal versions of library functions. */ |
282 | EXPORT_SYMBOL(_clear_page); | 244 | EXPORT_SYMBOL(_clear_page); |
283 | EXPORT_SYMBOL(clear_user_page); | 245 | EXPORT_SYMBOL(clear_user_page); |
@@ -334,9 +296,6 @@ EXPORT_SYMBOL(do_BUG); | |||
334 | /* for ns8703 */ | 296 | /* for ns8703 */ |
335 | EXPORT_SYMBOL(ns87303_lock); | 297 | EXPORT_SYMBOL(ns87303_lock); |
336 | 298 | ||
337 | /* for solaris compat module */ | ||
338 | EXPORT_SYMBOL_GPL(sys_call_table); | ||
339 | |||
340 | EXPORT_SYMBOL(tick_ops); | 299 | EXPORT_SYMBOL(tick_ops); |
341 | 300 | ||
342 | EXPORT_SYMBOL(xor_vis_2); | 301 | EXPORT_SYMBOL(xor_vis_2); |
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c deleted file mode 100644 index 75d2bad49839..000000000000 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ /dev/null | |||
@@ -1,275 +0,0 @@ | |||
1 | /* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $ | ||
2 | * sunos_ioctl32.c: SunOS ioctl compatibility on sparc64. | ||
3 | * | ||
4 | * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) | ||
5 | * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) | ||
6 | */ | ||
7 | |||
8 | #include <asm/uaccess.h> | ||
9 | |||
10 | #include <linux/sched.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/termios.h> | ||
14 | #include <linux/tty.h> | ||
15 | #include <linux/ioctl.h> | ||
16 | #include <linux/route.h> | ||
17 | #include <linux/sockios.h> | ||
18 | #include <linux/if.h> | ||
19 | #include <linux/netdevice.h> | ||
20 | #include <linux/if_arp.h> | ||
21 | #include <linux/fs.h> | ||
22 | #include <linux/file.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/smp.h> | ||
25 | #include <linux/syscalls.h> | ||
26 | #include <linux/compat.h> | ||
27 | |||
28 | #define SUNOS_NR_OPEN 256 | ||
29 | |||
30 | struct rtentry32 { | ||
31 | u32 rt_pad1; | ||
32 | struct sockaddr rt_dst; /* target address */ | ||
33 | struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ | ||
34 | struct sockaddr rt_genmask; /* target network mask (IP) */ | ||
35 | unsigned short rt_flags; | ||
36 | short rt_pad2; | ||
37 | u32 rt_pad3; | ||
38 | unsigned char rt_tos; | ||
39 | unsigned char rt_class; | ||
40 | short rt_pad4; | ||
41 | short rt_metric; /* +1 for binary compatibility! */ | ||
42 | /* char * */ u32 rt_dev; /* forcing the device at add */ | ||
43 | u32 rt_mtu; /* per route MTU/Window */ | ||
44 | u32 rt_window; /* Window clamping */ | ||
45 | unsigned short rt_irtt; /* Initial RTT */ | ||
46 | |||
47 | }; | ||
48 | |||
49 | struct ifmap32 { | ||
50 | u32 mem_start; | ||
51 | u32 mem_end; | ||
52 | unsigned short base_addr; | ||
53 | unsigned char irq; | ||
54 | unsigned char dma; | ||
55 | unsigned char port; | ||
56 | }; | ||
57 | |||
58 | struct ifreq32 { | ||
59 | #define IFHWADDRLEN 6 | ||
60 | #define IFNAMSIZ 16 | ||
61 | union { | ||
62 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ | ||
63 | } ifr_ifrn; | ||
64 | union { | ||
65 | struct sockaddr ifru_addr; | ||
66 | struct sockaddr ifru_dstaddr; | ||
67 | struct sockaddr ifru_broadaddr; | ||
68 | struct sockaddr ifru_netmask; | ||
69 | struct sockaddr ifru_hwaddr; | ||
70 | short ifru_flags; | ||
71 | int ifru_ivalue; | ||
72 | int ifru_mtu; | ||
73 | struct ifmap32 ifru_map; | ||
74 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ | ||
75 | compat_caddr_t ifru_data; | ||
76 | } ifr_ifru; | ||
77 | }; | ||
78 | |||
79 | struct ifconf32 { | ||
80 | int ifc_len; /* size of buffer */ | ||
81 | compat_caddr_t ifcbuf; | ||
82 | }; | ||
83 | |||
84 | extern asmlinkage int compat_sys_ioctl(unsigned int, unsigned int, u32); | ||
85 | |||
86 | asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) | ||
87 | { | ||
88 | int ret = -EBADF; | ||
89 | |||
90 | if(fd >= SUNOS_NR_OPEN) | ||
91 | goto out; | ||
92 | if(!fcheck(fd)) | ||
93 | goto out; | ||
94 | |||
95 | if(cmd == TIOCSETD) { | ||
96 | mm_segment_t old_fs = get_fs(); | ||
97 | int __user *p; | ||
98 | int ntty = N_TTY; | ||
99 | int tmp; | ||
100 | |||
101 | p = (int __user *) (unsigned long) arg; | ||
102 | ret = -EFAULT; | ||
103 | if(get_user(tmp, p)) | ||
104 | goto out; | ||
105 | if(tmp == 2) { | ||
106 | set_fs(KERNEL_DS); | ||
107 | ret = sys_ioctl(fd, cmd, (unsigned long) &ntty); | ||
108 | set_fs(old_fs); | ||
109 | ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); | ||
110 | goto out; | ||
111 | } | ||
112 | } | ||
113 | if(cmd == TIOCNOTTY) { | ||
114 | ret = sys_setsid(); | ||
115 | goto out; | ||
116 | } | ||
117 | switch(cmd) { | ||
118 | case _IOW('r', 10, struct rtentry32): | ||
119 | ret = compat_sys_ioctl(fd, SIOCADDRT, arg); | ||
120 | goto out; | ||
121 | case _IOW('r', 11, struct rtentry32): | ||
122 | ret = compat_sys_ioctl(fd, SIOCDELRT, arg); | ||
123 | goto out; | ||
124 | |||
125 | case _IOW('i', 12, struct ifreq32): | ||
126 | ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg); | ||
127 | goto out; | ||
128 | case _IOWR('i', 13, struct ifreq32): | ||
129 | ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg); | ||
130 | goto out; | ||
131 | case _IOW('i', 14, struct ifreq32): | ||
132 | ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg); | ||
133 | goto out; | ||
134 | case _IOWR('i', 15, struct ifreq32): | ||
135 | ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg); | ||
136 | goto out; | ||
137 | case _IOW('i', 16, struct ifreq32): | ||
138 | ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg); | ||
139 | goto out; | ||
140 | case _IOWR('i', 17, struct ifreq32): | ||
141 | ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg); | ||
142 | goto out; | ||
143 | case _IOW('i', 18, struct ifreq32): | ||
144 | ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg); | ||
145 | goto out; | ||
146 | case _IOWR('i', 19, struct ifreq32): | ||
147 | ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg); | ||
148 | goto out; | ||
149 | |||
150 | case _IOWR('i', 20, struct ifconf32): | ||
151 | ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg); | ||
152 | goto out; | ||
153 | |||
154 | case _IOW('i', 21, struct ifreq32): | ||
155 | ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg); | ||
156 | goto out; | ||
157 | |||
158 | case _IOWR('i', 22, struct ifreq32): | ||
159 | ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg); | ||
160 | goto out; | ||
161 | |||
162 | case _IOWR('i', 23, struct ifreq32): | ||
163 | ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg); | ||
164 | goto out; | ||
165 | case _IOW('i', 24, struct ifreq32): | ||
166 | ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg); | ||
167 | goto out; | ||
168 | case _IOWR('i', 25, struct ifreq32): | ||
169 | ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg); | ||
170 | goto out; | ||
171 | case _IOW('i', 26, struct ifreq32): | ||
172 | ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg); | ||
173 | goto out; | ||
174 | case _IOWR('i', 27, struct ifreq32): | ||
175 | ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg); | ||
176 | goto out; | ||
177 | case _IOW('i', 28, struct ifreq32): | ||
178 | ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg); | ||
179 | goto out; | ||
180 | |||
181 | case _IOW('i', 30, struct arpreq): | ||
182 | ret = compat_sys_ioctl(fd, SIOCSARP, arg); | ||
183 | goto out; | ||
184 | case _IOWR('i', 31, struct arpreq): | ||
185 | ret = compat_sys_ioctl(fd, SIOCGARP, arg); | ||
186 | goto out; | ||
187 | case _IOW('i', 32, struct arpreq): | ||
188 | ret = compat_sys_ioctl(fd, SIOCDARP, arg); | ||
189 | goto out; | ||
190 | |||
191 | case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */ | ||
192 | case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */ | ||
193 | case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */ | ||
194 | case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */ | ||
195 | case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */ | ||
196 | case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */ | ||
197 | case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */ | ||
198 | ret = -EOPNOTSUPP; | ||
199 | goto out; | ||
200 | |||
201 | case _IOW('i', 49, struct ifreq32): | ||
202 | ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg); | ||
203 | goto out; | ||
204 | case _IOW('i', 50, struct ifreq32): | ||
205 | ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg); | ||
206 | goto out; | ||
207 | |||
208 | /* FDDI interface ioctls, unsupported. */ | ||
209 | |||
210 | case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */ | ||
211 | case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */ | ||
212 | case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */ | ||
213 | case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */ | ||
214 | case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */ | ||
215 | case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */ | ||
216 | case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */ | ||
217 | case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */ | ||
218 | case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */ | ||
219 | printk("FDDI ioctl, returning EOPNOTSUPP\n"); | ||
220 | ret = -EOPNOTSUPP; | ||
221 | goto out; | ||
222 | |||
223 | case _IOW('t', 125, int): | ||
224 | /* More stupid tty sunos ioctls, just | ||
225 | * say it worked. | ||
226 | */ | ||
227 | ret = 0; | ||
228 | goto out; | ||
229 | |||
230 | /* Non posix grp */ | ||
231 | case _IOW('t', 118, int): { | ||
232 | int oldval, newval, __user *ptr; | ||
233 | |||
234 | cmd = TIOCSPGRP; | ||
235 | ptr = (int __user *) (unsigned long) arg; | ||
236 | ret = -EFAULT; | ||
237 | if(get_user(oldval, ptr)) | ||
238 | goto out; | ||
239 | ret = compat_sys_ioctl(fd, cmd, arg); | ||
240 | __get_user(newval, ptr); | ||
241 | if(newval == -1) { | ||
242 | __put_user(oldval, ptr); | ||
243 | ret = -EIO; | ||
244 | } | ||
245 | if(ret == -ENOTTY) | ||
246 | ret = -EIO; | ||
247 | goto out; | ||
248 | } | ||
249 | |||
250 | case _IOR('t', 119, int): { | ||
251 | int oldval, newval, __user *ptr; | ||
252 | |||
253 | cmd = TIOCGPGRP; | ||
254 | ptr = (int __user *) (unsigned long) arg; | ||
255 | ret = -EFAULT; | ||
256 | if(get_user(oldval, ptr)) | ||
257 | goto out; | ||
258 | ret = compat_sys_ioctl(fd, cmd, arg); | ||
259 | __get_user(newval, ptr); | ||
260 | if(newval == -1) { | ||
261 | __put_user(oldval, ptr); | ||
262 | ret = -EIO; | ||
263 | } | ||
264 | if(ret == -ENOTTY) | ||
265 | ret = -EIO; | ||
266 | goto out; | ||
267 | } | ||
268 | }; | ||
269 | |||
270 | ret = compat_sys_ioctl(fd, cmd, arg); | ||
271 | /* so stupid... */ | ||
272 | ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); | ||
273 | out: | ||
274 | return ret; | ||
275 | } | ||
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index f952745d0f3d..73ed01ba40dc 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c | |||
@@ -720,44 +720,6 @@ out: | |||
720 | return err; | 720 | return err; |
721 | } | 721 | } |
722 | 722 | ||
723 | asmlinkage long solaris_syscall(struct pt_regs *regs) | ||
724 | { | ||
725 | static int count; | ||
726 | |||
727 | regs->tpc = regs->tnpc; | ||
728 | regs->tnpc += 4; | ||
729 | if (test_thread_flag(TIF_32BIT)) { | ||
730 | regs->tpc &= 0xffffffff; | ||
731 | regs->tnpc &= 0xffffffff; | ||
732 | } | ||
733 | if (++count <= 5) { | ||
734 | printk ("For Solaris binary emulation you need solaris module loaded\n"); | ||
735 | show_regs (regs); | ||
736 | } | ||
737 | send_sig(SIGSEGV, current, 1); | ||
738 | |||
739 | return -ENOSYS; | ||
740 | } | ||
741 | |||
742 | #ifndef CONFIG_SUNOS_EMUL | ||
743 | asmlinkage long sunos_syscall(struct pt_regs *regs) | ||
744 | { | ||
745 | static int count; | ||
746 | |||
747 | regs->tpc = regs->tnpc; | ||
748 | regs->tnpc += 4; | ||
749 | if (test_thread_flag(TIF_32BIT)) { | ||
750 | regs->tpc &= 0xffffffff; | ||
751 | regs->tnpc &= 0xffffffff; | ||
752 | } | ||
753 | if (++count <= 20) | ||
754 | printk ("SunOS binary emulation not compiled in\n"); | ||
755 | force_sig(SIGSEGV, current); | ||
756 | |||
757 | return -ENOSYS; | ||
758 | } | ||
759 | #endif | ||
760 | |||
761 | asmlinkage long sys_utrap_install(utrap_entry_t type, | 723 | asmlinkage long sys_utrap_install(utrap_entry_t type, |
762 | utrap_handler_t new_p, | 724 | utrap_handler_t new_p, |
763 | utrap_handler_t new_d, | 725 | utrap_handler_t new_d, |
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c deleted file mode 100644 index e91194fe39d7..000000000000 --- a/arch/sparc64/kernel/sys_sunos32.c +++ /dev/null | |||
@@ -1,1359 +0,0 @@ | |||
1 | /* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $ | ||
2 | * sys_sunos32.c: SunOS binary compatibility layer on sparc64. | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) | ||
5 | * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) | ||
6 | * | ||
7 | * Based upon preliminary work which is: | ||
8 | * | ||
9 | * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu) | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/capability.h> | ||
16 | #include <linux/compat.h> | ||
17 | #include <linux/mman.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/swap.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/resource.h> | ||
23 | #include <linux/ipc.h> | ||
24 | #include <linux/shm.h> | ||
25 | #include <linux/msg.h> | ||
26 | #include <linux/sem.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/uio.h> | ||
29 | #include <linux/utsname.h> | ||
30 | #include <linux/major.h> | ||
31 | #include <linux/stat.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/pagemap.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/smp.h> | ||
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/syscalls.h> | ||
38 | |||
39 | #include <asm/uaccess.h> | ||
40 | #include <asm/page.h> | ||
41 | #include <asm/pgtable.h> | ||
42 | #include <asm/pconf.h> | ||
43 | #include <asm/idprom.h> /* for gethostid() */ | ||
44 | #include <asm/unistd.h> | ||
45 | #include <asm/system.h> | ||
46 | #include <asm/compat_signal.h> | ||
47 | |||
48 | /* For the nfs mount emulation */ | ||
49 | #include <linux/socket.h> | ||
50 | #include <linux/in.h> | ||
51 | #include <linux/nfs.h> | ||
52 | #include <linux/nfs2.h> | ||
53 | #include <linux/nfs_mount.h> | ||
54 | |||
55 | /* for sunos_select */ | ||
56 | #include <linux/time.h> | ||
57 | #include <linux/personality.h> | ||
58 | |||
59 | /* For SOCKET_I */ | ||
60 | #include <net/sock.h> | ||
61 | #include <net/compat.h> | ||
62 | |||
63 | #define SUNOS_NR_OPEN 256 | ||
64 | |||
65 | asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) | ||
66 | { | ||
67 | struct file *file = NULL; | ||
68 | unsigned long retval, ret_type; | ||
69 | |||
70 | if (flags & MAP_NORESERVE) { | ||
71 | static int cnt; | ||
72 | if (cnt++ < 10) | ||
73 | printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n", | ||
74 | current->comm); | ||
75 | flags &= ~MAP_NORESERVE; | ||
76 | } | ||
77 | retval = -EBADF; | ||
78 | if (!(flags & MAP_ANONYMOUS)) { | ||
79 | struct inode * inode; | ||
80 | if (fd >= SUNOS_NR_OPEN) | ||
81 | goto out; | ||
82 | file = fget(fd); | ||
83 | if (!file) | ||
84 | goto out; | ||
85 | inode = file->f_path.dentry->d_inode; | ||
86 | if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { | ||
87 | flags |= MAP_ANONYMOUS; | ||
88 | fput(file); | ||
89 | file = NULL; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | retval = -EINVAL; | ||
94 | if (!(flags & MAP_FIXED)) | ||
95 | addr = 0; | ||
96 | else if (len > 0xf0000000 || addr > 0xf0000000 - len) | ||
97 | goto out_putf; | ||
98 | ret_type = flags & _MAP_NEW; | ||
99 | flags &= ~_MAP_NEW; | ||
100 | |||
101 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
102 | down_write(¤t->mm->mmap_sem); | ||
103 | retval = do_mmap(file, | ||
104 | (unsigned long) addr, (unsigned long) len, | ||
105 | (unsigned long) prot, (unsigned long) flags, | ||
106 | (unsigned long) off); | ||
107 | up_write(¤t->mm->mmap_sem); | ||
108 | if (!ret_type) | ||
109 | retval = ((retval < 0xf0000000) ? 0 : retval); | ||
110 | out_putf: | ||
111 | if (file) | ||
112 | fput(file); | ||
113 | out: | ||
114 | return (u32) retval; | ||
115 | } | ||
116 | |||
117 | asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg) | ||
118 | { | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | asmlinkage int sunos_brk(u32 baddr) | ||
123 | { | ||
124 | int freepages, retval = -ENOMEM; | ||
125 | unsigned long rlim; | ||
126 | unsigned long newbrk, oldbrk, brk = (unsigned long) baddr; | ||
127 | |||
128 | down_write(¤t->mm->mmap_sem); | ||
129 | if (brk < current->mm->end_code) | ||
130 | goto out; | ||
131 | newbrk = PAGE_ALIGN(brk); | ||
132 | oldbrk = PAGE_ALIGN(current->mm->brk); | ||
133 | retval = 0; | ||
134 | if (oldbrk == newbrk) { | ||
135 | current->mm->brk = brk; | ||
136 | goto out; | ||
137 | } | ||
138 | /* Always allow shrinking brk. */ | ||
139 | if (brk <= current->mm->brk) { | ||
140 | current->mm->brk = brk; | ||
141 | do_munmap(current->mm, newbrk, oldbrk-newbrk); | ||
142 | goto out; | ||
143 | } | ||
144 | /* Check against rlimit and stack.. */ | ||
145 | retval = -ENOMEM; | ||
146 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
147 | if (rlim >= RLIM_INFINITY) | ||
148 | rlim = ~0; | ||
149 | if (brk - current->mm->end_code > rlim) | ||
150 | goto out; | ||
151 | /* Check against existing mmap mappings. */ | ||
152 | if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE)) | ||
153 | goto out; | ||
154 | /* stupid algorithm to decide if we have enough memory: while | ||
155 | * simple, it hopefully works in most obvious cases.. Easy to | ||
156 | * fool it, but this should catch most mistakes. | ||
157 | */ | ||
158 | freepages = global_page_state(NR_FILE_PAGES); | ||
159 | freepages >>= 1; | ||
160 | freepages += nr_free_pages(); | ||
161 | freepages += nr_swap_pages; | ||
162 | freepages -= num_physpages >> 4; | ||
163 | freepages -= (newbrk-oldbrk) >> PAGE_SHIFT; | ||
164 | if (freepages < 0) | ||
165 | goto out; | ||
166 | /* Ok, we have probably got enough memory - let it rip. */ | ||
167 | current->mm->brk = brk; | ||
168 | do_brk(oldbrk, newbrk-oldbrk); | ||
169 | retval = 0; | ||
170 | out: | ||
171 | up_write(¤t->mm->mmap_sem); | ||
172 | return retval; | ||
173 | } | ||
174 | |||
175 | asmlinkage u32 sunos_sbrk(int increment) | ||
176 | { | ||
177 | int error, oldbrk; | ||
178 | |||
179 | /* This should do it hopefully... */ | ||
180 | oldbrk = (int)current->mm->brk; | ||
181 | error = sunos_brk(((int) current->mm->brk) + increment); | ||
182 | if (!error) | ||
183 | error = oldbrk; | ||
184 | return error; | ||
185 | } | ||
186 | |||
187 | asmlinkage u32 sunos_sstk(int increment) | ||
188 | { | ||
189 | printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n", | ||
190 | current->comm, increment); | ||
191 | |||
192 | return (u32)-1; | ||
193 | } | ||
194 | |||
195 | /* Give hints to the kernel as to what paging strategy to use... | ||
196 | * Completely bogus, don't remind me. | ||
197 | */ | ||
198 | #define VA_NORMAL 0 /* Normal vm usage expected */ | ||
199 | #define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */ | ||
200 | #define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */ | ||
201 | #define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */ | ||
202 | static char *vstrings[] = { | ||
203 | "VA_NORMAL", | ||
204 | "VA_ABNORMAL", | ||
205 | "VA_SEQUENTIAL", | ||
206 | "VA_INVALIDATE", | ||
207 | }; | ||
208 | |||
209 | asmlinkage void sunos_vadvise(u32 strategy) | ||
210 | { | ||
211 | static int count; | ||
212 | |||
213 | /* I wanna see who uses this... */ | ||
214 | if (count++ < 5) | ||
215 | printk("%s: Advises us to use %s paging strategy\n", | ||
216 | current->comm, | ||
217 | strategy <= 3 ? vstrings[strategy] : "BOGUS"); | ||
218 | } | ||
219 | |||
220 | /* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE | ||
221 | * resource limit and is for backwards compatibility with older sunos | ||
222 | * revs. | ||
223 | */ | ||
224 | asmlinkage int sunos_getdtablesize(void) | ||
225 | { | ||
226 | return SUNOS_NR_OPEN; | ||
227 | } | ||
228 | |||
229 | |||
230 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
231 | |||
232 | asmlinkage u32 sunos_sigblock(u32 blk_mask) | ||
233 | { | ||
234 | u32 old; | ||
235 | |||
236 | spin_lock_irq(¤t->sighand->siglock); | ||
237 | old = (u32) current->blocked.sig[0]; | ||
238 | current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); | ||
239 | recalc_sigpending(); | ||
240 | spin_unlock_irq(¤t->sighand->siglock); | ||
241 | return old; | ||
242 | } | ||
243 | |||
244 | asmlinkage u32 sunos_sigsetmask(u32 newmask) | ||
245 | { | ||
246 | u32 retval; | ||
247 | |||
248 | spin_lock_irq(¤t->sighand->siglock); | ||
249 | retval = (u32) current->blocked.sig[0]; | ||
250 | current->blocked.sig[0] = (newmask & _BLOCKABLE); | ||
251 | recalc_sigpending(); | ||
252 | spin_unlock_irq(¤t->sighand->siglock); | ||
253 | return retval; | ||
254 | } | ||
255 | |||
256 | /* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */ | ||
257 | /* getdents system call, the format of the structure just has a different */ | ||
258 | /* layout (d_off+d_ino instead of d_ino+d_off) */ | ||
259 | struct sunos_dirent { | ||
260 | s32 d_off; | ||
261 | u32 d_ino; | ||
262 | u16 d_reclen; | ||
263 | u16 d_namlen; | ||
264 | char d_name[1]; | ||
265 | }; | ||
266 | |||
267 | struct sunos_dirent_callback { | ||
268 | struct sunos_dirent __user *curr; | ||
269 | struct sunos_dirent __user *previous; | ||
270 | int count; | ||
271 | int error; | ||
272 | }; | ||
273 | |||
274 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | ||
275 | #define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1)) | ||
276 | |||
277 | static int sunos_filldir(void * __buf, const char * name, int namlen, | ||
278 | loff_t offset, ino_t ino, unsigned int d_type) | ||
279 | { | ||
280 | struct sunos_dirent __user *dirent; | ||
281 | struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; | ||
282 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | ||
283 | u32 d_ino; | ||
284 | |||
285 | buf->error = -EINVAL; /* only used if we fail.. */ | ||
286 | if (reclen > buf->count) | ||
287 | return -EINVAL; | ||
288 | d_ino = ino; | ||
289 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
290 | return -EOVERFLOW; | ||
291 | dirent = buf->previous; | ||
292 | if (dirent) | ||
293 | put_user(offset, &dirent->d_off); | ||
294 | dirent = buf->curr; | ||
295 | buf->previous = dirent; | ||
296 | put_user(d_ino, &dirent->d_ino); | ||
297 | put_user(namlen, &dirent->d_namlen); | ||
298 | put_user(reclen, &dirent->d_reclen); | ||
299 | if (copy_to_user(dirent->d_name, name, namlen)) | ||
300 | return -EFAULT; | ||
301 | put_user(0, dirent->d_name + namlen); | ||
302 | dirent = (void __user *) dirent + reclen; | ||
303 | buf->curr = dirent; | ||
304 | buf->count -= reclen; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt) | ||
309 | { | ||
310 | struct file * file; | ||
311 | struct sunos_dirent __user *lastdirent; | ||
312 | struct sunos_dirent_callback buf; | ||
313 | int error = -EBADF; | ||
314 | |||
315 | if (fd >= SUNOS_NR_OPEN) | ||
316 | goto out; | ||
317 | |||
318 | file = fget(fd); | ||
319 | if (!file) | ||
320 | goto out; | ||
321 | |||
322 | error = -EINVAL; | ||
323 | if (cnt < (sizeof(struct sunos_dirent) + 255)) | ||
324 | goto out_putf; | ||
325 | |||
326 | buf.curr = (struct sunos_dirent __user *) dirent; | ||
327 | buf.previous = NULL; | ||
328 | buf.count = cnt; | ||
329 | buf.error = 0; | ||
330 | |||
331 | error = vfs_readdir(file, sunos_filldir, &buf); | ||
332 | if (error < 0) | ||
333 | goto out_putf; | ||
334 | |||
335 | lastdirent = buf.previous; | ||
336 | error = buf.error; | ||
337 | if (lastdirent) { | ||
338 | put_user(file->f_pos, &lastdirent->d_off); | ||
339 | error = cnt - buf.count; | ||
340 | } | ||
341 | |||
342 | out_putf: | ||
343 | fput(file); | ||
344 | out: | ||
345 | return error; | ||
346 | } | ||
347 | |||
348 | /* Old sunos getdirentries, severely broken compatibility stuff here. */ | ||
349 | struct sunos_direntry { | ||
350 | u32 d_ino; | ||
351 | u16 d_reclen; | ||
352 | u16 d_namlen; | ||
353 | char d_name[1]; | ||
354 | }; | ||
355 | |||
356 | struct sunos_direntry_callback { | ||
357 | struct sunos_direntry __user *curr; | ||
358 | struct sunos_direntry __user *previous; | ||
359 | int count; | ||
360 | int error; | ||
361 | }; | ||
362 | |||
363 | static int sunos_filldirentry(void * __buf, const char * name, int namlen, | ||
364 | loff_t offset, ino_t ino, unsigned int d_type) | ||
365 | { | ||
366 | struct sunos_direntry __user *dirent; | ||
367 | struct sunos_direntry_callback * buf = | ||
368 | (struct sunos_direntry_callback *) __buf; | ||
369 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | ||
370 | u32 d_ino; | ||
371 | |||
372 | buf->error = -EINVAL; /* only used if we fail.. */ | ||
373 | if (reclen > buf->count) | ||
374 | return -EINVAL; | ||
375 | d_ino = ino; | ||
376 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
377 | return -EOVERFLOW; | ||
378 | dirent = buf->previous; | ||
379 | dirent = buf->curr; | ||
380 | buf->previous = dirent; | ||
381 | put_user(d_ino, &dirent->d_ino); | ||
382 | put_user(namlen, &dirent->d_namlen); | ||
383 | put_user(reclen, &dirent->d_reclen); | ||
384 | if (copy_to_user(dirent->d_name, name, namlen)) | ||
385 | return -EFAULT; | ||
386 | put_user(0, dirent->d_name + namlen); | ||
387 | dirent = (void __user *) dirent + reclen; | ||
388 | buf->curr = dirent; | ||
389 | buf->count -= reclen; | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | asmlinkage int sunos_getdirentries(unsigned int fd, | ||
394 | void __user *dirent, | ||
395 | int cnt, | ||
396 | unsigned int __user *basep) | ||
397 | { | ||
398 | struct file * file; | ||
399 | struct sunos_direntry __user *lastdirent; | ||
400 | int error = -EBADF; | ||
401 | struct sunos_direntry_callback buf; | ||
402 | |||
403 | if (fd >= SUNOS_NR_OPEN) | ||
404 | goto out; | ||
405 | |||
406 | file = fget(fd); | ||
407 | if (!file) | ||
408 | goto out; | ||
409 | |||
410 | error = -EINVAL; | ||
411 | if (cnt < (sizeof(struct sunos_direntry) + 255)) | ||
412 | goto out_putf; | ||
413 | |||
414 | buf.curr = (struct sunos_direntry __user *) dirent; | ||
415 | buf.previous = NULL; | ||
416 | buf.count = cnt; | ||
417 | buf.error = 0; | ||
418 | |||
419 | error = vfs_readdir(file, sunos_filldirentry, &buf); | ||
420 | if (error < 0) | ||
421 | goto out_putf; | ||
422 | |||
423 | lastdirent = buf.previous; | ||
424 | error = buf.error; | ||
425 | if (lastdirent) { | ||
426 | put_user(file->f_pos, basep); | ||
427 | error = cnt - buf.count; | ||
428 | } | ||
429 | |||
430 | out_putf: | ||
431 | fput(file); | ||
432 | out: | ||
433 | return error; | ||
434 | } | ||
435 | |||
436 | struct sunos_utsname { | ||
437 | char sname[9]; | ||
438 | char nname[9]; | ||
439 | char nnext[56]; | ||
440 | char rel[9]; | ||
441 | char ver[9]; | ||
442 | char mach[9]; | ||
443 | }; | ||
444 | |||
445 | asmlinkage int sunos_uname(struct sunos_utsname __user *name) | ||
446 | { | ||
447 | int ret; | ||
448 | |||
449 | down_read(&uts_sem); | ||
450 | ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], | ||
451 | sizeof(name->sname) - 1); | ||
452 | ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], | ||
453 | sizeof(name->nname) - 1); | ||
454 | ret |= put_user('\0', &name->nname[8]); | ||
455 | ret |= copy_to_user(&name->rel[0], &utsname()->release[0], | ||
456 | sizeof(name->rel) - 1); | ||
457 | ret |= copy_to_user(&name->ver[0], &utsname()->version[0], | ||
458 | sizeof(name->ver) - 1); | ||
459 | ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], | ||
460 | sizeof(name->mach) - 1); | ||
461 | up_read(&uts_sem); | ||
462 | return (ret ? -EFAULT : 0); | ||
463 | } | ||
464 | |||
465 | asmlinkage int sunos_nosys(void) | ||
466 | { | ||
467 | struct pt_regs *regs; | ||
468 | siginfo_t info; | ||
469 | static int cnt; | ||
470 | |||
471 | regs = current_thread_info()->kregs; | ||
472 | if (test_thread_flag(TIF_32BIT)) { | ||
473 | regs->tpc &= 0xffffffff; | ||
474 | regs->tnpc &= 0xffffffff; | ||
475 | } | ||
476 | info.si_signo = SIGSYS; | ||
477 | info.si_errno = 0; | ||
478 | info.si_code = __SI_FAULT|0x100; | ||
479 | info.si_addr = (void __user *)regs->tpc; | ||
480 | info.si_trapno = regs->u_regs[UREG_G1]; | ||
481 | send_sig_info(SIGSYS, &info, current); | ||
482 | if (cnt++ < 4) { | ||
483 | printk("Process makes ni_syscall number %d, register dump:\n", | ||
484 | (int) regs->u_regs[UREG_G1]); | ||
485 | show_regs(regs); | ||
486 | } | ||
487 | return -ENOSYS; | ||
488 | } | ||
489 | |||
490 | /* This is not a real and complete implementation yet, just to keep | ||
491 | * the easy SunOS binaries happy. | ||
492 | */ | ||
493 | asmlinkage int sunos_fpathconf(int fd, int name) | ||
494 | { | ||
495 | int ret; | ||
496 | |||
497 | switch(name) { | ||
498 | case _PCONF_LINK: | ||
499 | ret = LINK_MAX; | ||
500 | break; | ||
501 | case _PCONF_CANON: | ||
502 | ret = MAX_CANON; | ||
503 | break; | ||
504 | case _PCONF_INPUT: | ||
505 | ret = MAX_INPUT; | ||
506 | break; | ||
507 | case _PCONF_NAME: | ||
508 | ret = NAME_MAX; | ||
509 | break; | ||
510 | case _PCONF_PATH: | ||
511 | ret = PATH_MAX; | ||
512 | break; | ||
513 | case _PCONF_PIPE: | ||
514 | ret = PIPE_BUF; | ||
515 | break; | ||
516 | case _PCONF_CHRESTRICT: /* XXX Investigate XXX */ | ||
517 | ret = 1; | ||
518 | break; | ||
519 | case _PCONF_NOTRUNC: /* XXX Investigate XXX */ | ||
520 | case _PCONF_VDISABLE: | ||
521 | ret = 0; | ||
522 | break; | ||
523 | default: | ||
524 | ret = -EINVAL; | ||
525 | break; | ||
526 | } | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | asmlinkage int sunos_pathconf(u32 u_path, int name) | ||
531 | { | ||
532 | int ret; | ||
533 | |||
534 | ret = sunos_fpathconf(0, name); /* XXX cheese XXX */ | ||
535 | return ret; | ||
536 | } | ||
537 | |||
538 | asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x) | ||
539 | { | ||
540 | int ret; | ||
541 | |||
542 | /* SunOS binaries expect that select won't change the tvp contents */ | ||
543 | ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp), | ||
544 | compat_ptr(exp), compat_ptr(tvp_x)); | ||
545 | if (ret == -EINTR && tvp_x) { | ||
546 | struct compat_timeval __user *tvp = compat_ptr(tvp_x); | ||
547 | time_t sec, usec; | ||
548 | |||
549 | __get_user(sec, &tvp->tv_sec); | ||
550 | __get_user(usec, &tvp->tv_usec); | ||
551 | if (sec == 0 && usec == 0) | ||
552 | ret = 0; | ||
553 | } | ||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | asmlinkage void sunos_nop(void) | ||
558 | { | ||
559 | return; | ||
560 | } | ||
561 | |||
562 | #if 0 /* This code doesn't translate user pointers correctly, | ||
563 | * disable for now. -DaveM | ||
564 | */ | ||
565 | |||
566 | /* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */ | ||
567 | #define SMNT_RDONLY 1 | ||
568 | #define SMNT_NOSUID 2 | ||
569 | #define SMNT_NEWTYPE 4 | ||
570 | #define SMNT_GRPID 8 | ||
571 | #define SMNT_REMOUNT 16 | ||
572 | #define SMNT_NOSUB 32 | ||
573 | #define SMNT_MULTI 64 | ||
574 | #define SMNT_SYS5 128 | ||
575 | |||
576 | struct sunos_fh_t { | ||
577 | char fh_data [NFS_FHSIZE]; | ||
578 | }; | ||
579 | |||
580 | struct sunos_nfs_mount_args { | ||
581 | struct sockaddr_in *addr; /* file server address */ | ||
582 | struct nfs_fh *fh; /* File handle to be mounted */ | ||
583 | int flags; /* flags */ | ||
584 | int wsize; /* write size in bytes */ | ||
585 | int rsize; /* read size in bytes */ | ||
586 | int timeo; /* initial timeout in .1 secs */ | ||
587 | int retrans; /* times to retry send */ | ||
588 | char *hostname; /* server's hostname */ | ||
589 | int acregmin; /* attr cache file min secs */ | ||
590 | int acregmax; /* attr cache file max secs */ | ||
591 | int acdirmin; /* attr cache dir min secs */ | ||
592 | int acdirmax; /* attr cache dir max secs */ | ||
593 | char *netname; /* server's netname */ | ||
594 | }; | ||
595 | |||
596 | |||
597 | /* Bind the socket on a local reserved port and connect it to the | ||
598 | * remote server. This on Linux/i386 is done by the mount program, | ||
599 | * not by the kernel. | ||
600 | */ | ||
601 | /* XXXXXXXXXXXXXXXXXXXX */ | ||
602 | static int | ||
603 | sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) | ||
604 | { | ||
605 | struct sockaddr_in local; | ||
606 | struct sockaddr_in server; | ||
607 | int try_port; | ||
608 | int ret; | ||
609 | struct socket *socket; | ||
610 | struct inode *inode; | ||
611 | struct file *file; | ||
612 | |||
613 | file = fget(fd); | ||
614 | if (!file) | ||
615 | return 0; | ||
616 | |||
617 | inode = file->f_path.dentry->d_inode; | ||
618 | |||
619 | socket = SOCKET_I(inode); | ||
620 | local.sin_family = AF_INET; | ||
621 | local.sin_addr.s_addr = htonl(INADDR_ANY); | ||
622 | |||
623 | /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */ | ||
624 | try_port = 1024; | ||
625 | do { | ||
626 | local.sin_port = htons (--try_port); | ||
627 | ret = socket->ops->bind(socket, (struct sockaddr*)&local, | ||
628 | sizeof(local)); | ||
629 | } while (ret && try_port > (1024 / 2)); | ||
630 | |||
631 | if (ret) { | ||
632 | fput(file); | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | server.sin_family = AF_INET; | ||
637 | server.sin_addr = addr->sin_addr; | ||
638 | server.sin_port = NFS_PORT; | ||
639 | |||
640 | /* Call sys_connect */ | ||
641 | ret = socket->ops->connect (socket, (struct sockaddr *) &server, | ||
642 | sizeof (server), file->f_flags); | ||
643 | fput(file); | ||
644 | if (ret < 0) | ||
645 | return 0; | ||
646 | return 1; | ||
647 | } | ||
648 | |||
649 | /* XXXXXXXXXXXXXXXXXXXX */ | ||
650 | static int get_default (int value, int def_value) | ||
651 | { | ||
652 | if (value) | ||
653 | return value; | ||
654 | else | ||
655 | return def_value; | ||
656 | } | ||
657 | |||
658 | /* XXXXXXXXXXXXXXXXXXXX */ | ||
659 | static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data) | ||
660 | { | ||
661 | int server_fd, err; | ||
662 | char *the_name, *mount_page; | ||
663 | struct nfs_mount_data linux_nfs_mount; | ||
664 | struct sunos_nfs_mount_args sunos_mount; | ||
665 | |||
666 | /* Ok, here comes the fun part: Linux's nfs mount needs a | ||
667 | * socket connection to the server, but SunOS mount does not | ||
668 | * require this, so we use the information on the destination | ||
669 | * address to create a socket and bind it to a reserved | ||
670 | * port on this system | ||
671 | */ | ||
672 | if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount))) | ||
673 | return -EFAULT; | ||
674 | |||
675 | server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
676 | if (server_fd < 0) | ||
677 | return -ENXIO; | ||
678 | |||
679 | if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr, | ||
680 | sizeof(*sunos_mount.addr)) || | ||
681 | copy_from_user(&linux_nfs_mount.root, sunos_mount.fh, | ||
682 | sizeof(*sunos_mount.fh))) { | ||
683 | sys_close (server_fd); | ||
684 | return -EFAULT; | ||
685 | } | ||
686 | |||
687 | if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){ | ||
688 | sys_close (server_fd); | ||
689 | return -ENXIO; | ||
690 | } | ||
691 | |||
692 | /* Now, bind it to a locally reserved port */ | ||
693 | linux_nfs_mount.version = NFS_MOUNT_VERSION; | ||
694 | linux_nfs_mount.flags = sunos_mount.flags; | ||
695 | linux_nfs_mount.fd = server_fd; | ||
696 | |||
697 | linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192); | ||
698 | linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192); | ||
699 | linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10); | ||
700 | linux_nfs_mount.retrans = sunos_mount.retrans; | ||
701 | |||
702 | linux_nfs_mount.acregmin = sunos_mount.acregmin; | ||
703 | linux_nfs_mount.acregmax = sunos_mount.acregmax; | ||
704 | linux_nfs_mount.acdirmin = sunos_mount.acdirmin; | ||
705 | linux_nfs_mount.acdirmax = sunos_mount.acdirmax; | ||
706 | |||
707 | the_name = getname(sunos_mount.hostname); | ||
708 | if (IS_ERR(the_name)) | ||
709 | return PTR_ERR(the_name); | ||
710 | |||
711 | strlcpy(linux_nfs_mount.hostname, the_name, | ||
712 | sizeof(linux_nfs_mount.hostname)); | ||
713 | putname (the_name); | ||
714 | |||
715 | mount_page = (char *) get_zeroed_page(GFP_KERNEL); | ||
716 | if (!mount_page) | ||
717 | return -ENOMEM; | ||
718 | |||
719 | memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount)); | ||
720 | |||
721 | err = do_mount("", dir_name, "nfs", linux_flags, mount_page); | ||
722 | |||
723 | free_page((unsigned long) mount_page); | ||
724 | return err; | ||
725 | } | ||
726 | |||
727 | /* XXXXXXXXXXXXXXXXXXXX */ | ||
728 | asmlinkage int | ||
729 | sunos_mount(char *type, char *dir, int flags, void *data) | ||
730 | { | ||
731 | int linux_flags = 0; | ||
732 | int ret = -EINVAL; | ||
733 | char *dev_fname = 0; | ||
734 | char *dir_page, *type_page; | ||
735 | |||
736 | if (!capable (CAP_SYS_ADMIN)) | ||
737 | return -EPERM; | ||
738 | |||
739 | /* We don't handle the integer fs type */ | ||
740 | if ((flags & SMNT_NEWTYPE) == 0) | ||
741 | goto out; | ||
742 | |||
743 | /* Do not allow for those flags we don't support */ | ||
744 | if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5)) | ||
745 | goto out; | ||
746 | |||
747 | if (flags & SMNT_REMOUNT) | ||
748 | linux_flags |= MS_REMOUNT; | ||
749 | if (flags & SMNT_RDONLY) | ||
750 | linux_flags |= MS_RDONLY; | ||
751 | if (flags & SMNT_NOSUID) | ||
752 | linux_flags |= MS_NOSUID; | ||
753 | |||
754 | dir_page = getname(dir); | ||
755 | ret = PTR_ERR(dir_page); | ||
756 | if (IS_ERR(dir_page)) | ||
757 | goto out; | ||
758 | |||
759 | type_page = getname(type); | ||
760 | ret = PTR_ERR(type_page); | ||
761 | if (IS_ERR(type_page)) | ||
762 | goto out1; | ||
763 | |||
764 | if (strcmp(type_page, "ext2") == 0) { | ||
765 | dev_fname = getname(data); | ||
766 | } else if (strcmp(type_page, "iso9660") == 0) { | ||
767 | dev_fname = getname(data); | ||
768 | } else if (strcmp(type_page, "minix") == 0) { | ||
769 | dev_fname = getname(data); | ||
770 | } else if (strcmp(type_page, "nfs") == 0) { | ||
771 | ret = sunos_nfs_mount (dir_page, flags, data); | ||
772 | goto out2; | ||
773 | } else if (strcmp(type_page, "ufs") == 0) { | ||
774 | printk("Warning: UFS filesystem mounts unsupported.\n"); | ||
775 | ret = -ENODEV; | ||
776 | goto out2; | ||
777 | } else if (strcmp(type_page, "proc")) { | ||
778 | ret = -ENODEV; | ||
779 | goto out2; | ||
780 | } | ||
781 | ret = PTR_ERR(dev_fname); | ||
782 | if (IS_ERR(dev_fname)) | ||
783 | goto out2; | ||
784 | lock_kernel(); | ||
785 | ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL); | ||
786 | unlock_kernel(); | ||
787 | if (dev_fname) | ||
788 | putname(dev_fname); | ||
789 | out2: | ||
790 | putname(type_page); | ||
791 | out1: | ||
792 | putname(dir_page); | ||
793 | out: | ||
794 | return ret; | ||
795 | } | ||
796 | #endif | ||
797 | |||
798 | asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) | ||
799 | { | ||
800 | int ret; | ||
801 | |||
802 | /* So stupid... */ | ||
803 | if ((!pid || pid == current->pid) && | ||
804 | !pgid) { | ||
805 | sys_setsid(); | ||
806 | ret = 0; | ||
807 | } else { | ||
808 | ret = sys_setpgid(pid, pgid); | ||
809 | } | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | /* So stupid... */ | ||
814 | extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int, | ||
815 | struct compat_rusage __user *); | ||
816 | |||
817 | asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru) | ||
818 | { | ||
819 | int ret; | ||
820 | |||
821 | ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)), | ||
822 | stat_addr, options, ru); | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | asmlinkage int sunos_killpg(int pgrp, int sig) | ||
827 | { | ||
828 | int ret; | ||
829 | |||
830 | rcu_read_lock(); | ||
831 | ret = -EINVAL; | ||
832 | if (pgrp > 0) | ||
833 | ret = kill_pgrp(find_vpid(pgrp), sig, 0); | ||
834 | rcu_read_unlock(); | ||
835 | |||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | asmlinkage int sunos_audit(void) | ||
840 | { | ||
841 | printk ("sys_audit\n"); | ||
842 | return -1; | ||
843 | } | ||
844 | |||
845 | asmlinkage u32 sunos_gethostid(void) | ||
846 | { | ||
847 | u32 ret; | ||
848 | |||
849 | ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum)); | ||
850 | |||
851 | return ret; | ||
852 | } | ||
853 | |||
854 | /* sysconf options, for SunOS compatibility */ | ||
855 | #define _SC_ARG_MAX 1 | ||
856 | #define _SC_CHILD_MAX 2 | ||
857 | #define _SC_CLK_TCK 3 | ||
858 | #define _SC_NGROUPS_MAX 4 | ||
859 | #define _SC_OPEN_MAX 5 | ||
860 | #define _SC_JOB_CONTROL 6 | ||
861 | #define _SC_SAVED_IDS 7 | ||
862 | #define _SC_VERSION 8 | ||
863 | |||
864 | asmlinkage s32 sunos_sysconf (int name) | ||
865 | { | ||
866 | s32 ret; | ||
867 | |||
868 | switch (name){ | ||
869 | case _SC_ARG_MAX: | ||
870 | ret = ARG_MAX; | ||
871 | break; | ||
872 | case _SC_CHILD_MAX: | ||
873 | ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur; | ||
874 | break; | ||
875 | case _SC_CLK_TCK: | ||
876 | ret = HZ; | ||
877 | break; | ||
878 | case _SC_NGROUPS_MAX: | ||
879 | ret = NGROUPS_MAX; | ||
880 | break; | ||
881 | case _SC_OPEN_MAX: | ||
882 | ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; | ||
883 | break; | ||
884 | case _SC_JOB_CONTROL: | ||
885 | ret = 1; /* yes, we do support job control */ | ||
886 | break; | ||
887 | case _SC_SAVED_IDS: | ||
888 | ret = 1; /* yes, we do support saved uids */ | ||
889 | break; | ||
890 | case _SC_VERSION: | ||
891 | /* mhm, POSIX_VERSION is in /usr/include/unistd.h | ||
892 | * should it go on /usr/include/linux? | ||
893 | */ | ||
894 | ret = 199009; | ||
895 | break; | ||
896 | default: | ||
897 | ret = -1; | ||
898 | break; | ||
899 | }; | ||
900 | return ret; | ||
901 | } | ||
902 | |||
903 | asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr) | ||
904 | { | ||
905 | union semun arg4; | ||
906 | int ret; | ||
907 | |||
908 | switch (op) { | ||
909 | case 0: | ||
910 | /* Most arguments match on a 1:1 basis but cmd doesn't */ | ||
911 | switch(arg3) { | ||
912 | case 4: | ||
913 | arg3=GETPID; break; | ||
914 | case 5: | ||
915 | arg3=GETVAL; break; | ||
916 | case 6: | ||
917 | arg3=GETALL; break; | ||
918 | case 3: | ||
919 | arg3=GETNCNT; break; | ||
920 | case 7: | ||
921 | arg3=GETZCNT; break; | ||
922 | case 8: | ||
923 | arg3=SETVAL; break; | ||
924 | case 9: | ||
925 | arg3=SETALL; break; | ||
926 | } | ||
927 | /* sys_semctl(): */ | ||
928 | /* value to modify semaphore to */ | ||
929 | arg4.__pad = ptr; | ||
930 | ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4); | ||
931 | break; | ||
932 | case 1: | ||
933 | /* sys_semget(): */ | ||
934 | ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3); | ||
935 | break; | ||
936 | case 2: | ||
937 | /* sys_semop(): */ | ||
938 | ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2, | ||
939 | (unsigned int) arg3); | ||
940 | break; | ||
941 | default: | ||
942 | ret = -EINVAL; | ||
943 | break; | ||
944 | }; | ||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | struct msgbuf32 { | ||
949 | s32 mtype; | ||
950 | char mtext[1]; | ||
951 | }; | ||
952 | |||
953 | struct ipc_perm32 | ||
954 | { | ||
955 | key_t key; | ||
956 | compat_uid_t uid; | ||
957 | compat_gid_t gid; | ||
958 | compat_uid_t cuid; | ||
959 | compat_gid_t cgid; | ||
960 | compat_mode_t mode; | ||
961 | unsigned short seq; | ||
962 | }; | ||
963 | |||
964 | struct msqid_ds32 | ||
965 | { | ||
966 | struct ipc_perm32 msg_perm; | ||
967 | u32 msg_first; | ||
968 | u32 msg_last; | ||
969 | compat_time_t msg_stime; | ||
970 | compat_time_t msg_rtime; | ||
971 | compat_time_t msg_ctime; | ||
972 | u32 wwait; | ||
973 | u32 rwait; | ||
974 | unsigned short msg_cbytes; | ||
975 | unsigned short msg_qnum; | ||
976 | unsigned short msg_qbytes; | ||
977 | compat_ipc_pid_t msg_lspid; | ||
978 | compat_ipc_pid_t msg_lrpid; | ||
979 | }; | ||
980 | |||
981 | static inline int sunos_msqid_get(struct msqid_ds32 __user *user, | ||
982 | struct msqid_ds *kern) | ||
983 | { | ||
984 | if (get_user(kern->msg_perm.key, &user->msg_perm.key) || | ||
985 | __get_user(kern->msg_perm.uid, &user->msg_perm.uid) || | ||
986 | __get_user(kern->msg_perm.gid, &user->msg_perm.gid) || | ||
987 | __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || | ||
988 | __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || | ||
989 | __get_user(kern->msg_stime, &user->msg_stime) || | ||
990 | __get_user(kern->msg_rtime, &user->msg_rtime) || | ||
991 | __get_user(kern->msg_ctime, &user->msg_ctime) || | ||
992 | __get_user(kern->msg_ctime, &user->msg_cbytes) || | ||
993 | __get_user(kern->msg_ctime, &user->msg_qnum) || | ||
994 | __get_user(kern->msg_ctime, &user->msg_qbytes) || | ||
995 | __get_user(kern->msg_ctime, &user->msg_lspid) || | ||
996 | __get_user(kern->msg_ctime, &user->msg_lrpid)) | ||
997 | return -EFAULT; | ||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | static inline int sunos_msqid_put(struct msqid_ds32 __user *user, | ||
1002 | struct msqid_ds *kern) | ||
1003 | { | ||
1004 | if (put_user(kern->msg_perm.key, &user->msg_perm.key) || | ||
1005 | __put_user(kern->msg_perm.uid, &user->msg_perm.uid) || | ||
1006 | __put_user(kern->msg_perm.gid, &user->msg_perm.gid) || | ||
1007 | __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || | ||
1008 | __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || | ||
1009 | __put_user(kern->msg_stime, &user->msg_stime) || | ||
1010 | __put_user(kern->msg_rtime, &user->msg_rtime) || | ||
1011 | __put_user(kern->msg_ctime, &user->msg_ctime) || | ||
1012 | __put_user(kern->msg_ctime, &user->msg_cbytes) || | ||
1013 | __put_user(kern->msg_ctime, &user->msg_qnum) || | ||
1014 | __put_user(kern->msg_ctime, &user->msg_qbytes) || | ||
1015 | __put_user(kern->msg_ctime, &user->msg_lspid) || | ||
1016 | __put_user(kern->msg_ctime, &user->msg_lrpid)) | ||
1017 | return -EFAULT; | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len) | ||
1022 | { | ||
1023 | if (get_user(kern->mtype, &user->mtype) || | ||
1024 | __copy_from_user(kern->mtext, &user->mtext, len)) | ||
1025 | return -EFAULT; | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len) | ||
1030 | { | ||
1031 | if (put_user(kern->mtype, &user->mtype) || | ||
1032 | __copy_to_user(user->mtext, kern->mtext, len)) | ||
1033 | return -EFAULT; | ||
1034 | return 0; | ||
1035 | } | ||
1036 | |||
1037 | asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) | ||
1038 | { | ||
1039 | struct sparc_stackf32 __user *sp; | ||
1040 | struct msqid_ds kds; | ||
1041 | struct msgbuf *kmbuf; | ||
1042 | mm_segment_t old_fs = get_fs(); | ||
1043 | u32 arg5; | ||
1044 | int rval; | ||
1045 | |||
1046 | switch(op) { | ||
1047 | case 0: | ||
1048 | rval = sys_msgget((key_t)arg1, (int)arg2); | ||
1049 | break; | ||
1050 | case 1: | ||
1051 | if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) { | ||
1052 | set_fs(KERNEL_DS); | ||
1053 | rval = sys_msgctl((int)arg1, (int)arg2, | ||
1054 | (struct msqid_ds __user *)(unsigned long)arg3); | ||
1055 | set_fs(old_fs); | ||
1056 | if (!rval) | ||
1057 | rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3, | ||
1058 | &kds); | ||
1059 | } else | ||
1060 | rval = -EFAULT; | ||
1061 | break; | ||
1062 | case 2: | ||
1063 | rval = -EFAULT; | ||
1064 | kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, | ||
1065 | GFP_KERNEL); | ||
1066 | if (!kmbuf) | ||
1067 | break; | ||
1068 | sp = (struct sparc_stackf32 __user *) | ||
1069 | (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL); | ||
1070 | if (get_user(arg5, &sp->xxargs[0])) { | ||
1071 | rval = -EFAULT; | ||
1072 | kfree(kmbuf); | ||
1073 | break; | ||
1074 | } | ||
1075 | set_fs(KERNEL_DS); | ||
1076 | rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf, | ||
1077 | (size_t)arg3, | ||
1078 | (long)arg4, (int)arg5); | ||
1079 | set_fs(old_fs); | ||
1080 | if (!rval) | ||
1081 | rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2, | ||
1082 | kmbuf, arg3); | ||
1083 | kfree(kmbuf); | ||
1084 | break; | ||
1085 | case 3: | ||
1086 | rval = -EFAULT; | ||
1087 | kmbuf = kmalloc(sizeof(struct msgbuf) + arg3, | ||
1088 | GFP_KERNEL); | ||
1089 | if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, | ||
1090 | kmbuf, arg3)) | ||
1091 | break; | ||
1092 | set_fs(KERNEL_DS); | ||
1093 | rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf, | ||
1094 | (size_t)arg3, (int)arg4); | ||
1095 | set_fs(old_fs); | ||
1096 | kfree(kmbuf); | ||
1097 | break; | ||
1098 | default: | ||
1099 | rval = -EINVAL; | ||
1100 | break; | ||
1101 | } | ||
1102 | return rval; | ||
1103 | } | ||
1104 | |||
1105 | struct shmid_ds32 { | ||
1106 | struct ipc_perm32 shm_perm; | ||
1107 | int shm_segsz; | ||
1108 | compat_time_t shm_atime; | ||
1109 | compat_time_t shm_dtime; | ||
1110 | compat_time_t shm_ctime; | ||
1111 | compat_ipc_pid_t shm_cpid; | ||
1112 | compat_ipc_pid_t shm_lpid; | ||
1113 | unsigned short shm_nattch; | ||
1114 | }; | ||
1115 | |||
1116 | static inline int sunos_shmid_get(struct shmid_ds32 __user *user, | ||
1117 | struct shmid_ds *kern) | ||
1118 | { | ||
1119 | if (get_user(kern->shm_perm.key, &user->shm_perm.key) || | ||
1120 | __get_user(kern->shm_perm.uid, &user->shm_perm.uid) || | ||
1121 | __get_user(kern->shm_perm.gid, &user->shm_perm.gid) || | ||
1122 | __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || | ||
1123 | __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || | ||
1124 | __get_user(kern->shm_segsz, &user->shm_segsz) || | ||
1125 | __get_user(kern->shm_atime, &user->shm_atime) || | ||
1126 | __get_user(kern->shm_dtime, &user->shm_dtime) || | ||
1127 | __get_user(kern->shm_ctime, &user->shm_ctime) || | ||
1128 | __get_user(kern->shm_cpid, &user->shm_cpid) || | ||
1129 | __get_user(kern->shm_lpid, &user->shm_lpid) || | ||
1130 | __get_user(kern->shm_nattch, &user->shm_nattch)) | ||
1131 | return -EFAULT; | ||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1135 | static inline int sunos_shmid_put(struct shmid_ds32 __user *user, | ||
1136 | struct shmid_ds *kern) | ||
1137 | { | ||
1138 | if (put_user(kern->shm_perm.key, &user->shm_perm.key) || | ||
1139 | __put_user(kern->shm_perm.uid, &user->shm_perm.uid) || | ||
1140 | __put_user(kern->shm_perm.gid, &user->shm_perm.gid) || | ||
1141 | __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || | ||
1142 | __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || | ||
1143 | __put_user(kern->shm_segsz, &user->shm_segsz) || | ||
1144 | __put_user(kern->shm_atime, &user->shm_atime) || | ||
1145 | __put_user(kern->shm_dtime, &user->shm_dtime) || | ||
1146 | __put_user(kern->shm_ctime, &user->shm_ctime) || | ||
1147 | __put_user(kern->shm_cpid, &user->shm_cpid) || | ||
1148 | __put_user(kern->shm_lpid, &user->shm_lpid) || | ||
1149 | __put_user(kern->shm_nattch, &user->shm_nattch)) | ||
1150 | return -EFAULT; | ||
1151 | return 0; | ||
1152 | } | ||
1153 | |||
1154 | asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) | ||
1155 | { | ||
1156 | struct shmid_ds ksds; | ||
1157 | unsigned long raddr; | ||
1158 | mm_segment_t old_fs = get_fs(); | ||
1159 | int rval; | ||
1160 | |||
1161 | switch(op) { | ||
1162 | case 0: | ||
1163 | /* do_shmat(): attach a shared memory area */ | ||
1164 | rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr); | ||
1165 | if (!rval) | ||
1166 | rval = (int) raddr; | ||
1167 | break; | ||
1168 | case 1: | ||
1169 | /* sys_shmctl(): modify shared memory area attr. */ | ||
1170 | if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) { | ||
1171 | set_fs(KERNEL_DS); | ||
1172 | rval = sys_shmctl((int) arg1,(int) arg2, | ||
1173 | (struct shmid_ds __user *) &ksds); | ||
1174 | set_fs(old_fs); | ||
1175 | if (!rval) | ||
1176 | rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3, | ||
1177 | &ksds); | ||
1178 | } else | ||
1179 | rval = -EFAULT; | ||
1180 | break; | ||
1181 | case 2: | ||
1182 | /* sys_shmdt(): detach a shared memory area */ | ||
1183 | rval = sys_shmdt((char __user *)(unsigned long)arg1); | ||
1184 | break; | ||
1185 | case 3: | ||
1186 | /* sys_shmget(): get a shared memory area */ | ||
1187 | rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3); | ||
1188 | break; | ||
1189 | default: | ||
1190 | rval = -EINVAL; | ||
1191 | break; | ||
1192 | }; | ||
1193 | return rval; | ||
1194 | } | ||
1195 | |||
1196 | extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode); | ||
1197 | |||
1198 | asmlinkage int sunos_open(u32 fname, int flags, int mode) | ||
1199 | { | ||
1200 | const char __user *filename = compat_ptr(fname); | ||
1201 | |||
1202 | return sparc32_open(filename, flags, mode); | ||
1203 | } | ||
1204 | |||
1205 | #define SUNOS_EWOULDBLOCK 35 | ||
1206 | |||
1207 | /* see the sunos man page read(2v) for an explanation | ||
1208 | of this garbage. We use O_NDELAY to mark | ||
1209 | file descriptors that have been set non-blocking | ||
1210 | using 4.2BSD style calls. (tridge) */ | ||
1211 | |||
1212 | static inline int check_nonblock(int ret, int fd) | ||
1213 | { | ||
1214 | if (ret == -EAGAIN) { | ||
1215 | struct file * file = fget(fd); | ||
1216 | if (file) { | ||
1217 | if (file->f_flags & O_NDELAY) | ||
1218 | ret = -SUNOS_EWOULDBLOCK; | ||
1219 | fput(file); | ||
1220 | } | ||
1221 | } | ||
1222 | return ret; | ||
1223 | } | ||
1224 | |||
1225 | asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count) | ||
1226 | { | ||
1227 | int ret; | ||
1228 | |||
1229 | ret = check_nonblock(sys_read(fd, buf, count), fd); | ||
1230 | return ret; | ||
1231 | } | ||
1232 | |||
1233 | asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count) | ||
1234 | { | ||
1235 | int ret; | ||
1236 | |||
1237 | ret = check_nonblock(compat_sys_readv(fd, vector, count), fd); | ||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1241 | asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count) | ||
1242 | { | ||
1243 | int ret; | ||
1244 | |||
1245 | ret = check_nonblock(sys_write(fd, buf, count), fd); | ||
1246 | return ret; | ||
1247 | } | ||
1248 | |||
1249 | asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count) | ||
1250 | { | ||
1251 | int ret; | ||
1252 | |||
1253 | ret = check_nonblock(compat_sys_writev(fd, vector, count), fd); | ||
1254 | return ret; | ||
1255 | } | ||
1256 | |||
1257 | asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags) | ||
1258 | { | ||
1259 | int ret, fd = (int) __fd; | ||
1260 | |||
1261 | ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags) | ||
1266 | { | ||
1267 | int ret, fd = (int) __fd; | ||
1268 | |||
1269 | ret = check_nonblock(sys_send(fd, buff, len, flags), fd); | ||
1270 | return ret; | ||
1271 | } | ||
1272 | |||
1273 | asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen) | ||
1274 | { | ||
1275 | int ret, fd = (int) __fd; | ||
1276 | |||
1277 | while (1) { | ||
1278 | ret = check_nonblock(sys_accept(fd, sa, addrlen), fd); | ||
1279 | if (ret != -ENETUNREACH && ret != -EHOSTUNREACH) | ||
1280 | break; | ||
1281 | } | ||
1282 | return ret; | ||
1283 | } | ||
1284 | |||
1285 | #define SUNOS_SV_INTERRUPT 2 | ||
1286 | |||
1287 | asmlinkage int sunos_sigaction (int sig, | ||
1288 | struct old_sigaction32 __user *act, | ||
1289 | struct old_sigaction32 __user *oact) | ||
1290 | { | ||
1291 | struct k_sigaction new_ka, old_ka; | ||
1292 | int ret; | ||
1293 | |||
1294 | if (act) { | ||
1295 | compat_old_sigset_t mask; | ||
1296 | u32 u_handler; | ||
1297 | |||
1298 | if (get_user(u_handler, &act->sa_handler) || | ||
1299 | __get_user(new_ka.sa.sa_flags, &act->sa_flags)) | ||
1300 | return -EFAULT; | ||
1301 | new_ka.sa.sa_handler = compat_ptr(u_handler); | ||
1302 | __get_user(mask, &act->sa_mask); | ||
1303 | new_ka.sa.sa_restorer = NULL; | ||
1304 | new_ka.ka_restorer = NULL; | ||
1305 | siginitset(&new_ka.sa.sa_mask, mask); | ||
1306 | new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; | ||
1307 | } | ||
1308 | |||
1309 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
1310 | |||
1311 | if (!ret && oact) { | ||
1312 | old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; | ||
1313 | if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) || | ||
1314 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) | ||
1315 | return -EFAULT; | ||
1316 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
1317 | } | ||
1318 | |||
1319 | return ret; | ||
1320 | } | ||
1321 | |||
1322 | asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname, | ||
1323 | char __user *optval, u32 __optlen) | ||
1324 | { | ||
1325 | int fd = (int) __fd; | ||
1326 | int level = (int) __level; | ||
1327 | int optname = (int) __optname; | ||
1328 | int optlen = (int) __optlen; | ||
1329 | int tr_opt = optname; | ||
1330 | int ret; | ||
1331 | |||
1332 | if (level == SOL_IP) { | ||
1333 | /* Multicast socketopts (ttl, membership) */ | ||
1334 | if (tr_opt >=2 && tr_opt <= 6) | ||
1335 | tr_opt += 30; | ||
1336 | } | ||
1337 | ret = sys_setsockopt(fd, level, tr_opt, | ||
1338 | optval, optlen); | ||
1339 | return ret; | ||
1340 | } | ||
1341 | |||
1342 | asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname, | ||
1343 | char __user *optval, int __user *optlen) | ||
1344 | { | ||
1345 | int fd = (int) __fd; | ||
1346 | int level = (int) __level; | ||
1347 | int optname = (int) __optname; | ||
1348 | int tr_opt = optname; | ||
1349 | int ret; | ||
1350 | |||
1351 | if (level == SOL_IP) { | ||
1352 | /* Multicast socketopts (ttl, membership) */ | ||
1353 | if (tr_opt >=2 && tr_opt <= 6) | ||
1354 | tr_opt += 30; | ||
1355 | } | ||
1356 | ret = compat_sys_getsockopt(fd, level, tr_opt, | ||
1357 | optval, optlen); | ||
1358 | return ret; | ||
1359 | } | ||
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 6b9b718e24af..a4fef2ba1ae1 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
@@ -155,125 +155,3 @@ sys_call_table: | |||
155 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 155 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
156 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 156 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
157 | .word sys_timerfd_settime, sys_timerfd_gettime | 157 | .word sys_timerfd_settime, sys_timerfd_gettime |
158 | |||
159 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | ||
160 | defined(CONFIG_SOLARIS_EMUL_MODULE) | ||
161 | /* Now the 32-bit SunOS syscall table. */ | ||
162 | |||
163 | .align 4 | ||
164 | .globl sunos_sys_table | ||
165 | sunos_sys_table: | ||
166 | /*0*/ .word sunos_indir, sys32_exit, sys_fork | ||
167 | .word sunos_read, sunos_write, sunos_open | ||
168 | .word sys_close, sunos_wait4, sys_creat | ||
169 | .word sys_link, sys_unlink, sunos_execv | ||
170 | .word sys_chdir, sunos_nosys, sys32_mknod | ||
171 | .word sys_chmod, sys32_lchown16, sunos_brk | ||
172 | .word sunos_nosys, sys32_lseek, sunos_getpid | ||
173 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
174 | .word sunos_getuid, sunos_nosys, sys_ptrace | ||
175 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
176 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
177 | .word sys_access, sunos_nosys, sunos_nosys | ||
178 | .word sys_sync, sys_kill, compat_sys_newstat | ||
179 | .word sunos_nosys, compat_sys_newlstat, sys_dup | ||
180 | .word sys_pipe, sunos_nosys, sunos_nosys | ||
181 | .word sunos_nosys, sunos_nosys, sunos_getgid | ||
182 | .word sunos_nosys, sunos_nosys | ||
183 | /*50*/ .word sunos_nosys, sys_acct, sunos_nosys | ||
184 | .word sunos_mctl, sunos_ioctl, sys_reboot | ||
185 | .word sunos_nosys, sys_symlink, sys_readlink | ||
186 | .word sys32_execve, sys_umask, sys_chroot | ||
187 | .word compat_sys_newfstat, sunos_nosys, sys_getpagesize | ||
188 | .word sys_msync, sys_vfork, sunos_nosys | ||
189 | .word sunos_nosys, sunos_sbrk, sunos_sstk | ||
190 | .word sunos_mmap, sunos_vadvise, sys_munmap | ||
191 | .word sys_mprotect, sys_madvise, sys_vhangup | ||
192 | .word sunos_nosys, sys_mincore, sys32_getgroups16 | ||
193 | .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp | ||
194 | .word compat_sys_setitimer, sunos_nosys, sys_swapon | ||
195 | .word compat_sys_getitimer, sys_gethostname, sys_sethostname | ||
196 | .word sunos_getdtablesize, sys_dup2, sunos_nop | ||
197 | .word compat_sys_fcntl, sunos_select, sunos_nop | ||
198 | .word sys_fsync, sys32_setpriority, sys32_socket | ||
199 | .word sys32_connect, sunos_accept | ||
200 | /*100*/ .word sys_getpriority, sunos_send, sunos_recv | ||
201 | .word sunos_nosys, sys32_bind, sunos_setsockopt | ||
202 | .word sys32_listen, sunos_nosys, sunos_sigaction | ||
203 | .word sunos_sigblock, sunos_sigsetmask, sys_sigpause | ||
204 | .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg | ||
205 | .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage | ||
206 | .word sunos_getsockopt, sunos_nosys, sunos_readv | ||
207 | .word sunos_writev, sys32_settimeofday, sys32_fchown16 | ||
208 | .word sys_fchmod, sys32_recvfrom, sys32_setreuid16 | ||
209 | .word sys32_setregid16, sys_rename, sys_truncate | ||
210 | .word sys_ftruncate, sys_flock, sunos_nosys | ||
211 | .word sys32_sendto, sys32_shutdown, sys32_socketpair | ||
212 | .word sys_mkdir, sys_rmdir, sys32_utimes | ||
213 | .word sys32_sigreturn, sunos_nosys, sys32_getpeername | ||
214 | .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit | ||
215 | .word compat_sys_setrlimit, sunos_killpg, sunos_nosys | ||
216 | .word sunos_nosys, sunos_nosys | ||
217 | /*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys | ||
218 | .word sys_poll, sunos_nosys, sunos_nosys | ||
219 | .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs | ||
220 | .word sys_oldumount, sunos_nosys, sunos_nosys | ||
221 | .word sys_getdomainname, sys_setdomainname | ||
222 | .word sunos_nosys, sys_quotactl, sunos_nosys | ||
223 | .word sunos_nosys, sys_ustat, sunos_semsys | ||
224 | .word sunos_nosys, sunos_shmsys, sunos_audit | ||
225 | .word sunos_nosys, sunos_getdents, sys_setsid | ||
226 | .word sys_fchdir, sunos_nosys, sunos_nosys | ||
227 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
228 | .word sunos_nosys, compat_sys_sigpending, sunos_nosys | ||
229 | .word sys_setpgid, sunos_pathconf, sunos_fpathconf | ||
230 | .word sunos_sysconf, sunos_uname, sunos_nosys | ||
231 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
232 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
233 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
234 | /*200*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
235 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
236 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
237 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
238 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
239 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
240 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
241 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
242 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
243 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
244 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
245 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
246 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
247 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
248 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
249 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
250 | .word sunos_nosys, sunos_nosys | ||
251 | /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
252 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
253 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
254 | .word sunos_nosys | ||
255 | /*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
256 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
257 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
258 | .word sunos_nosys | ||
259 | /*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
260 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
261 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
262 | .word sunos_nosys | ||
263 | /*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
264 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
265 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
266 | .word sunos_nosys | ||
267 | /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
268 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
269 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
270 | .word sunos_nosys | ||
271 | /*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
272 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
273 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
274 | .word sunos_nosys | ||
275 | /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys | ||
276 | .word sunos_nosys, sunos_nosys, sunos_nosys | ||
277 | .word sunos_nosys | ||
278 | |||
279 | #endif | ||
diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h index 8a0d20a35d0c..bc9f5dac4069 100644 --- a/arch/sparc64/kernel/systbls.h +++ b/arch/sparc64/kernel/systbls.h | |||
@@ -27,8 +27,6 @@ extern asmlinkage unsigned long sys64_mremap(unsigned long addr, | |||
27 | unsigned long new_addr); | 27 | unsigned long new_addr); |
28 | extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); | 28 | extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); |
29 | extern asmlinkage long sys_getdomainname(char __user *name, int len); | 29 | extern asmlinkage long sys_getdomainname(char __user *name, int len); |
30 | extern asmlinkage long solaris_syscall(struct pt_regs *regs); | ||
31 | extern asmlinkage long sunos_syscall(struct pt_regs *regs); | ||
32 | extern asmlinkage long sys_utrap_install(utrap_entry_t type, | 30 | extern asmlinkage long sys_utrap_install(utrap_entry_t type, |
33 | utrap_handler_t new_p, | 31 | utrap_handler_t new_p, |
34 | utrap_handler_t new_d, | 32 | utrap_handler_t new_d, |
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 7575aa371da8..b0de4c00b11a 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S | |||
@@ -117,16 +117,13 @@ tl0_f4o: FILL_4_OTHER | |||
117 | tl0_f5o: FILL_5_OTHER | 117 | tl0_f5o: FILL_5_OTHER |
118 | tl0_f6o: FILL_6_OTHER | 118 | tl0_f6o: FILL_6_OTHER |
119 | tl0_f7o: FILL_7_OTHER | 119 | tl0_f7o: FILL_7_OTHER |
120 | tl0_sunos: SUNOS_SYSCALL_TRAP | 120 | tl0_resv100: BTRAP(0x100) |
121 | tl0_bkpt: BREAKPOINT_TRAP | 121 | tl0_bkpt: BREAKPOINT_TRAP |
122 | tl0_divz: TRAP(do_div0) | 122 | tl0_divz: TRAP(do_div0) |
123 | tl0_flushw: FLUSH_WINDOW_TRAP | 123 | tl0_flushw: FLUSH_WINDOW_TRAP |
124 | tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) | 124 | tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) BTRAP(0x108) |
125 | .globl tl0_solaris | 125 | tl0_resv109: BTRAP(0x109) BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) |
126 | tl0_solaris: SOLARIS_SYSCALL_TRAP | 126 | tl0_resv10e: BTRAP(0x10e) BTRAP(0x10f) |
127 | tl0_resv109: BTRAP(0x109) | ||
128 | tl0_resv10a: BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e) | ||
129 | tl0_resv10f: BTRAP(0x10f) | ||
130 | tl0_linux32: LINUX_32BIT_SYSCALL_TRAP | 127 | tl0_linux32: LINUX_32BIT_SYSCALL_TRAP |
131 | tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP | 128 | tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP |
132 | tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113) | 129 | tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113) |
@@ -139,8 +136,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC | |||
139 | tl0_getcc: GETCC_TRAP | 136 | tl0_getcc: GETCC_TRAP |
140 | tl0_setcc: SETCC_TRAP | 137 | tl0_setcc: SETCC_TRAP |
141 | tl0_getpsr: TRAP(do_getpsr) | 138 | tl0_getpsr: TRAP(do_getpsr) |
142 | tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) | 139 | tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127) |
143 | tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156) | ||
144 | tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) | 140 | tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) |
145 | tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) | 141 | tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) |
146 | tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) | 142 | tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) |