riscv_fork.c: Fix vfork() for kernel mode + SMP

There was an error in the fork() routine when system calls are in use:
the child context is saved on the child's user stack, which is incorrect,
the context must be saved on the kernel stack instead.

The result is a full system crash if (when) the child executes on a
different CPU which does not have the same MMU mappings active.
diff --git a/arch/risc-v/src/common/riscv_fork.c b/arch/risc-v/src/common/riscv_fork.c
index 896d8d4..6f17f8d 100644
--- a/arch/risc-v/src/common/riscv_fork.c
+++ b/arch/risc-v/src/common/riscv_fork.c
@@ -133,34 +133,48 @@
   DEBUGASSERT(stacktop > parent->xcp.regs[REG_SP]);
   stackutil = stacktop - parent->xcp.regs[REG_SP];
 
-  /* Copy the parent stack contents (overwrites child's SP and TP) */
+  /* Copy goes to child's user stack top */
 
   newtop = (uintptr_t)child->cmn.stack_base_ptr + child->cmn.adj_stack_size;
   newsp = newtop - stackutil;
 
+  memcpy((void *)newsp, (const void *)parent->xcp.regs[REG_SP], stackutil);
+
 #ifdef CONFIG_SCHED_THREAD_LOCAL
   /* Save child's thread pointer */
 
   tp = child->cmn.xcp.regs[REG_TP];
 #endif
 
-  /* Set up frame for context and copy the parent's user context there */
+  /* Determine the integer context save area */
 
-  memcpy((void *)(newsp - XCPTCONTEXT_SIZE),
-         parent->xcp.regs, XCPTCONTEXT_SIZE);
+#ifdef CONFIG_ARCH_KERNEL_STACK
+  if (child->cmn.xcp.kstack)
+    {
+      /* Set context to kernel stack */
+
+      stacktop = (uintptr_t)child->cmn.xcp.ktopstk;
+    }
+  else
+#endif
+    {
+      /* Set context to user stack */
+
+      stacktop = newsp;
+    }
+
+  /* Set the new register restore area to the new stack top */
+
+  child->cmn.xcp.regs = (void *)(stacktop - XCPTCONTEXT_SIZE);
+
+  /* Copy the parent integer context (overwrites child's SP and TP) */
+
+  memcpy(child->cmn.xcp.regs, parent->xcp.regs, XCPTCONTEXT_SIZE);
 
   /* Save FPU */
 
   riscv_savefpu(child->cmn.xcp.regs, riscv_fpuregs(&child->cmn));
 
-  /* Copy the parent stack contents */
-
-  memcpy((void *)newsp, (const void *)parent->xcp.regs[REG_SP], stackutil);
-
-  /* Set the new register restore area to the new stack top */
-
-  child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);
-
   /* Return 0 to child */
 
   child->cmn.xcp.regs[REG_A0] = 0;