1 /* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
2 * misc.c: Miscellaneous syscall emulation for Solaris
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/types.h>
10 #include <linux/smp_lock.h>
11 #include <linux/utsname.h>
12 #include <linux/limits.h>
14 #include <linux/smp.h>
15 #include <linux/mman.h>
16 #include <linux/file.h>
17 #include <linux/timex.h>
18 #include <linux/major.h>
19 #include <linux/compat.h>
21 #include <asm/uaccess.h>
22 #include <asm/string.h>
23 #include <asm/oplib.h>
24 #include <asm/idprom.h>
29 /* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
30 Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
31 ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
32 equivalents. I return EINVAL in that case, which is very wrong. If
33 someone suggest a better value for them, you're welcomed.
34 On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
35 but that doesn't matter here. --jj */
36 int solaris_err_table
[] = {
37 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
38 /* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
39 /* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
40 /* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
41 /* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
42 /* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
43 /* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
44 /* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
45 /* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
46 /* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
47 /* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
48 /* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
49 /* 120 */ 22, 22, 88, 86, 85, 22, 22,
52 #define SOLARIS_NR_OPEN 256
54 static u32
do_solaris_mmap(u32 addr
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u64 off
)
56 struct file
*file
= NULL
;
57 unsigned long retval
, ret_type
;
59 /* Do we need it here? */
60 set_personality(PER_SVR4
);
61 if (flags
& MAP_NORESERVE
) {
65 printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n",
69 flags
&= ~MAP_NORESERVE
;
72 if(!(flags
& MAP_ANONYMOUS
)) {
73 if(fd
>= SOLARIS_NR_OPEN
)
79 struct inode
* inode
= file
->f_dentry
->d_inode
;
80 if(imajor(inode
) == MEM_MAJOR
&&
82 flags
|= MAP_ANONYMOUS
;
90 len
= PAGE_ALIGN(len
);
91 if(!(flags
& MAP_FIXED
))
93 else if (len
> 0xf0000000UL
|| addr
> 0xf0000000UL
- len
)
95 ret_type
= flags
& _MAP_NEW
;
98 down_write(¤t
->mm
->mmap_sem
);
99 flags
&= ~(MAP_EXECUTABLE
| MAP_DENYWRITE
);
100 retval
= do_mmap(file
,
101 (unsigned long) addr
, (unsigned long) len
,
102 (unsigned long) prot
, (unsigned long) flags
, off
);
103 up_write(¤t
->mm
->mmap_sem
);
105 retval
= ((retval
< 0xf0000000) ? 0 : retval
);
114 asmlinkage u32
solaris_mmap(u32 addr
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u32 off
)
116 return do_solaris_mmap(addr
, len
, prot
, flags
, fd
, (u64
) off
);
119 asmlinkage u32
solaris_mmap64(struct pt_regs
*regs
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u32 offhi
)
123 if (regs
->u_regs
[UREG_G1
]) {
124 if (get_user (offlo
, (u32 __user
*)(long)((u32
)regs
->u_regs
[UREG_I6
] + 0x5c)))
127 if (get_user (offlo
, (u32 __user
*)(long)((u32
)regs
->u_regs
[UREG_I6
] + 0x60)))
130 return do_solaris_mmap((u32
)regs
->u_regs
[UREG_I0
], len
, prot
, flags
, fd
, (((u64
)offhi
)<<32)|offlo
);
133 asmlinkage
int solaris_brk(u32 brk
)
135 int (*sunos_brk
)(u32
) = (int (*)(u32
))SUNOS(17);
137 return sunos_brk(brk
);
140 static int __set_utsfield(char __user
*to
, int to_size
,
141 const char *from
, int from_size
,
142 int dotchop
, int countfrom
)
144 int len
= countfrom
? (to_size
> from_size
?
145 from_size
: to_size
) : to_size
;
148 if (copy_to_user(to
, from
, len
))
151 off
= len
< to_size
? len
: len
- 1;
153 const char *p
= strnchr(from
, len
, '.');
154 if (p
) off
= p
- from
;
157 if (__put_user('\0', to
+ off
))
163 #define set_utsfield(to, from, dotchop, countfrom) \
164 __set_utsfield((to), sizeof(to), \
165 (from), sizeof(from), \
166 (dotchop), (countfrom))
184 static char *machine(void)
186 switch (sparc_cpu_model
) {
187 case sun4
: return "sun4";
188 case sun4c
: return "sun4c";
189 case sun4e
: return "sun4e";
190 case sun4m
: return "sun4m";
191 case sun4d
: return "sun4d";
192 case sun4u
: return "sun4u";
193 default: return "sparc";
197 static char *platform(char *buffer
)
202 len
= prom_getproperty(prom_root_node
, "name", buffer
, 256);
208 for (p
= buffer
; *p
; p
++)
209 if (*p
== '/' || *p
== ' ') *p
= '_';
216 static char *serial(char *buffer
)
218 int node
= prom_getchild(prom_root_node
);
221 node
= prom_searchsiblings(node
, "options");
223 len
= prom_getproperty(node
, "system-board-serial#", buffer
, 256);
227 return "4512348717234";
232 asmlinkage
int solaris_utssys(u32 buf
, u32 flags
, int which
, u32 buf2
)
234 struct sol_uname __user
*v
= A(buf
);
238 case 0: /* old uname */
240 err
= set_utsfield(v
->sysname
, "SunOS", 1, 0);
242 err
|= set_utsfield(v
->nodename
, system_utsname
.nodename
,
245 err
|= set_utsfield(v
->release
, "2.6", 0, 0);
246 err
|= set_utsfield(v
->version
, "Generic", 0, 0);
247 err
|= set_utsfield(v
->machine
, machine(), 0, 0);
248 return (err
? -EFAULT
: 0);
258 asmlinkage
int solaris_utsname(u32 buf
)
260 struct sol_utsname __user
*v
= A(buf
);
263 /* Why should we not lie a bit? */
265 err
= set_utsfield(v
->sysname
, "SunOS", 0, 0);
266 err
|= set_utsfield(v
->nodename
, system_utsname
.nodename
, 1, 1);
267 err
|= set_utsfield(v
->release
, "5.6", 0, 0);
268 err
|= set_utsfield(v
->version
, "Generic", 0, 0);
269 err
|= set_utsfield(v
->machine
, machine(), 0, 0);
272 return (err
? -EFAULT
: 0);
275 #define SI_SYSNAME 1 /* return name of operating system */
276 #define SI_HOSTNAME 2 /* return name of node */
277 #define SI_RELEASE 3 /* return release of operating system */
278 #define SI_VERSION 4 /* return version field of utsname */
279 #define SI_MACHINE 5 /* return kind of machine */
280 #define SI_ARCHITECTURE 6 /* return instruction set arch */
281 #define SI_HW_SERIAL 7 /* return hardware serial number */
282 #define SI_HW_PROVIDER 8 /* return hardware manufacturer */
283 #define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
284 #define SI_PLATFORM 513 /* return platform identifier */
286 asmlinkage
int solaris_sysinfo(int cmd
, u32 buf
, s32 count
)
292 /* Again, we cheat :)) */
294 case SI_SYSNAME
: r
= "SunOS"; break;
298 for (p
= system_utsname
.nodename
, q
= buffer
;
299 q
< r
&& *p
&& *p
!= '.'; *q
++ = *p
++);
304 case SI_RELEASE
: r
= "5.6"; break;
305 case SI_MACHINE
: r
= machine(); break;
306 case SI_ARCHITECTURE
: r
= "sparc"; break;
307 case SI_HW_PROVIDER
: r
= "Sun_Microsystems"; break;
308 case SI_HW_SERIAL
: r
= serial(buffer
); break;
309 case SI_PLATFORM
: r
= platform(buffer
); break;
310 case SI_SRPC_DOMAIN
: r
= ""; break;
311 case SI_VERSION
: r
= "Generic"; break;
312 default: return -EINVAL
;
316 if (copy_to_user(A(buf
), r
, count
- 1) ||
317 __put_user(0, (char __user
*)A(buf
) + count
- 1))
320 if (copy_to_user(A(buf
), r
, len
))
326 #define SOLARIS_CONFIG_NGROUPS 2
327 #define SOLARIS_CONFIG_CHILD_MAX 3
328 #define SOLARIS_CONFIG_OPEN_FILES 4
329 #define SOLARIS_CONFIG_POSIX_VER 5
330 #define SOLARIS_CONFIG_PAGESIZE 6
331 #define SOLARIS_CONFIG_CLK_TCK 7
332 #define SOLARIS_CONFIG_XOPEN_VER 8
333 #define SOLARIS_CONFIG_PROF_TCK 10
334 #define SOLARIS_CONFIG_NPROC_CONF 11
335 #define SOLARIS_CONFIG_NPROC_ONLN 12
336 #define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
337 #define SOLARIS_CONFIG_AIO_MAX 14
338 #define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
339 #define SOLARIS_CONFIG_DELAYTIMER_MAX 16
340 #define SOLARIS_CONFIG_MQ_OPEN_MAX 17
341 #define SOLARIS_CONFIG_MQ_PRIO_MAX 18
342 #define SOLARIS_CONFIG_RTSIG_MAX 19
343 #define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
344 #define SOLARIS_CONFIG_SEM_VALUE_MAX 21
345 #define SOLARIS_CONFIG_SIGQUEUE_MAX 22
346 #define SOLARIS_CONFIG_SIGRT_MIN 23
347 #define SOLARIS_CONFIG_SIGRT_MAX 24
348 #define SOLARIS_CONFIG_TIMER_MAX 25
349 #define SOLARIS_CONFIG_PHYS_PAGES 26
350 #define SOLARIS_CONFIG_AVPHYS_PAGES 27
352 asmlinkage
int solaris_sysconf(int id
)
355 case SOLARIS_CONFIG_NGROUPS
: return NGROUPS_MAX
;
356 case SOLARIS_CONFIG_CHILD_MAX
: return CHILD_MAX
;
357 case SOLARIS_CONFIG_OPEN_FILES
: return OPEN_MAX
;
358 case SOLARIS_CONFIG_POSIX_VER
: return 199309;
359 case SOLARIS_CONFIG_PAGESIZE
: return PAGE_SIZE
;
360 case SOLARIS_CONFIG_XOPEN_VER
: return 3;
361 case SOLARIS_CONFIG_CLK_TCK
:
362 case SOLARIS_CONFIG_PROF_TCK
:
363 return sparc64_get_clock_tick(smp_processor_id());
365 case SOLARIS_CONFIG_NPROC_CONF
: return NR_CPUS
;
366 case SOLARIS_CONFIG_NPROC_ONLN
: return num_online_cpus();
368 case SOLARIS_CONFIG_NPROC_CONF
: return 1;
369 case SOLARIS_CONFIG_NPROC_ONLN
: return 1;
371 case SOLARIS_CONFIG_SIGRT_MIN
: return 37;
372 case SOLARIS_CONFIG_SIGRT_MAX
: return 44;
373 case SOLARIS_CONFIG_PHYS_PAGES
:
374 case SOLARIS_CONFIG_AVPHYS_PAGES
:
379 if (id
== SOLARIS_CONFIG_PHYS_PAGES
)
380 return s
.totalram
>>= PAGE_SHIFT
;
382 return s
.freeram
>>= PAGE_SHIFT
;
384 /* XXX support these as well -jj */
385 case SOLARIS_CONFIG_AIO_LISTIO_MAX
: return -EINVAL
;
386 case SOLARIS_CONFIG_AIO_MAX
: return -EINVAL
;
387 case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX
: return -EINVAL
;
388 case SOLARIS_CONFIG_DELAYTIMER_MAX
: return -EINVAL
;
389 case SOLARIS_CONFIG_MQ_OPEN_MAX
: return -EINVAL
;
390 case SOLARIS_CONFIG_MQ_PRIO_MAX
: return -EINVAL
;
391 case SOLARIS_CONFIG_RTSIG_MAX
: return -EINVAL
;
392 case SOLARIS_CONFIG_SEM_NSEMS_MAX
: return -EINVAL
;
393 case SOLARIS_CONFIG_SEM_VALUE_MAX
: return -EINVAL
;
394 case SOLARIS_CONFIG_SIGQUEUE_MAX
: return -EINVAL
;
395 case SOLARIS_CONFIG_TIMER_MAX
: return -EINVAL
;
396 default: return -EINVAL
;
400 asmlinkage
int solaris_procids(int cmd
, s32 pid
, s32 pgid
)
405 case 0: /* getpgrp */
406 return process_group(current
);
407 case 1: /* setpgrp */
409 int (*sys_setpgid
)(pid_t
,pid_t
) =
410 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
412 /* can anyone explain me the difference between
413 Solaris setpgrp and setsid? */
414 ret
= sys_setpgid(0, 0);
416 current
->signal
->tty
= NULL
;
417 return process_group(current
);
421 int (*sys_getsid
)(pid_t
) = (int (*)(pid_t
))SYS(getsid
);
422 return sys_getsid(pid
);
426 int (*sys_setsid
)(void) = (int (*)(void))SYS(setsid
);
429 case 4: /* getpgid */
431 int (*sys_getpgid
)(pid_t
) = (int (*)(pid_t
))SYS(getpgid
);
432 return sys_getpgid(pid
);
434 case 5: /* setpgid */
436 int (*sys_setpgid
)(pid_t
,pid_t
) =
437 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
438 return sys_setpgid(pid
,pgid
);
444 asmlinkage
int solaris_gettimeofday(u32 tim
)
446 int (*sys_gettimeofday
)(struct timeval
*, struct timezone
*) =
447 (int (*)(struct timeval
*, struct timezone
*))SYS(gettimeofday
);
449 return sys_gettimeofday((struct timeval
*)(u64
)tim
, NULL
);
452 #define RLIM_SOL_INFINITY32 0x7fffffff
453 #define RLIM_SOL_SAVED_MAX32 0x7ffffffe
454 #define RLIM_SOL_SAVED_CUR32 0x7ffffffd
455 #define RLIM_SOL_INFINITY ((u64)-3)
456 #define RLIM_SOL_SAVED_MAX ((u64)-2)
457 #define RLIM_SOL_SAVED_CUR ((u64)-1)
458 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
459 #define RLIMIT_SOL_NOFILE 5
460 #define RLIMIT_SOL_VMEM 6
467 asmlinkage
int solaris_getrlimit(unsigned int resource
, struct rlimit32 __user
*rlim
)
471 mm_segment_t old_fs
= get_fs ();
472 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
473 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
475 if (resource
> RLIMIT_SOL_VMEM
)
478 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
479 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
483 ret
= sys_getrlimit(resource
, &r
);
486 if (r
.rlim_cur
== RLIM_INFINITY
)
487 r
.rlim_cur
= RLIM_SOL_INFINITY32
;
488 else if ((u64
)r
.rlim_cur
> RLIM_SOL_INFINITY32
)
489 r
.rlim_cur
= RLIM_SOL_SAVED_CUR32
;
490 if (r
.rlim_max
== RLIM_INFINITY
)
491 r
.rlim_max
= RLIM_SOL_INFINITY32
;
492 else if ((u64
)r
.rlim_max
> RLIM_SOL_INFINITY32
)
493 r
.rlim_max
= RLIM_SOL_SAVED_MAX32
;
494 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
495 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
500 asmlinkage
int solaris_setrlimit(unsigned int resource
, struct rlimit32 __user
*rlim
)
502 struct rlimit r
, rold
;
504 mm_segment_t old_fs
= get_fs ();
505 int (*sys_getrlimit
)(unsigned int, struct rlimit __user
*) =
506 (int (*)(unsigned int, struct rlimit __user
*))SYS(getrlimit
);
507 int (*sys_setrlimit
)(unsigned int, struct rlimit __user
*) =
508 (int (*)(unsigned int, struct rlimit __user
*))SYS(setrlimit
);
510 if (resource
> RLIMIT_SOL_VMEM
)
513 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
514 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
517 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
518 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
521 ret
= sys_getrlimit(resource
, &rold
);
523 if (r
.rlim_cur
== RLIM_SOL_INFINITY32
)
524 r
.rlim_cur
= RLIM_INFINITY
;
525 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR32
)
526 r
.rlim_cur
= rold
.rlim_cur
;
527 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX32
)
528 r
.rlim_cur
= rold
.rlim_max
;
529 if (r
.rlim_max
== RLIM_SOL_INFINITY32
)
530 r
.rlim_max
= RLIM_INFINITY
;
531 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR32
)
532 r
.rlim_max
= rold
.rlim_cur
;
533 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX32
)
534 r
.rlim_max
= rold
.rlim_max
;
535 ret
= sys_setrlimit(resource
, &r
);
541 asmlinkage
int solaris_getrlimit64(unsigned int resource
, struct rlimit __user
*rlim
)
545 mm_segment_t old_fs
= get_fs ();
546 int (*sys_getrlimit
)(unsigned int, struct rlimit __user
*) =
547 (int (*)(unsigned int, struct rlimit __user
*))SYS(getrlimit
);
549 if (resource
> RLIMIT_SOL_VMEM
)
552 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
553 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
557 ret
= sys_getrlimit(resource
, &r
);
560 if (r
.rlim_cur
== RLIM_INFINITY
)
561 r
.rlim_cur
= RLIM_SOL_INFINITY
;
562 if (r
.rlim_max
== RLIM_INFINITY
)
563 r
.rlim_max
= RLIM_SOL_INFINITY
;
564 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
565 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
570 asmlinkage
int solaris_setrlimit64(unsigned int resource
, struct rlimit __user
*rlim
)
572 struct rlimit r
, rold
;
574 mm_segment_t old_fs
= get_fs ();
575 int (*sys_getrlimit
)(unsigned int, struct rlimit __user
*) =
576 (int (*)(unsigned int, struct rlimit __user
*))SYS(getrlimit
);
577 int (*sys_setrlimit
)(unsigned int, struct rlimit __user
*) =
578 (int (*)(unsigned int, struct rlimit __user
*))SYS(setrlimit
);
580 if (resource
> RLIMIT_SOL_VMEM
)
583 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
584 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
587 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
588 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
591 ret
= sys_getrlimit(resource
, &rold
);
593 if (r
.rlim_cur
== RLIM_SOL_INFINITY
)
594 r
.rlim_cur
= RLIM_INFINITY
;
595 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR
)
596 r
.rlim_cur
= rold
.rlim_cur
;
597 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX
)
598 r
.rlim_cur
= rold
.rlim_max
;
599 if (r
.rlim_max
== RLIM_SOL_INFINITY
)
600 r
.rlim_max
= RLIM_INFINITY
;
601 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR
)
602 r
.rlim_max
= rold
.rlim_cur
;
603 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX
)
604 r
.rlim_max
= rold
.rlim_max
;
605 ret
= sys_setrlimit(resource
, &r
);
611 struct sol_ntptimeval
{
612 struct compat_timeval time
;
637 asmlinkage
int solaris_ntp_gettime(struct sol_ntptimeval __user
*ntp
)
639 int (*sys_adjtimex
)(struct timex __user
*) =
640 (int (*)(struct timex __user
*))SYS(adjtimex
);
643 mm_segment_t old_fs
= get_fs();
647 ret
= sys_adjtimex(&t
);
651 ret
= put_user (t
.time
.tv_sec
, &ntp
->time
.tv_sec
);
652 ret
|= __put_user (t
.time
.tv_usec
, &ntp
->time
.tv_usec
);
653 ret
|= __put_user (t
.maxerror
, &ntp
->maxerror
);
654 ret
|= __put_user (t
.esterror
, &ntp
->esterror
);
658 asmlinkage
int solaris_ntp_adjtime(struct sol_timex __user
*txp
)
660 int (*sys_adjtimex
)(struct timex __user
*) =
661 (int (*)(struct timex __user
*))SYS(adjtimex
);
664 mm_segment_t old_fs
= get_fs();
666 ret
= get_user (t
.modes
, &txp
->modes
);
667 ret
|= __get_user (t
.offset
, &txp
->offset
);
668 ret
|= __get_user (t
.freq
, &txp
->freq
);
669 ret
|= __get_user (t
.maxerror
, &txp
->maxerror
);
670 ret
|= __get_user (t
.esterror
, &txp
->esterror
);
671 ret
|= __get_user (t
.status
, &txp
->status
);
672 ret
|= __get_user (t
.constant
, &txp
->constant
);
674 ret
= sys_adjtimex(&t
);
678 err
= put_user (t
.offset
, &txp
->offset
);
679 err
|= __put_user (t
.freq
, &txp
->freq
);
680 err
|= __put_user (t
.maxerror
, &txp
->maxerror
);
681 err
|= __put_user (t
.esterror
, &txp
->esterror
);
682 err
|= __put_user (t
.status
, &txp
->status
);
683 err
|= __put_user (t
.constant
, &txp
->constant
);
684 err
|= __put_user (t
.precision
, &txp
->precision
);
685 err
|= __put_user (t
.tolerance
, &txp
->tolerance
);
686 err
|= __put_user (t
.ppsfreq
, &txp
->ppsfreq
);
687 err
|= __put_user (t
.jitter
, &txp
->jitter
);
688 err
|= __put_user (t
.shift
, &txp
->shift
);
689 err
|= __put_user (t
.stabil
, &txp
->stabil
);
690 err
|= __put_user (t
.jitcnt
, &txp
->jitcnt
);
691 err
|= __put_user (t
.calcnt
, &txp
->calcnt
);
692 err
|= __put_user (t
.errcnt
, &txp
->errcnt
);
693 err
|= __put_user (t
.stbcnt
, &txp
->stbcnt
);
699 asmlinkage
int do_sol_unimplemented(struct pt_regs
*regs
)
701 printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
702 (int)regs
->u_regs
[UREG_G1
],
703 (int)regs
->u_regs
[UREG_I0
],
704 (int)regs
->u_regs
[UREG_I1
],
705 (int)regs
->u_regs
[UREG_I2
],
706 (int)regs
->u_regs
[UREG_I3
]);
710 asmlinkage
void solaris_register(void)
712 set_personality(PER_SVR4
);
715 extern long solaris_to_linux_signals
[], linux_to_solaris_signals
[];
717 struct exec_domain solaris_exec_domain
= {
720 .pers_low
= 1, /* PER_SVR4 personality */
722 .signal_map
= solaris_to_linux_signals
,
723 .signal_invmap
=linux_to_solaris_signals
,
724 .module
= THIS_MODULE
,
728 extern int init_socksys(void);
732 MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
733 MODULE_DESCRIPTION("Solaris binary emulation module");
734 MODULE_LICENSE("GPL");
737 extern u32 tl0_solaris
[8];
738 #define update_ttable(x) \
739 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
740 __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
744 extern u32 solaris_sparc_syscall
[];
745 extern u32 solaris_syscall
[];
746 extern void cleanup_socksys(void);
748 extern u32 entry64_personality_patch
;
750 int init_module(void)
754 SOLDD(("Solaris module at %p\n", solaris_sparc_syscall
));
755 register_exec_domain(&solaris_exec_domain
);
756 if ((ret
= init_socksys())) {
757 unregister_exec_domain(&solaris_exec_domain
);
760 update_ttable(solaris_sparc_syscall
);
761 entry64_personality_patch
|=
762 (offsetof(struct task_struct
, personality
) +
763 (sizeof(unsigned long) - 1));
764 __asm__
__volatile__("membar #StoreStore; flush %0"
765 : : "r" (&entry64_personality_patch
));
769 void cleanup_module(void)
771 update_ttable(solaris_syscall
);
773 unregister_exec_domain(&solaris_exec_domain
);
777 int init_solaris_emul(void)
779 register_exec_domain(&solaris_exec_domain
);