* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/smp_lock.h>
#include <linux/limits.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/tty.h>
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/timex.h>
#include <asm/oplib.h>
#include <asm/idprom.h>
#include <asm/smp.h>
+#include <asm/prom.h>
#include "conv.h"
if (!file)
goto out;
else {
- struct inode * inode = file->f_dentry->d_inode;
+ struct inode * inode = file->f_path.dentry->d_inode;
if(imajor(inode) == MEM_MAJOR &&
iminor(inode) == 5) {
flags |= MAP_ANONYMOUS;
len = PAGE_ALIGN(len);
if(!(flags & MAP_FIXED))
addr = 0;
- else if (len > 0xf0000000UL || addr > 0xf0000000UL - len)
+ else if (len > STACK_TOP32 || addr > STACK_TOP32 - len)
goto out_putf;
ret_type = flags & _MAP_NEW;
flags &= ~_MAP_NEW;
(unsigned long) prot, (unsigned long) flags, off);
up_write(¤t->mm->mmap_sem);
if(!ret_type)
- retval = ((retval < 0xf0000000) ? 0 : retval);
+ retval = ((retval < STACK_TOP32) ? 0 : retval);
out_putf:
if (file)
u32 offlo;
if (regs->u_regs[UREG_G1]) {
- if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
+ if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
return -EFAULT;
} else {
- if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
+ if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
return -EFAULT;
}
return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
return sunos_brk(brk);
}
-#define set_utsfield(to, from, dotchop, countfrom) { \
- char *p; \
- int i, len = (countfrom) ? \
- ((sizeof(to) > sizeof(from) ? \
- sizeof(from) : sizeof(to))) : sizeof(to); \
- if (copy_to_user(to, from, len)) \
- return -EFAULT; \
- if (dotchop) \
- for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
- else \
- i = len - 1; \
- if (__put_user('\0', (char *)(to+i))) \
- return -EFAULT; \
+static int __set_utsfield(char __user *to, int to_size,
+ const char *from, int from_size,
+ int dotchop, int countfrom)
+{
+ int len = countfrom ? (to_size > from_size ?
+ from_size : to_size) : to_size;
+ int off;
+
+ if (copy_to_user(to, from, len))
+ return -EFAULT;
+
+ off = len < to_size? len: len - 1;
+ if (dotchop) {
+ const char *p = strnchr(from, len, '.');
+ if (p) off = p - from;
+ }
+
+ if (__put_user('\0', to + off))
+ return -EFAULT;
+
+ return 0;
}
+#define set_utsfield(to, from, dotchop, countfrom) \
+ __set_utsfield((to), sizeof(to), \
+ (from), sizeof(from), \
+ (dotchop), (countfrom))
+
struct sol_uname {
char sysname[9];
char nodename[9];
}
}
-static char *platform(char *buffer)
+static char *platform(char *buffer, int sz)
{
+ struct device_node *dp = of_find_node_by_path("/");
int len;
*buffer = 0;
- len = prom_getproperty(prom_root_node, "name", buffer, 256);
- if(len > 0)
- buffer[len] = 0;
+ len = strlen(dp->name);
+ if (len > sz)
+ len = sz;
+ memcpy(buffer, dp->name, len);
+ buffer[len] = 0;
if (*buffer) {
char *p;
return "sun4u";
}
-static char *serial(char *buffer)
+static char *serial(char *buffer, int sz)
{
- int node = prom_getchild(prom_root_node);
+ struct device_node *dp = of_find_node_by_path("/options");
int len;
- node = prom_searchsiblings(node, "options");
*buffer = 0;
- len = prom_getproperty(node, "system-board-serial#", buffer, 256);
- if(len > 0)
- buffer[len] = 0;
+ if (dp) {
+ char *val = of_get_property(dp, "system-board-serial#", &len);
+
+ if (val && len > 0) {
+ if (len > sz)
+ len = sz;
+ memcpy(buffer, val, len);
+ buffer[len] = 0;
+ }
+ }
if (!*buffer)
return "4512348717234";
else
asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
{
+ struct sol_uname __user *v = A(buf);
+ int err;
+
switch (which) {
case 0: /* old uname */
/* Let's cheat */
- set_utsfield(((struct sol_uname *)A(buf))->sysname,
- "SunOS", 1, 0);
+ err = set_utsfield(v->sysname, "SunOS", 1, 0);
down_read(&uts_sem);
- set_utsfield(((struct sol_uname *)A(buf))->nodename,
- system_utsname.nodename, 1, 1);
+ err |= set_utsfield(v->nodename, utsname()->nodename,
+ 1, 1);
up_read(&uts_sem);
- set_utsfield(((struct sol_uname *)A(buf))->release,
- "2.6", 0, 0);
- set_utsfield(((struct sol_uname *)A(buf))->version,
- "Generic", 0, 0);
- set_utsfield(((struct sol_uname *)A(buf))->machine,
- machine(), 0, 0);
- return 0;
+ err |= set_utsfield(v->release, "2.6", 0, 0);
+ err |= set_utsfield(v->version, "Generic", 0, 0);
+ err |= set_utsfield(v->machine, machine(), 0, 0);
+ return (err ? -EFAULT : 0);
case 2: /* ustat */
return -ENOSYS;
case 3: /* fusers */
asmlinkage int solaris_utsname(u32 buf)
{
+ struct sol_utsname __user *v = A(buf);
+ int err;
+
/* Why should we not lie a bit? */
down_read(&uts_sem);
- set_utsfield(((struct sol_utsname *)A(buf))->sysname,
- "SunOS", 0, 0);
- set_utsfield(((struct sol_utsname *)A(buf))->nodename,
- system_utsname.nodename, 1, 1);
- set_utsfield(((struct sol_utsname *)A(buf))->release,
- "5.6", 0, 0);
- set_utsfield(((struct sol_utsname *)A(buf))->version,
- "Generic", 0, 0);
- set_utsfield(((struct sol_utsname *)A(buf))->machine,
- machine(), 0, 0);
+ err = set_utsfield(v->sysname, "SunOS", 0, 0);
+ err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
+ err |= set_utsfield(v->release, "5.6", 0, 0);
+ err |= set_utsfield(v->version, "Generic", 0, 0);
+ err |= set_utsfield(v->machine, machine(), 0, 0);
up_read(&uts_sem);
- return 0;
+
+ return (err ? -EFAULT : 0);
}
#define SI_SYSNAME 1 /* return name of operating system */
case SI_HOSTNAME:
r = buffer + 256;
down_read(&uts_sem);
- for (p = system_utsname.nodename, q = buffer;
+ for (p = utsname()->nodename, q = buffer;
q < r && *p && *p != '.'; *q++ = *p++);
up_read(&uts_sem);
*q = 0;
case SI_MACHINE: r = machine(); break;
case SI_ARCHITECTURE: r = "sparc"; break;
case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
- case SI_HW_SERIAL: r = serial(buffer); break;
- case SI_PLATFORM: r = platform(buffer); break;
+ case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
+ case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
case SI_SRPC_DOMAIN: r = ""; break;
case SI_VERSION: r = "Generic"; break;
default: return -EINVAL;
}
len = strlen(r) + 1;
if (count < len) {
- if (copy_to_user((char *)A(buf), r, count - 1) ||
- __put_user(0, (char *)A(buf) + count - 1))
+ if (copy_to_user(A(buf), r, count - 1) ||
+ __put_user(0, (char __user *)A(buf) + count - 1))
return -EFAULT;
} else {
- if (copy_to_user((char *)A(buf), r, len))
+ if (copy_to_user(A(buf), r, len))
return -EFAULT;
}
return len;
{
switch (id) {
case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
- case SOLARIS_CONFIG_CHILD_MAX: return CHILD_MAX;
+ case SOLARIS_CONFIG_CHILD_MAX: return -1; /* no limit */
case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX;
case SOLARIS_CONFIG_POSIX_VER: return 199309;
case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
Solaris setpgrp and setsid? */
ret = sys_setpgid(0, 0);
if (ret) return ret;
- current->signal->tty = NULL;
+ proc_clear_tty(current);
return process_group(current);
}
case 2: /* getsid */
u32 rlim_max;
};
-asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 *rlim)
+asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim)
{
struct rlimit r;
int ret;
return ret;
}
-asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 *rlim)
+asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim)
{
struct rlimit r, rold;
int ret;
mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
- int (*sys_setrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
+ int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
+ (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
+ int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
+ (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
if (resource > RLIMIT_SOL_VMEM)
return -EINVAL;
return ret;
}
-asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit *rlim)
+asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim)
{
struct rlimit r;
int ret;
mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
+ int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
+ (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
if (resource > RLIMIT_SOL_VMEM)
return -EINVAL;
return ret;
}
-asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit *rlim)
+asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim)
{
struct rlimit r, rold;
int ret;
mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
- int (*sys_setrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
+ int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
+ (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
+ int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
+ (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
if (resource > RLIMIT_SOL_VMEM)
return -EINVAL;
s32 stbcnt;
};
-asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval *ntp)
+asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp)
{
- int (*sys_adjtimex)(struct timex *) =
- (int (*)(struct timex *))SYS(adjtimex);
+ int (*sys_adjtimex)(struct timex __user *) =
+ (int (*)(struct timex __user *))SYS(adjtimex);
struct timex t;
int ret;
mm_segment_t old_fs = get_fs();
return ret;
}
-asmlinkage int solaris_ntp_adjtime(struct sol_timex *txp)
+asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp)
{
- int (*sys_adjtimex)(struct timex *) =
- (int (*)(struct timex *))SYS(adjtimex);
+ int (*sys_adjtimex)(struct timex __user *) =
+ (int (*)(struct timex __user *))SYS(adjtimex);
struct timex t;
int ret, err;
mm_segment_t old_fs = get_fs();
extern int init_socksys(void);
-#ifdef MODULE
-
MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
MODULE_DESCRIPTION("Solaris binary emulation module");
MODULE_LICENSE("GPL");
-#ifdef __sparc_v9__
extern u32 tl0_solaris[8];
#define update_ttable(x) \
tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
- __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
-#else
-#endif
+ wmb(); \
+ __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
extern u32 solaris_sparc_syscall[];
extern u32 solaris_syscall[];
extern u32 entry64_personality_patch;
-int init_module(void)
+static int __init solaris_init(void)
{
int ret;
entry64_personality_patch |=
(offsetof(struct task_struct, personality) +
(sizeof(unsigned long) - 1));
- __asm__ __volatile__("membar #StoreStore; flush %0"
+ wmb();
+ __asm__ __volatile__("flush %0"
: : "r" (&entry64_personality_patch));
return 0;
}
-void cleanup_module(void)
+static void __exit solaris_exit(void)
{
update_ttable(solaris_syscall);
cleanup_socksys();
unregister_exec_domain(&solaris_exec_domain);
}
-#else
-int init_solaris_emul(void)
-{
- register_exec_domain(&solaris_exec_domain);
- init_socksys();
- return 0;
-}
-#endif
-
+module_init(solaris_init);
+module_exit(solaris_exit);