]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel: delivermsg improvements 20/3120/1
authorBen Gras <ben@minix3.org>
Sun, 28 Jun 2015 22:07:29 +0000 (00:07 +0200)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 17 Sep 2015 13:41:09 +0000 (13:41 +0000)
    . make arch-independent, and local to proc.c, reduce code duplication
    . make vm_suspend public but unduplicated in proc.c
    . ask VM for handling once, 2nd time SIGSEGV process
    . remove debug printfs
    . test case for bogus sendrec() address argument

Change-Id: I3893758910c01de60b8fe3e50edd594296a0b73e

minix/kernel/arch/earm/memory.c
minix/kernel/arch/i386/memory.c
minix/kernel/proc.c
minix/kernel/proc.h
minix/kernel/proto.h

index e8648897c6391e123997bf4cd1e826abbbcac2d7..743886a330a157ffa90d4c26229458df2a9b976c 100644 (file)
@@ -394,35 +394,6 @@ size_t vm_lookup_range(const struct proc *proc, vir_bytes vir_addr,
        return MIN(bytes, len);
 }
 
-/*===========================================================================*
- *                              vm_suspend                                *
- *===========================================================================*/
-static void vm_suspend(struct proc *caller, const struct proc *target,
-       const vir_bytes linaddr, const vir_bytes len, const int type,
-       const int writeflag)
-{
-       /* This range is not OK for this process. Set parameters  
-        * of the request and notify VM about the pending request. 
-        */                                                             
-       assert(!RTS_ISSET(caller, RTS_VMREQUEST));
-       assert(!RTS_ISSET(target, RTS_VMREQUEST));
-
-       RTS_SET(caller, RTS_VMREQUEST);
-
-       caller->p_vmrequest.req_type = VMPTYPE_CHECK;
-       caller->p_vmrequest.target = target->p_endpoint;
-       caller->p_vmrequest.params.check.start = linaddr;
-       caller->p_vmrequest.params.check.length = len;
-       caller->p_vmrequest.params.check.writeflag = writeflag;
-       caller->p_vmrequest.type = type;
-                                                       
-       /* Connect caller on vmrequest wait queue. */   
-       if(!(caller->p_vmrequest.nextrequestor = vmrequest))
-               if(OK != send_sig(VM_PROC_NR, SIGKMEM))
-                       panic("send_sig failed");
-       vmrequest = caller;
-}
-
 /*===========================================================================*
  *                             vm_check_range                               *
  *===========================================================================*/
@@ -449,35 +420,6 @@ int vm_check_range(struct proc *caller, struct proc *target,
        return VMSUSPEND;
 }
 
-/*===========================================================================*
- *                              delivermsg                                *
- *===========================================================================*/
-void delivermsg(struct proc *rp)
-{
-       int r = OK;
-
-       assert(rp->p_misc_flags & MF_DELIVERMSG);
-       assert(rp->p_delivermsg.m_source != NONE);
-
-       if (copy_msg_to_user(&rp->p_delivermsg,
-                               (message *) rp->p_delivermsg_vir)) {
-               printf("WARNING wrong user pointer 0x%08lx from "
-                               "process %s / %d\n",
-                               rp->p_delivermsg_vir,
-                               rp->p_name,
-                               rp->p_endpoint);
-               r = EFAULT;
-       }
-
-       /* Indicate message has been delivered; address is 'used'. */
-       rp->p_delivermsg.m_source = NONE;
-       rp->p_misc_flags &= ~MF_DELIVERMSG;
-
-       if(!(rp->p_misc_flags & MF_CONTEXT_SET)) {
-               rp->p_reg.retreg = r;
-       }
-}
-
 /*===========================================================================*
  *                                 vmmemset                                  *
  *===========================================================================*/
index b07d685f403dea60aa1bac9630376f976fcdee46..57ca4ce9c89c8f99da142b0bf9c5a099a2a856b3 100644 (file)
@@ -421,37 +421,6 @@ size_t vm_lookup_range(const struct proc *proc, vir_bytes vir_addr,
        return MIN(bytes, len);
 }
 
