1 /* $Id: misc.c,v 1.20 2000/01/12 02:59:26 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
;
86 down(¤t
->mm
->mmap_sem
);
88 if(!(flags
& MAP_FIXED
) && !addr
) {
89 unsigned long attempt
= get_unmapped_area(addr
, len
);
90 if(!attempt
|| (attempt
>= 0xf0000000UL
))
94 if(!(flags
& MAP_FIXED
))
96 ret_type
= flags
& _MAP_NEW
;
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
);
104 retval
= ((retval
< 0xf0000000) ? 0 : retval
);
106 up(¤t
->mm
->mmap_sem
);
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
*)(long)((u32
)regs
->u_regs
[UREG_I6
] + 0x5c)))
127 if (get_user (offlo
, (u32
*)(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 #define set_utsfield(to, from, dotchop, countfrom) { \
142 int i, len = (countfrom) ? \
143 ((sizeof(to) > sizeof(from) ? \
144 sizeof(from) : sizeof(to))) : sizeof(to); \
145 copy_to_user_ret(to, from, len, -EFAULT); \
147 for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
150 __put_user_ret('\0', (char *)(to+i), -EFAULT); \
169 static char *machine(void)
171 switch (sparc_cpu_model
) {
172 case sun4
: return "sun4";
173 case sun4c
: return "sun4c";
174 case sun4e
: return "sun4e";
175 case sun4m
: return "sun4m";
176 case sun4d
: return "sun4d";
177 case sun4u
: return "sun4u";
178 default: return "sparc";
182 static char *platform(char *buffer
)
189 { "sun4", (SM_SUN4
| SM_4_110
) },
190 { "sun4", (SM_SUN4
| SM_4_260
) },
191 { "sun4", (SM_SUN4
| SM_4_330
) },
192 { "sun4", (SM_SUN4
| SM_4_470
) },
193 { "SUNW,Sun_4_60", (SM_SUN4C
| SM_4C_SS1
) },
194 { "SUNW,Sun_4_40", (SM_SUN4C
| SM_4C_IPC
) },
195 { "SUNW,Sun_4_65", (SM_SUN4C
| SM_4C_SS1PLUS
) },
196 { "SUNW,Sun_4_20", (SM_SUN4C
| SM_4C_SLC
) },
197 { "SUNW,Sun_4_75", (SM_SUN4C
| SM_4C_SS2
) },
198 { "SUNW,Sun_4_25", (SM_SUN4C
| SM_4C_ELC
) },
199 { "SUNW,Sun_4_50", (SM_SUN4C
| SM_4C_IPX
) },
200 { "SUNW,Sun_4_600", (SM_SUN4M
| SM_4M_SS60
) },
201 { "SUNW,SPARCstation-5", (SM_SUN4M
| SM_4M_SS50
) },
202 { "SUNW,SPARCstation-20", (SM_SUN4M
| SM_4M_SS40
) }
206 len
= prom_getproperty(prom_root_node
, "name", buffer
, 256);
212 for (p
= buffer
; *p
; p
++)
213 if (*p
== '/' || *p
== ' ') *p
= '_';
216 for (i
= 0; i
< sizeof (platforms
)/sizeof (platforms
[0]); i
++)
217 if (platforms
[i
].id_machtype
== idprom
->id_machtype
)
218 return platforms
[i
].platform
;
222 static char *serial(char *buffer
)
224 int node
= prom_getchild(prom_root_node
);
227 node
= prom_searchsiblings(node
, "options");
229 len
= prom_getproperty(node
, "system-board-serial#", buffer
, 256);
233 return "4512348717234";
238 asmlinkage
int solaris_utssys(u32 buf
, u32 flags
, int which
, u32 buf2
)
241 case 0: /* old uname */
243 set_utsfield(((struct sol_uname
*)A(buf
))->sysname
,
245 set_utsfield(((struct sol_uname
*)A(buf
))->nodename
,
246 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;
303 for (p
= system_utsname
.nodename
, q
= buffer
;
304 q
< r
&& *p
&& *p
!= '.'; *q
++ = *p
++);
308 case SI_RELEASE
: r
= "5.6"; break;
309 case SI_MACHINE
: r
= machine(); break;
310 case SI_ARCHITECTURE
: r
= "sparc"; break;
311 case SI_HW_PROVIDER
: r
= "Sun_Microsystems"; break;
312 case SI_HW_SERIAL
: r
= serial(buffer
); break;
313 case SI_PLATFORM
: r
= platform(buffer
); break;
314 case SI_SRPC_DOMAIN
: r
= ""; break;
315 case SI_VERSION
: r
= "Generic"; break;
316 default: return -EINVAL
;
320 copy_to_user_ret((char *)A(buf
), r
, count
- 1, -EFAULT
);
321 __put_user_ret(0, (char *)A(buf
) + count
- 1, -EFAULT
);
323 copy_to_user_ret((char *)A(buf
), r
, len
, -EFAULT
);
327 #define SOLARIS_CONFIG_NGROUPS 2
328 #define SOLARIS_CONFIG_CHILD_MAX 3
329 #define SOLARIS_CONFIG_OPEN_FILES 4
330 #define SOLARIS_CONFIG_POSIX_VER 5
331 #define SOLARIS_CONFIG_PAGESIZE 6
332 #define SOLARIS_CONFIG_CLK_TCK 7
333 #define SOLARIS_CONFIG_XOPEN_VER 8
334 #define SOLARIS_CONFIG_PROF_TCK 10
335 #define SOLARIS_CONFIG_NPROC_CONF 11
336 #define SOLARIS_CONFIG_NPROC_ONLN 12
337 #define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
338 #define SOLARIS_CONFIG_AIO_MAX 14
339 #define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
340 #define SOLARIS_CONFIG_DELAYTIMER_MAX 16
341 #define SOLARIS_CONFIG_MQ_OPEN_MAX 17
342 #define SOLARIS_CONFIG_MQ_PRIO_MAX 18
343 #define SOLARIS_CONFIG_RTSIG_MAX 19
344 #define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
345 #define SOLARIS_CONFIG_SEM_VALUE_MAX 21
346 #define SOLARIS_CONFIG_SIGQUEUE_MAX 22
347 #define SOLARIS_CONFIG_SIGRT_MIN 23
348 #define SOLARIS_CONFIG_SIGRT_MAX 24
349 #define SOLARIS_CONFIG_TIMER_MAX 25
350 #define SOLARIS_CONFIG_PHYS_PAGES 26
351 #define SOLARIS_CONFIG_AVPHYS_PAGES 27
353 extern unsigned prom_cpu_nodes
[NR_CPUS
];
355 asmlinkage
int solaris_sysconf(int id
)
358 case SOLARIS_CONFIG_NGROUPS
: return NGROUPS_MAX
;
359 case SOLARIS_CONFIG_CHILD_MAX
: return CHILD_MAX
;
360 case SOLARIS_CONFIG_OPEN_FILES
: return OPEN_MAX
;
361 case SOLARIS_CONFIG_POSIX_VER
: return 199309;
362 case SOLARIS_CONFIG_PAGESIZE
: return PAGE_SIZE
;
363 case SOLARIS_CONFIG_XOPEN_VER
: return 3;
364 case SOLARIS_CONFIG_CLK_TCK
:
365 case SOLARIS_CONFIG_PROF_TCK
:
366 return prom_getintdefault(prom_cpu_nodes
[smp_processor_id()],
367 "clock-frequency", 167000000);
369 case SOLARIS_CONFIG_NPROC_CONF
: return NR_CPUS
;
370 case SOLARIS_CONFIG_NPROC_ONLN
: return smp_num_cpus
;
372 case SOLARIS_CONFIG_NPROC_CONF
: return 1;
373 case SOLARIS_CONFIG_NPROC_ONLN
: return 1;
375 case SOLARIS_CONFIG_SIGRT_MIN
: return 37;
376 case SOLARIS_CONFIG_SIGRT_MAX
: return 44;
377 case SOLARIS_CONFIG_PHYS_PAGES
:
378 case SOLARIS_CONFIG_AVPHYS_PAGES
:
383 if (id
== SOLARIS_CONFIG_PHYS_PAGES
)
384 return s
.totalram
>>= PAGE_SHIFT
;
386 return s
.freeram
>>= PAGE_SHIFT
;
388 /* XXX support these as well -jj */
389 case SOLARIS_CONFIG_AIO_LISTIO_MAX
: return -EINVAL
;
390 case SOLARIS_CONFIG_AIO_MAX
: return -EINVAL
;
391 case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX
: return -EINVAL
;
392 case SOLARIS_CONFIG_DELAYTIMER_MAX
: return -EINVAL
;
393 case SOLARIS_CONFIG_MQ_OPEN_MAX
: return -EINVAL
;
394 case SOLARIS_CONFIG_MQ_PRIO_MAX
: return -EINVAL
;
395 case SOLARIS_CONFIG_RTSIG_MAX
: return -EINVAL
;
396 case SOLARIS_CONFIG_SEM_NSEMS_MAX
: return -EINVAL
;
397 case SOLARIS_CONFIG_SEM_VALUE_MAX
: return -EINVAL
;
398 case SOLARIS_CONFIG_SIGQUEUE_MAX
: return -EINVAL
;
399 case SOLARIS_CONFIG_TIMER_MAX
: return -EINVAL
;
400 default: return -EINVAL
;
404 asmlinkage
int solaris_procids(int cmd
, s32 pid
, s32 pgid
)
409 case 0: /* getpgrp */
410 return current
->pgrp
;
411 case 1: /* setpgrp */
413 int (*sys_setpgid
)(pid_t
,pid_t
) =
414 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
416 /* can anyone explain me the difference between
417 Solaris setpgrp and setsid? */
418 ret
= sys_setpgid(0, 0);
421 return current
->pgrp
;
425 int (*sys_getsid
)(pid_t
) = (int (*)(pid_t
))SYS(getsid
);
426 return sys_getsid(pid
);
430 int (*sys_setsid
)(void) = (int (*)(void))SYS(setsid
);
433 case 4: /* getpgid */
435 int (*sys_getpgid
)(pid_t
) = (int (*)(pid_t
))SYS(getpgid
);
436 return sys_getpgid(pid
);
438 case 5: /* setpgid */
440 int (*sys_setpgid
)(pid_t
,pid_t
) =
441 (int (*)(pid_t
,pid_t
))SYS(setpgid
);
442 return sys_setpgid(pid
,pgid
);
448 asmlinkage
int solaris_gettimeofday(u32 tim
)
450 int (*sys_gettimeofday
)(struct timeval
*, struct timezone
*) =
451 (int (*)(struct timeval
*, struct timezone
*))SYS(gettimeofday
);
453 return sys_gettimeofday((struct timeval
*)(u64
)tim
, NULL
);
456 #define RLIM_SOL_INFINITY32 0x7fffffff
457 #define RLIM_SOL_SAVED_MAX32 0x7ffffffe
458 #define RLIM_SOL_SAVED_CUR32 0x7ffffffd
459 #define RLIM_SOL_INFINITY ((u64)-3)
460 #define RLIM_SOL_SAVED_MAX ((u64)-2)
461 #define RLIM_SOL_SAVED_CUR ((u64)-1)
462 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
463 #define RLIMIT_SOL_NOFILE 5
464 #define RLIMIT_SOL_VMEM 6
471 asmlinkage
int solaris_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
475 mm_segment_t old_fs
= get_fs ();
476 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
477 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
479 if (resource
> RLIMIT_SOL_VMEM
)
482 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
483 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
487 ret
= sys_getrlimit(resource
, &r
);
490 if (r
.rlim_cur
== RLIM_INFINITY
)
491 r
.rlim_cur
= RLIM_SOL_INFINITY32
;
492 else if ((u64
)r
.rlim_cur
> RLIM_SOL_INFINITY32
)
493 r
.rlim_cur
= RLIM_SOL_SAVED_CUR32
;
494 if (r
.rlim_max
== RLIM_INFINITY
)
495 r
.rlim_max
= RLIM_SOL_INFINITY32
;
496 else if ((u64
)r
.rlim_max
> RLIM_SOL_INFINITY32
)
497 r
.rlim_max
= RLIM_SOL_SAVED_MAX32
;
498 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
499 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
504 asmlinkage
int solaris_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
506 struct rlimit r
, rold
;
508 mm_segment_t old_fs
= get_fs ();
509 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
510 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
511 int (*sys_setrlimit
)(unsigned int, struct rlimit
*) =
512 (int (*)(unsigned int, struct rlimit
*))SYS(setrlimit
);
514 if (resource
> RLIMIT_SOL_VMEM
)
517 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
518 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
521 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
522 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
525 ret
= sys_getrlimit(resource
, &rold
);
527 if (r
.rlim_cur
== RLIM_SOL_INFINITY32
)
528 r
.rlim_cur
= RLIM_INFINITY
;
529 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR32
)
530 r
.rlim_cur
= rold
.rlim_cur
;
531 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX32
)
532 r
.rlim_cur
= rold
.rlim_max
;
533 if (r
.rlim_max
== RLIM_SOL_INFINITY32
)
534 r
.rlim_max
= RLIM_INFINITY
;
535 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR32
)
536 r
.rlim_max
= rold
.rlim_cur
;
537 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX32
)
538 r
.rlim_max
= rold
.rlim_max
;
539 ret
= sys_setrlimit(resource
, &r
);
545 asmlinkage
int solaris_getrlimit64(unsigned int resource
, struct rlimit
*rlim
)
549 mm_segment_t old_fs
= get_fs ();
550 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
551 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
553 if (resource
> RLIMIT_SOL_VMEM
)
556 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
557 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
561 ret
= sys_getrlimit(resource
, &r
);
564 if (r
.rlim_cur
== RLIM_INFINITY
)
565 r
.rlim_cur
= RLIM_SOL_INFINITY
;
566 if (r
.rlim_max
== RLIM_INFINITY
)
567 r
.rlim_max
= RLIM_SOL_INFINITY
;
568 ret
= put_user (r
.rlim_cur
, &rlim
->rlim_cur
);
569 ret
|= __put_user (r
.rlim_max
, &rlim
->rlim_max
);
574 asmlinkage
int solaris_setrlimit64(unsigned int resource
, struct rlimit
*rlim
)
576 struct rlimit r
, rold
;
578 mm_segment_t old_fs
= get_fs ();
579 int (*sys_getrlimit
)(unsigned int, struct rlimit
*) =
580 (int (*)(unsigned int, struct rlimit
*))SYS(getrlimit
);
581 int (*sys_setrlimit
)(unsigned int, struct rlimit
*) =
582 (int (*)(unsigned int, struct rlimit
*))SYS(setrlimit
);
584 if (resource
> RLIMIT_SOL_VMEM
)
587 case RLIMIT_SOL_NOFILE
: resource
= RLIMIT_NOFILE
; break;
588 case RLIMIT_SOL_VMEM
: resource
= RLIMIT_AS
; break;
591 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
592 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
595 ret
= sys_getrlimit(resource
, &rold
);
597 if (r
.rlim_cur
== RLIM_SOL_INFINITY
)
598 r
.rlim_cur
= RLIM_INFINITY
;
599 else if (r
.rlim_cur
== RLIM_SOL_SAVED_CUR
)
600 r
.rlim_cur
= rold
.rlim_cur
;
601 else if (r
.rlim_cur
== RLIM_SOL_SAVED_MAX
)
602 r
.rlim_cur
= rold
.rlim_max
;
603 if (r
.rlim_max
== RLIM_SOL_INFINITY
)
604 r
.rlim_max
= RLIM_INFINITY
;
605 else if (r
.rlim_max
== RLIM_SOL_SAVED_CUR
)
606 r
.rlim_max
= rold
.rlim_cur
;
607 else if (r
.rlim_max
== RLIM_SOL_SAVED_MAX
)
608 r
.rlim_max
= rold
.rlim_max
;
609 ret
= sys_setrlimit(resource
, &r
);
619 struct sol_ntptimeval
{
620 struct timeval32 time
;
645 asmlinkage
int solaris_ntp_gettime(struct sol_ntptimeval
*ntp
)
647 int (*sys_adjtimex
)(struct timex
*) =
648 (int (*)(struct timex
*))SYS(adjtimex
);
651 mm_segment_t old_fs
= get_fs();
655 ret
= sys_adjtimex(&t
);
659 ret
= put_user (t
.time
.tv_sec
, &ntp
->time
.tv_sec
);
660 ret
|= __put_user (t
.time
.tv_usec
, &ntp
->time
.tv_usec
);
661 ret
|= __put_user (t
.maxerror
, &ntp
->maxerror
);
662 ret
|= __put_user (t
.esterror
, &ntp
->esterror
);
666 asmlinkage
int solaris_ntp_adjtime(struct sol_timex
*txp
)
668 int (*sys_adjtimex
)(struct timex
*) =
669 (int (*)(struct timex
*))SYS(adjtimex
);
672 mm_segment_t old_fs
= get_fs();
674 ret
= get_user (t
.modes
, &txp
->modes
);
675 ret
|= __get_user (t
.offset
, &txp
->offset
);
676 ret
|= __get_user (t
.freq
, &txp
->freq
);
677 ret
|= __get_user (t
.maxerror
, &txp
->maxerror
);
678 ret
|= __get_user (t
.esterror
, &txp
->esterror
);
679 ret
|= __get_user (t
.status
, &txp
->status
);
680 ret
|= __get_user (t
.constant
, &txp
->constant
);
682 ret
= sys_adjtimex(&t
);
686 err
= put_user (t
.offset
, &txp
->offset
);
687 err
|= __put_user (t
.freq
, &txp
->freq
);
688 err
|= __put_user (t
.maxerror
, &txp
->maxerror
);
689 err
|= __put_user (t
.esterror
, &txp
->esterror
);
690 err
|= __put_user (t
.status
, &txp
->status
);
691 err
|= __put_user (t
.constant
, &txp
->constant
);
692 err
|= __put_user (t
.precision
, &txp
->precision
);
693 err
|= __put_user (t
.tolerance
, &txp
->tolerance
);
694 err
|= __put_user (t
.ppsfreq
, &txp
->ppsfreq
);
695 err
|= __put_user (t
.jitter
, &txp
->jitter
);
696 err
|= __put_user (t
.shift
, &txp
->shift
);
697 err
|= __put_user (t
.stabil
, &txp
->stabil
);
698 err
|= __put_user (t
.jitcnt
, &txp
->jitcnt
);
699 err
|= __put_user (t
.calcnt
, &txp
->calcnt
);
700 err
|= __put_user (t
.errcnt
, &txp
->errcnt
);
701 err
|= __put_user (t
.stbcnt
, &txp
->stbcnt
);
707 asmlinkage
int do_sol_unimplemented(struct pt_regs
*regs
)
709 printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
710 (int)regs
->u_regs
[UREG_G1
],
711 (int)regs
->u_regs
[UREG_I0
],
712 (int)regs
->u_regs
[UREG_I1
],
713 (int)regs
->u_regs
[UREG_I2
],
714 (int)regs
->u_regs
[UREG_I3
]);
718 asmlinkage
void solaris_register(void)
721 current
->personality
= PER_SVR4
;
722 if (current
->exec_domain
&& current
->exec_domain
->module
)
723 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
724 current
->exec_domain
= lookup_exec_domain(current
->personality
);
725 if (current
->exec_domain
&& current
->exec_domain
->module
)
726 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
730 extern long solaris_to_linux_signals
[], linux_to_solaris_signals
[];
732 struct exec_domain solaris_exec_domain
= {
735 1, 1, /* PER_SVR4 personality */
736 solaris_to_linux_signals
,
737 linux_to_solaris_signals
,
742 extern int init_socksys(void);
746 MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
747 MODULE_DESCRIPTION("Solaris binary emulation module");
751 extern u32 tl0_solaris
[8];
752 #define update_ttable(x) \
753 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
754 __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
758 extern u32 solaris_sparc_syscall
[];
759 extern u32 solaris_syscall
[];
760 extern void cleanup_socksys(void);
762 int init_module(void)
766 SOLDD(("Solaris module at %p\n", solaris_sparc_syscall
));
767 register_exec_domain(&solaris_exec_domain
);
768 if ((ret
= init_socksys())) {
769 unregister_exec_domain(&solaris_exec_domain
);
772 update_ttable(solaris_sparc_syscall
);
776 void cleanup_module(void)
778 update_ttable(solaris_syscall
);
780 unregister_exec_domain(&solaris_exec_domain
);
784 int init_solaris_emul(void)
786 register_exec_domain(&solaris_exec_domain
);