1 /* $Id: misc.c,v 1.22 2000/02/16 07:31:41 davem Exp $
2 * misc.c: Miscelaneous syscall emulation for Solaris
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7 #include <linux/module.h>
8 #include <linux/types.h>
9 #include <linux/smp_lock.h>
10 #include <linux/utsname.h>
11 #include <linux/limits.h>
13 #include <linux/smp.h>
14 #include <linux/mman.h>
15 #include <linux/file.h>
16 #include <linux/timex.h>
18 #include <asm/uaccess.h>
19 #include <asm/string.h>
20 #include <asm/oplib.h>
21 #include <asm/idprom.h>
22 #include <asm/machines.h>
26 /* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
27 Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
28 ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
29 equivalents. I return EINVAL in that case, which is very wrong. If
30 someone suggest a better value for them, you're welcomed.
31 On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
32 but that doesn't matter here. --jj */
33 int solaris_err_table
[] = {
34 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
35 /* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
36 /* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
37 /* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
38 /* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
39 /* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
40 /* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
41 /* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
42 /* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
43 /* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
44 /* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
45 /* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
46 /* 120 */ 22, 22, 88, 86, 85, 22, 22,
49 #define SOLARIS_NR_OPEN 256
51 static u32
do_solaris_mmap(u32 addr
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u64 off
)
53 struct file
*file
= NULL
;
54 unsigned long retval
, ret_type
;
57 current
->personality
|= PER_SVR4
;
58 if (flags
& MAP_NORESERVE
) {
62 printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n",
66 flags
&= ~MAP_NORESERVE
;
69 if(!(flags
& MAP_ANONYMOUS
)) {
70 if(fd
>= SOLARIS_NR_OPEN
)
75 if (file
->f_dentry
&& file
->f_dentry
->d_inode
) {
76 struct inode
* inode
= file
->f_dentry
->d_inode
;
77 if(MAJOR(inode
->i_rdev
) == MEM_MAJOR
&&
78 MINOR(inode
->i_rdev
) == 5) {
79 flags
|= MAP_ANONYMOUS
;
87 len
= PAGE_ALIGN(len
);
88 if(!(flags
& MAP_FIXED
))
90 else if (len
> 0xf0000000UL
|| addr
> 0xf0000000UL
- len
)
92 ret_type
= flags
& _MAP_NEW
;
95 down(¤t
->mm
->mmap_sem
);
96 flags
&= ~(MAP_EXECUTABLE
| MAP_DENYWRITE
);
97 retval
= do_mmap(file
,
98 (unsigned long) addr
, (unsigned long) len
,
99 (unsigned long) prot
, (unsigned long) flags
, off
);
100 up(¤t
->mm
->mmap_sem
);
102 retval
= ((retval
< 0xf0000000) ? 0 : retval
);
112 asmlinkage u32
solaris_mmap(u32 addr
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u32 off
)
114 return do_solaris_mmap(addr
, len
, prot
, flags
, fd
, (u64
) off
);
117 asmlinkage u32
solaris_mmap64(struct pt_regs
*regs
, u32 len
, u32 prot
, u32 flags
, u32 fd
, u32 offhi
)
121 if (regs
->u_regs
[UREG_G1
]) {
122 if (get_user (offlo
, (u32
*)(long)((u32
)regs
->u_regs
[UREG_I6
] + 0x5c)))
125 if (get_user (offlo
, (u32
*)(long)((u32
)regs
->u_regs
[UREG_I6
] + 0x60)))
128 return do_solaris_mmap((u32
)regs
->u_regs
[UREG_I0
], len
, prot
, flags
, fd
, (((u64
)offhi
)<<32)|offlo
);
131 asmlinkage
int solaris_brk(u32 brk
)
133 int (*sunos_brk
)(u32
) = (int (*)(u32
))SUNOS(17);
135 return sunos_brk(brk
);
138 #define set_utsfield(to, from, dotchop, countfrom) { \
140 int i, len = (countfrom) ? \
141 ((sizeof(to) > sizeof(from) ? \
142 sizeof(from) : sizeof(to))) : sizeof(to); \
143 copy_to_user_ret(to, from, len, -EFAULT); \
145 for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
148 __put_user_ret('\0', (char *)(to+i), -EFAULT); \
167 static char *machine(void)
169 switch (sparc_cpu_model
) {
170 case sun4
: return "sun4";
171 case sun4c
: return "sun4c";
172 case sun4e
: return "sun4e";
173 case sun4m
: return "sun4m";
174 case sun4d
: return "sun4d";
175 case sun4u
: return "sun4u";
176 default: return "sparc";
180 static char *platform(char *buffer
)
187 { "sun4", (SM_SUN4
| SM_4_110
) },
188 { "sun4", (SM_SUN4
| SM_4_260
) },
189 { "sun4", (SM_SUN4
| SM_4_330
) },
190 { "sun4", (SM_SUN4
| SM_4_470
) },
191 { "SUNW,Sun_4_60", (SM_SUN4C
| SM_4C_SS1
) },
192 { "SUNW,Sun_4_40", (SM_SUN4C
| SM_4C_IPC
) },
193 { "SUNW,Sun_4_65", (SM_SUN4C
| SM_4C_SS1PLUS
) },
194 { "SUNW,Sun_4_20", (SM_SUN4C
| SM_4C_SLC
) },
195 { "SUNW,Sun_4_75", (SM_SUN4C
| SM_4C_SS2
) },
196 { "SUNW,Sun_4_25", (SM_SUN4C
| SM_4C_ELC
) },
197 { "SUNW,Sun_4_50", (SM_SUN4C
| SM_4C_IPX
) },
198 { "SUNW,Sun_4_600", (SM_SUN4M
| SM_4M_SS60
) },
199 { "SUNW,SPARCstation-5", (SM_SUN4M
| SM_4M_SS50
) },
200 { "SUNW,SPARCstation-20", (SM_SUN4M
| SM_4M_SS40
) }
204 len
= prom_getproperty(prom_root_node
, "name", buffer
, 256);
210 for (p
= buffer
; *p
; p
++)
211 if (*p
== '/' || *p
== ' ') *p
= '_';
214 for (i
= 0; i
< sizeof (platforms
)/sizeof (platforms
[0]); i
++)
215 if (platforms
[i
].id_machtype
== idprom
->id_machtype
)
216 return platforms
[i
].platform
;
220 static char *serial(char *buffer
)
222 int node
= prom_getchild(prom_root_node
);
225 node
= prom_searchsiblings(node
, "options");
227 len
= prom_getproperty(node
, "system-board-serial#", buffer
, 256);
231 return "4512348717234";
236 asmlinkage
int solaris_utssys(u32 buf
, u32 flags
, int which
, u32 buf2
)
239 case 0: /* old uname */
241 set_utsfield(((struct sol_uname
*)A(buf
))->sysname
,
244 set_utsfield(((struct sol_uname
*)A(buf
))->nodename
,
245 system_utsname
.nodename
, 1, 1);
247 set_utsfield(((struct sol_uname
*)A(buf
))->release
,
249 set_utsfield(((struct sol_uname
*)A(buf
))->version
,
251 set_utsfield(((struct sol_uname
*)A(buf
))->machine
,
263 asmlinkage
int solaris_utsname(u32 buf
)
265 /* Why should we not lie a bit? */
267 set_utsfield(((struct sol_utsname
*)A(buf
))->sysname
,
269 set_utsfield(((struct sol_utsname
*)A(buf
))->nodename
,
270 system_utsname
.nodename
, 1, 1);
271 set_utsfield(((struct sol_utsname
*)A(buf
))->release
,
273 set_utsfield(((struct sol_utsname
*)A(buf
))->version
,
275 set_utsfield(((struct sol_utsname
*)A(buf
))->machine
,
281 #define SI_SYSNAME 1 /* return name of operating system */
282 #define SI_HOSTNAME 2 /* return name of node */
283 #define SI_RELEASE 3 /* return release of operating system */
284 #define SI_VERSION 4 /* return version field of utsname */
285 #define SI_MACHINE 5 /* return kind of machine */
286 #define SI_ARCHITECTURE 6 /* return instruction set arch */
287 #define SI_HW_SERIAL 7 /* return hardware serial number */
288 #define SI_HW_PROVIDER 8 /* return hardware manufacturer */
289 #define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
290 #define SI_PLATFORM 513 /* return platform identifier */
292 asmlinkage
int solaris_sysinfo(int cmd
, u32 buf
, s32 count
)
298 /* Again, we cheat :)) */
300 case SI_SYSNAME
: r
= "SunOS"; break;
304 for (p
= system_utsname
.nodename
, q
= buffer
;
305 q
< r
&& *p
&& *p
!= '.'; *q
++ = *p
++);
310 case SI_RELEASE
: r
= "5.6"; break;
311 case SI_MACHINE
: r
= machine(); break;
312 case SI_ARCHITECTURE
: r
= "sparc"; break;
313 case SI_HW_PROVIDER
: r
= "Sun_Microsystems"; break;
314 case SI_HW_SERIAL
: r
= serial(buffer
); break;
315 case SI_PLATFORM
: r
= platform(buffer
); break;
316 case SI_SRPC_DOMAIN
: r
= ""; break;
317 case SI_VERSION
: r
= "Generic"; break;
318 default: return -EINVAL
;
322 copy_to_user_ret((char *)A(buf
), r
, count
- 1, -EFAULT
);
323 __put_user_ret(0, (char *)A(buf
) + count
- 1, -EFAULT
);
325 copy_to_user_ret((char *)A(buf
), r
, len
, -EFAULT
);
329 #define SOLARIS_CONFIG_NGROUPS 2
330 #define SOLARIS_CONFIG_CHILD_MAX 3
331 #define SOLARIS_CONFIG_OPEN_FILES 4
332 #define SOLARIS_CONFIG_POSIX_VER 5
333 #define SOLARIS_CONFIG_PAGESIZE 6
334 #define SOLARIS_CONFIG_CLK_TCK 7
335 #define SOLARIS_CONFIG_XOPEN_VER 8
336 #define SOLARIS_CONFIG_PROF_TCK 10
337 #define SOLARIS_CONFIG_NPROC_CONF 11
338 #define SOLARIS_CONFIG_NPROC_ONLN 12
339 #define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
340 #define SOLARIS_CONFIG_AIO_MAX 14
341 #define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
342 #define SOLARIS_CONFIG_DELAYTIMER_MAX 16
343 #define SOLARIS_CONFIG_MQ_OPEN_MAX 17
344 #define SOLARIS_CONFIG_MQ_PRIO_MAX 18
345 #define SOLARIS_CONFIG_RTSIG_MAX 19
346 #define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
347 #define SOLARIS_CONFIG_SEM_VALUE_MAX 21
348 #define SOLARIS_CONFIG_SIGQUEUE_MAX 22
349 #define SOLARIS_CONFIG_SIGRT_MIN 23
350 #define SOLARIS_CONFIG_SIGRT_MAX 24
351 #define SOLARIS_CONFIG_TIMER_MAX 25
352 #define SOLARIS_CONFIG_PHYS_PAGES 26
353 #define SOLARIS_CONFIG_AVPHYS_PAGES 27
355 extern unsigned prom_cpu_nodes
[NR_CPUS
];
357 asmlinkage
int solaris_sysconf(int id
)
360 case SOLARIS_CONFIG_NGROUPS
: return NGROUPS_MAX
;
361 case SOLARIS_CONFIG_CHILD_MAX
: return CHILD_MAX
;
362 case SOLARIS_CONFIG_OPEN_FILES
: return OPEN_MAX
;
363 case SOLARIS_CONFIG_POSIX_VER
: return 199309;
364 case SOLARIS_CONFIG_PAGESIZE
: return PAGE_SIZE
;
365 case SOLARIS_CONFIG_XOPEN_VER
: return 3;
366 case SOLARIS_CONFIG_CLK_TCK
:
367 case SOLARIS_CONFIG_PROF_TCK
:
368 return prom_getintdefault(prom_cpu_nodes
[smp_processor_id()],
369 "clock-frequency", 167000000);
371 case SOLARIS_CONFIG_NPROC_CONF
: return NR_CPUS
;
372 case SOLARIS_CONFIG_NPROC_ONLN
: return smp_num_cpus
;
374 case SOLARIS_CONFIG_NPROC_CONF
: return 1;
375 case SOLARIS_CONFIG_NPROC_ONLN
: return 1;
377 case SOLARIS_CONFIG_SIGRT_MIN
: return 37;
378 case SOLARIS_CONFIG_SIGRT_MAX
: return 44;
379 case SOLARIS_CONFIG_PHYS_PAGES
:
380 case SOLARIS_CONFIG_AVPHYS_PAGES
:
385 if (id
== SOLARIS_CONFIG_PHYS_PAGES
)
386 return s
.totalram
>>= PAGE_SHIFT
;
388 return s
.freeram
>>= PAGE_SHIFT
;
390 /* XXX support these as well -jj */
391 case SOLARIS_CONFIG_AIO_LISTIO_MAX
: return -EINVAL
;
392 case SOLARIS_CONFIG_AIO_MAX
: return -EINVAL
;
393 case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX
: return -EINVAL
;
394 case SOLARIS_CONFIG_DELAYTIMER_MAX
: return -EINVAL
;
395 case SOLARIS_CONFIG_MQ_OPEN_MAX
: return -EINVAL
;
396 case SOLARIS_CONFIG_MQ_PRIO_MAX
: return -EINVAL
;
397 case SOLARIS_CONFIG_RTSIG_MAX
: return -EINVAL
;
398 case SOLARIS_CONFIG_SEM_NSEMS_MAX
: return -EINVAL
;
399 case SOLARIS_CONFIG_SEM_VALUE_MAX
: return -EINVAL
;
400 case SOLARIS_CONFIG_SIGQUEUE_MAX
: return -EINVAL
;
401 case SOLARIS_CONFIG_TIMER_MAX
: return -EINVAL
;
402 default: return -EINVAL
;
406 asmlinkage
int solaris_procids(int cmd
, s32 pid
, s32 pgid
)
411 case 0: /* getpgrp */
412 return current
->pgrp
;
413 case 1: /* setpgrp */
415 int (*sys_setpgid
)(pid_t
,pid_t
) =
416 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
418 /* can anyone explain me the difference between
419 Solaris setpgrp and setsid? */
420 ret
= sys_setpgid(0, 0);
423 return current
->pgrp
;
427 int (*sys_getsid
)(pid_t
) = (int (*)(pid_t
))SYS(getsid
);
428 return sys_getsid(pid
);
432 int (*sys_setsid
)(void) = (int (*)(void))SYS(setsid
);
435 case 4: /* getpgid */
437 int (*sys_getpgid
)(pid_t
) = (int (*)(pid_t
))SYS(getpgid
);
438 return sys_getpgid(pid
);
440 case 5: /* setpgid */
442 int (*sys_setpgid
)(pid_t
,pid_t
) =
443 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
444 return sys_setpgid(pid
,pgid
);
450 asmlinkage
int solaris_gettimeofday(u32 tim
)
452 int (*sys_gettimeofday
)(struct timeval
*, struct timezone
*) =
453 (int (*)(struct timeval
*, struct timezone
*))SYS(gettimeofday
);
455 return sys_gettimeofday((struct timeval
*)(u64
)tim
, NULL
);
458 #define RLIM_SOL_INFINITY32 0x7fffffff
459 #define RLIM_SOL_SAVED_MAX32 0x7ffffffe
460 #define RLIM_SOL_SAVED_CUR32 0x7ffffffd
461 #define RLIM_SOL_INFINITY ((u64)-3)
462 #define RLIM_SOL_SAVED_MAX ((u64)-2)
463 #define RLIM_SOL_SAVED_CUR ((u64)-1)
464 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
465 #define RLIMIT_SOL_NOFILE 5
466 #define RLIMIT_SOL_VMEM 6
473 asmlinkage
int solaris_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
477 mm_segment_t old_fs
= get_fs ();
478 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
479 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
481 if (resource
> RLIMIT_SOL_VMEM
)
484 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
485 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
489 ret
= sys_getrlimit(resource
, &r
);
492 if (r
.rlim_cur
== RLIM_INFINITY
)
493 r
.rlim_cur
= RLIM_SOL_INFINITY32
;
494 else if ((u64
)r
.rlim_cur
> RLIM_SOL_INFINITY32
)
495 r
.rlim_cur
= RLIM_SOL_SAVED_CUR32
;
496 if (r
.rlim_max
== RLIM_INFINITY
)
497 r
.rlim_max
= RLIM_SOL_INFINITY32
;
498 else if ((u64
)r
.rlim_max
> RLIM_SOL_INFINITY32
)
499 r
.rlim_max
= RLIM_SOL_SAVED_MAX32
;
500 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
501 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
506 asmlinkage
int solaris_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
508 struct rlimit r
, rold
;
510 mm_segment_t old_fs
= get_fs ();
511 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
512 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
513 int (*sys_setrlimit
)(unsigned int, struct rlimit
*) =
514 (int (*)(unsigned int, struct rlimit
*))SYS(setrlimit
);
516 if (resource
> RLIMIT_SOL_VMEM
)
519 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
520 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
523 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
524 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
527 ret
= sys_getrlimit(resource
, &rold
);
529 if (r
.rlim_cur
== RLIM_SOL_INFINITY32
)
530 r
.rlim_cur
= RLIM_INFINITY
;
531 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR32
)
532 r
.rlim_cur
= rold
.rlim_cur
;
533 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX32
)
534 r
.rlim_cur
= rold
.rlim_max
;
535 if (r
.rlim_max
== RLIM_SOL_INFINITY32
)
536 r
.rlim_max
= RLIM_INFINITY
;
537 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR32
)
538 r
.rlim_max
= rold
.rlim_cur
;
539 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX32
)
540 r
.rlim_max
= rold
.rlim_max
;
541 ret
= sys_setrlimit(resource
, &r
);
547 asmlinkage
int solaris_getrlimit64(unsigned int resource
, struct rlimit
*rlim
)
551 mm_segment_t old_fs
= get_fs ();
552 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
553 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
555 if (resource
> RLIMIT_SOL_VMEM
)
558 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
559 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
563 ret
= sys_getrlimit(resource
, &r
);
566 if (r
.rlim_cur
== RLIM_INFINITY
)
567 r
.rlim_cur
= RLIM_SOL_INFINITY
;
568 if (r
.rlim_max
== RLIM_INFINITY
)
569 r
.rlim_max
= RLIM_SOL_INFINITY
;
570 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
571 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
576 asmlinkage
int solaris_setrlimit64(unsigned int resource
, struct rlimit
*rlim
)
578 struct rlimit r
, rold
;
580 mm_segment_t old_fs
= get_fs ();
581 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
582 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
583 int (*sys_setrlimit
)(unsigned int, struct rlimit
*) =
584 (int (*)(unsigned int, struct rlimit
*))SYS(setrlimit
);
586 if (resource
> RLIMIT_SOL_VMEM
)
589 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
590 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
593 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
594 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
597 ret
= sys_getrlimit(resource
, &rold
);
599 if (r
.rlim_cur
== RLIM_SOL_INFINITY
)
600 r
.rlim_cur
= RLIM_INFINITY
;
601 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR
)
602 r
.rlim_cur
= rold
.rlim_cur
;
603 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX
)
604 r
.rlim_cur
= rold
.rlim_max
;
605 if (r
.rlim_max
== RLIM_SOL_INFINITY
)
606 r
.rlim_max
= RLIM_INFINITY
;
607 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR
)
608 r
.rlim_max
= rold
.rlim_cur
;
609 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX
)
610 r
.rlim_max
= rold
.rlim_max
;
611 ret
= sys_setrlimit(resource
, &r
);
621 struct sol_ntptimeval
{
622 struct timeval32 time
;
647 asmlinkage
int solaris_ntp_gettime(struct sol_ntptimeval
*ntp
)
649 int (*sys_adjtimex
)(struct timex
*) =
650 (int (*)(struct timex
*))SYS(adjtimex
);
653 mm_segment_t old_fs
= get_fs();
657 ret
= sys_adjtimex(&t
);
661 ret
= put_user (t
.time
.tv_sec
, &ntp
->time
.tv_sec
);
662 ret
|= __put_user (t
.time
.tv_usec
, &ntp
->time
.tv_usec
);
663 ret
|= __put_user (t
.maxerror
, &ntp
->maxerror
);
664 ret
|= __put_user (t
.esterror
, &ntp
->esterror
);
668 asmlinkage
int solaris_ntp_adjtime(struct sol_timex
*txp
)
670 int (*sys_adjtimex
)(struct timex
*) =
671 (int (*)(struct timex
*))SYS(adjtimex
);
674 mm_segment_t old_fs
= get_fs();
676 ret
= get_user (t
.modes
, &txp
->modes
);
677 ret
|= __get_user (t
.offset
, &txp
->offset
);
678 ret
|= __get_user (t
.freq
, &txp
->freq
);
679 ret
|= __get_user (t
.maxerror
, &txp
->maxerror
);
680 ret
|= __get_user (t
.esterror
, &txp
->esterror
);
681 ret
|= __get_user (t
.status
, &txp
->status
);
682 ret
|= __get_user (t
.constant
, &txp
->constant
);
684 ret
= sys_adjtimex(&t
);
688 err
= put_user (t
.offset
, &txp
->offset
);
689 err
|= __put_user (t
.freq
, &txp
->freq
);
690 err
|= __put_user (t
.maxerror
, &txp
->maxerror
);
691 err
|= __put_user (t
.esterror
, &txp
->esterror
);
692 err
|= __put_user (t
.status
, &txp
->status
);
693 err
|= __put_user (t
.constant
, &txp
->constant
);
694 err
|= __put_user (t
.precision
, &txp
->precision
);
695 err
|= __put_user (t
.tolerance
, &txp
->tolerance
);
696 err
|= __put_user (t
.ppsfreq
, &txp
->ppsfreq
);
697 err
|= __put_user (t
.jitter
, &txp
->jitter
);
698 err
|= __put_user (t
.shift
, &txp
->shift
);
699 err
|= __put_user (t
.stabil
, &txp
->stabil
);
700 err
|= __put_user (t
.jitcnt
, &txp
->jitcnt
);
701 err
|= __put_user (t
.calcnt
, &txp
->calcnt
);
702 err
|= __put_user (t
.errcnt
, &txp
->errcnt
);
703 err
|= __put_user (t
.stbcnt
, &txp
->stbcnt
);
709 asmlinkage
int do_sol_unimplemented(struct pt_regs
*regs
)
711 printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
712 (int)regs
->u_regs
[UREG_G1
],
713 (int)regs
->u_regs
[UREG_I0
],
714 (int)regs
->u_regs
[UREG_I1
],
715 (int)regs
->u_regs
[UREG_I2
],
716 (int)regs
->u_regs
[UREG_I3
]);
720 asmlinkage
void solaris_register(void)
723 current
->personality
= PER_SVR4
;
724 if (current
->exec_domain
&& current
->exec_domain
->module
)
725 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
726 current
->exec_domain
= lookup_exec_domain(current
->personality
);
727 if (current
->exec_domain
&& current
->exec_domain
->module
)
728 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
732 extern long solaris_to_linux_signals
[], linux_to_solaris_signals
[];
734 struct exec_domain solaris_exec_domain
= {
737 1, 1, /* PER_SVR4 personality */
738 solaris_to_linux_signals
,
739 linux_to_solaris_signals
,
744 extern int init_socksys(void);
748 MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
749 MODULE_DESCRIPTION("Solaris binary emulation module");
753 extern u32 tl0_solaris
[8];
754 #define update_ttable(x) \
755 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
756 __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
760 extern u32 solaris_sparc_syscall
[];
761 extern u32 solaris_syscall
[];
762 extern void cleanup_socksys(void);
764 int init_module(void)
768 SOLDD(("Solaris module at %p\n", solaris_sparc_syscall
));
769 register_exec_domain(&solaris_exec_domain
);
770 if ((ret
= init_socksys())) {
771 unregister_exec_domain(&solaris_exec_domain
);
774 update_ttable(solaris_sparc_syscall
);
778 void cleanup_module(void)
780 update_ttable(solaris_syscall
);
782 unregister_exec_domain(&solaris_exec_domain
);
786 int init_solaris_emul(void)
788 register_exec_domain(&solaris_exec_domain
);