-/*===========================================================================*
- *                              vm_suspend                                *
- *===========================================================================*/
-static void vm_suspend(struct proc *caller, const struct proc *target,
-       const vir_bytes linaddr, const vir_bytes len, const int type,
-       const int writeflag)
-{
-       /* This range is not OK for this process. Set parameters  
-        * of the request and notify VM about the pending request. 
-        */                                                             
-       assert(!RTS_ISSET(caller, RTS_VMREQUEST));
-       assert(!RTS_ISSET(target, RTS_VMREQUEST));
-
-       RTS_SET(caller, RTS_VMREQUEST);
-
-       assert(caller->p_endpoint != VM_PROC_NR);
-
-       caller->p_vmrequest.req_type = VMPTYPE_CHECK;
-       caller->p_vmrequest.target = target->p_endpoint;
-       caller->p_vmrequest.params.check.start = linaddr;
-       caller->p_vmrequest.params.check.length = len;
-       caller->p_vmrequest.params.check.writeflag = writeflag;
-       caller->p_vmrequest.type = type;
-                                                       
-       /* Connect caller on vmrequest wait queue. */   
-       if(!(caller->p_vmrequest.nextrequestor = vmrequest))
-               if(OK != send_sig(VM_PROC_NR, SIGKMEM))
-                       panic("send_sig failed");
-       vmrequest = caller;
-}
-
 /*===========================================================================*
  *                             vm_check_range                               *
  *===========================================================================*/
@@ -478,36 +447,6 @@ int vm_check_range(struct proc *caller, struct proc *target,
        return VMSUSPEND;
 }
 
-/*===========================================================================*
- *                              delivermsg                                *
- *===========================================================================*/
-void delivermsg(struct proc *rp)
-{
-       int r = OK;
-
-       assert(rp->p_misc_flags & MF_DELIVERMSG);
-       assert(rp->p_delivermsg.m_source != NONE);
-
-       if (copy_msg_to_user(&rp->p_delivermsg,
-                               (message *) rp->p_delivermsg_vir)) {
-               printf("WARNING wrong user pointer 0x%08lx from "
-                               "process %s / %d\n",
-                               rp->p_delivermsg_vir,
-                               rp->p_name,
-                               rp->p_endpoint);
-               cause_sig(rp->p_nr, SIGSEGV);
-               r = EFAULT;
-       }
-
-       /* Indicate message has been delivered; address is 'used'. */
-       rp->p_delivermsg.m_source = NONE;
-       rp->p_misc_flags &= ~MF_DELIVERMSG;
-
-       if(!(rp->p_misc_flags & MF_CONTEXT_SET)) {
-               rp->p_reg.retreg = r;
-       }
-}
-
 #if 0
 static char *flagstr(u32_t e, const int dir)
 {
index bc8458f4c146e5ba886ca3bc890320ab9a32fbf4..57864dbe6d7365fc758463f557db72a0bf01bce7 100644 (file)
@@ -231,6 +231,71 @@ static void idle(void)
         */
 }
 
