CVSROOT: /home/cvs
Module name: malta
Changes by: beth@ftp.linux-mips.org 05/08/16 10:49:13
Modified files:
linux/arch/mips/kernel: Tag: MaltaRef_2_6 kspd.c rtlx.c
Log message:
* arch/mips/kernel/kspd.c: Fix loop where in some circumstances the SP
channel could not be opened.
Translate SDE based MTSP syscall commands to linux equivalents.
Support unlimited number of arguments to syscall, but for now
only set up the first 4 as the rest have to go on the 'user' stack.
* arch/mips/kernel/rtlx.c: Handle an exit code from SP in the shared
pointer,
useful if an exception occurs before rtlx has been set up.
diff -urN malta/linux/arch/mips/kernel/kspd.c
malta/linux/arch/mips/kernel/kspd.c
--- malta/linux/arch/mips/kernel/Attic/kspd.c 2005/08/08 13:24:14
1.1.1000.2
+++ malta/linux/arch/mips/kernel/Attic/kspd.c 2005/08/16 09:49:13
1.1.1000.3
@@ -31,12 +31,25 @@
static struct workqueue_struct *workqueue = NULL;
static struct work_struct work;
-struct sp_request {
- int cmd;
- int arg0;
- int arg1;
- int arg2;
- int ret;
+struct mtsp_syscall {
+ int cmd;
+ unsigned char abi;
+ unsigned char size;
+};
+
+struct mtsp_syscall_ret {
+ int retval;
+ int errno;
+};
+
+struct mtsp_syscall_generic {
+ int arg0;
+ int arg1;
+ int arg2;
+ int arg3;
+ int arg4;
+ int arg5;
+ int arg6;
};
static struct list_head kspd_notifylist;
@@ -45,7 +58,11 @@
/* these should match with those in the SDE kit */
#define MTSP_SYSCALL_BASE 0
#define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0)
-#define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 5)
+#define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1)
+#define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2)
+#define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3)
+#define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4)
+#define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5)
#define MTSP_O_RDONLY 0x0000
#define MTSP_O_WRONLY 0x0001
@@ -81,13 +98,22 @@
{MTSP_O_NOFOLLOW, O_NOFOLLOW}
};
-static int sp_syscall(int num, int arg0, int arg1, int arg2)
+struct apsp_table syscall_command_table[] = {
+ {MTSP_SYSCALL_OPEN, __NR_open},
+ {MTSP_SYSCALL_CLOSE, __NR_close},
+ {MTSP_SYSCALL_READ, __NR_read},
+ {MTSP_SYSCALL_WRITE, __NR_write},
+ {MTSP_SYSCALL_LSEEK32, __NR_lseek}
+};
+
+static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
{
register long int _num __asm__ ("$2") = num;
register long int _arg0 __asm__ ("$4") = arg0;
register long int _arg1 __asm__ ("$5") = arg1;
register long int _arg2 __asm__ ("$6") = arg2;
- register long int eflag __asm__ ("$7") = 1;
+ register long int _arg3 __asm__ ("$7") = arg3;
+// register long int eflag __asm__ ("$7") = 1;
mm_segment_t old_fs;
@@ -96,19 +122,33 @@
__asm__ __volatile__ (
"syscall\n\t"
- : "=r" (_num), "=r" (eflag)
- : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2)
+ : "=r" (_num), "=r" (_arg3)
+ : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3)
);
set_fs (old_fs);
- if (eflag)
+ /* $a3 is error flag */
+ if (_arg3)
return -_num;
return _num;
}
-static int translate_open_flags(int flags)
+static int translate_syscall_command(int cmd)
+{
+ int i;
+ int ret = -1;
+
+ for (i = 0; i < (sizeof(syscall_command_table) / sizeof(struct
apsp_table));
+ i++) {
+ if( (cmd == syscall_command_table[i].sp) )
+ return syscall_command_table[i].ap;
+ }
+
+ return ret;
+}
+static unsigned int translate_open_flags(int flags)
{
int i;
unsigned int ret = 0;
@@ -123,6 +163,7 @@
return ret;
}
+
static void sp_setfsuidgid( uid_t uid, gid_t gid)
{
current->fsuid = uid;
@@ -139,14 +180,24 @@
*/
void sp_work_handle_request(void)
{
- struct sp_request spreq;
+ struct mtsp_syscall sc;
+ struct mtsp_syscall_generic generic;
+ struct mtsp_syscall_ret ret;
struct kspd_notifications *n;
char *vcwd;
mm_segment_t old_fs;
+ int size;
+
+ ret.retval = -1;
+
+ if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall),
0)) {
+ printk(KERN_ERR "Expected request but nothing to read\n");
+ return;
+ }
- spreq.ret = -1;
+ size = sc.size;
- if (!rtlx_read(RTLX_CHANNEL_SYSIO, &spreq, sizeof(struct sp_request),
0)) {
+ if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) {
printk(KERN_ERR "Expected request but nothing to read\n");
return;
}
@@ -157,23 +208,24 @@
if (vpe_getuid(SP_VPE))
sp_setfsuidgid( vpe_getuid(SP_VPE), vpe_getgid(SP_VPE));
- /* Linux compatible syscalls can be actioned directly */
- if ((spreq.cmd >= __NR_Linux) &&
- (spreq.cmd <= (__NR_Linux + __NR_Linux_syscalls))) {
- /* its a linux syscall */
+ switch (sc.cmd) {
+
+ /* needs the flags argument translating from SDE kit to
+ linux */
+
+ case MTSP_SYSCALL_EXIT:
+ list_for_each_entry(n, &kspd_notifylist, list) {
+ n->kspd_sp_exit(SP_VPE);
+ }
+ sp_stopping = 1;
- spreq.ret = sp_syscall(spreq.cmd, spreq.arg0, spreq.arg1,
- spreq.arg2);
+ printk(KERN_DEBUG "KSPD got exit syscall from SP
exitcode %d\n",
+ generic.arg0);
+ break;
- }
- else {
- switch (spreq.cmd) {
-
- /* needs the flags argument translating from SDE kit to
- linux */
case MTSP_SYSCALL_OPEN:
- spreq.arg1 = translate_open_flags(spreq.arg1);
-
+ generic.arg1 = translate_open_flags(generic.arg1);
+
vcwd = vpe_getcwd(SP_VPE);
/* change to the cwd of the process that loaded the SP
program */
@@ -182,32 +234,36 @@
sys_chdir(vcwd);
set_fs (old_fs);
- spreq.ret = sp_syscall(__NR_open, spreq.arg0,
spreq.arg1,
- spreq.arg2);
+ sc.cmd = __NR_open;
- break;
+ /* fall through */
+
+ default:
+ {
+ int cmd;
- case MTSP_SYSCALL_EXIT:
- list_for_each_entry(n, &kspd_notifylist, list) {
- n->kspd_sp_exit(SP_VPE);
+ if ((sc.cmd >= __NR_Linux) && (sc.cmd <= (__NR_Linux +
__NR_Linux_syscalls)) )
+ cmd = sc.cmd;
+ else
+ cmd = translate_syscall_command(sc.cmd);
+
+ if (cmd >= 0) {
+ ret.retval = sp_syscall(cmd, generic.arg0,
generic.arg1,
+ generic.arg2,
generic.arg3);
+ ret.errno = errno;
+ }
+ else {
+ printk(KERN_WARNING "KSPD: Unknown SP syscall
number %d\n",
+ sc.cmd);
}
- sp_stopping = 1;
-
- printk(KERN_DEBUG "KSPD got exit syscall from SP\n");
- break;
-
- default:
- printk(KERN_WARNING "KSPD: Invalid SP syscall number
%d\n",
- spreq.cmd);
- break;
}
- }
-
+ } /* switch */
+
if (vpe_getuid(SP_VPE))
sp_setfsuidgid( 0, 0);
- if ((rtlx_write(RTLX_CHANNEL_SYSIO, &spreq, sizeof(struct sp_request),
0))
- < sizeof(struct sp_request))
+ if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct
mtsp_syscall_ret), 0))
+ < sizeof(struct mtsp_syscall_ret))
printk("KSPD: sp_work_handle_request failed to send to SP\n");
}
@@ -217,8 +273,10 @@
static void sp_work( void *data)
{
if (!channel_open) {
- if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0)
+ if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
printk("KSPD: unable to open sp channel\n");
+ sp_stopping = 1;
+ }
else {
channel_open++;
printk(KERN_DEBUG "KSPD: SP channel opened\n");
diff -urN malta/linux/arch/mips/kernel/rtlx.c
malta/linux/arch/mips/kernel/rtlx.c
--- malta/linux/arch/mips/kernel/rtlx.c 2005/08/11 13:27:20 1.1.1000.3
+++ malta/linux/arch/mips/kernel/rtlx.c 2005/08/16 09:49:13 1.1.1000.4
@@ -211,6 +211,12 @@
return -ENOSYS;
}
}
+
+ if ((unsigned int)*p < KSEG0) {
+ printk(KERN_WARNING "vpe_get_shared returned an invalid
pointer "
+ "maybe an error code %d\n", (int)*p);
+ return -ENOSYS;
+ }
if ((ret = rtlx_init(*p)) < 0)
return ret;
|