maltalinux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: malta

To: maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
From: beth@linux-mips.org
Date: Tue, 16 Aug 2005 10:49:15 +0100
Reply-to: linux-mips@linux-mips.org
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
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;

<Prev in Thread] Current Thread [Next in Thread>