+/*===========================================================================*
+ *                              vm_suspend                                *
+ *===========================================================================*/
+void vm_suspend(struct proc *caller, const struct proc *target,
+        const vir_bytes linaddr, const vir_bytes len, const int type,
+        const int writeflag)
+{
+        /* This range is not OK for this process. Set parameters
+         * of the request and notify VM about the pending request.
+         */
+        assert(!RTS_ISSET(caller, RTS_VMREQUEST));
+        assert(!RTS_ISSET(target, RTS_VMREQUEST));
+
+        RTS_SET(caller, RTS_VMREQUEST);
+
+        caller->p_vmrequest.req_type = VMPTYPE_CHECK;
+        caller->p_vmrequest.target = target->p_endpoint;
+        caller->p_vmrequest.params.check.start = linaddr;
+        caller->p_vmrequest.params.check.length = len;
+        caller->p_vmrequest.params.check.writeflag = writeflag;
+        caller->p_vmrequest.type = type;
+
+        /* Connect caller on vmrequest wait queue. */
+        if(!(caller->p_vmrequest.nextrequestor = vmrequest))
+                if(OK != send_sig(VM_PROC_NR, SIGKMEM))
+                        panic("send_sig failed");
+        vmrequest = caller;
+}
+
+/*===========================================================================*
+ *                              delivermsg                                *
+ *===========================================================================*/
+static void delivermsg(struct proc *rp)
+{
+        assert(!RTS_ISSET(rp, RTS_VMREQUEST));
+        assert(rp->p_misc_flags & MF_DELIVERMSG);
+        assert(rp->p_delivermsg.m_source != NONE);
+
+        if (copy_msg_to_user(&rp->p_delivermsg,
+                                (message *) rp->p_delivermsg_vir)) {
+                if(rp->p_misc_flags & MF_MSGFAILED) {
+                        /* 2nd consecutive failure means this won't succeed */
+                        printf("WARNING wrong user pointer 0x%08lx from "
+                                "process %s / %d\n",
+                                rp->p_delivermsg_vir,
+                                rp->p_name,
+                                rp->p_endpoint);
+                        cause_sig(rp->p_nr, SIGSEGV);
+                } else {
+                        /* 1st failure means we have to ask VM to handle it */
+                        vm_suspend(rp, rp, rp->p_delivermsg_vir,
+                                sizeof(message), VMSTYPE_DELIVERMSG, 1);
+                        rp->p_misc_flags |= MF_MSGFAILED;
+                }
+        } else {
+                /* Indicate message has been delivered; address is 'used'. */
+                rp->p_delivermsg.m_source = NONE;
+                rp->p_misc_flags &= ~(MF_DELIVERMSG|MF_MSGFAILED);
+
+                if(!(rp->p_misc_flags & MF_CONTEXT_SET)) {
+                        rp->p_reg.retreg = OK;
+                }
+        }
+}
+
 /*===========================================================================*
  *                             switch_to_user                               * 
  *===========================================================================*/
index 559e3585044e2eefaafd001d30da450ab03e27dc..3b80630d68da4b57bc820468b88eac494681893d 100644 (file)
@@ -255,6 +255,7 @@ struct proc {
                                    because of VM modifying the sender's address
                                    space*/
 #define MF_STEP                 0x40000 /* Single-step process */
+#define MF_MSGFAILED    0x80000
 
 /* Magic process table addresses. */
 #define BEG_PROC_ADDR (&proc[0])
index e0161879b9adb3fb0dd9fe6530d7af85c1f3efa2..cc5d8414a508256f47c2d4223d63cdd50ee08de5 100644 (file)
@@ -59,6 +59,9 @@ int has_pending_notify(struct proc * caller, int src_p);
 int has_pending_asend(struct proc * caller, int src_p);
 void unset_notify_pending(struct proc * caller, int src_p);
 int mini_notify(const struct proc *src, endpoint_t dst);
+void vm_suspend(struct proc *caller, const struct proc *target,
+        const vir_bytes linaddr, const vir_bytes len, const int type,
+        const int writeflag);
 void enqueue(struct proc *rp);
 void dequeue(struct proc *rp);
 void switch_to_user(void);
@@ -215,7 +218,6 @@ int vm_lookup(const struct proc *proc, vir_bytes virtual, phys_bytes
        *result, u32_t *ptent);
 size_t vm_lookup_range(const struct proc *proc,
        vir_bytes vir_addr, phys_bytes *phys_addr, size_t bytes);
-void delivermsg(struct proc *target);
 void arch_do_syscall(struct proc *proc);
 int arch_phys_map(int index, phys_bytes *addr, phys_bytes *len, int
        *flags);