Proc refcnting wrappers
[akaros.git] / kern / arch / i686 / process.c
index 06aa9cd..ddae33d 100644 (file)
@@ -8,19 +8,11 @@
 #include <assert.h>
 #include <stdio.h>
 
-// architecture-specific process initialization code
-void proc_init_arch(struct proc *SAFE p)
-{
-}
-
-// architecture-specific process termination code
-void proc_free_arch(struct proc *SAFE p)
-{
-}
-
 void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
                          uint32_t entryp, uint32_t stack_top)
 {
+       memset(tf,0,sizeof(*tf));
+
        /* Set up appropriate initial values for the segment registers.
         * GD_UD is the user data segment selector in the GDT, and
         * GD_UT is the user text segment selector (see inc/memlayout.h).
@@ -29,7 +21,7 @@ void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
        tf->tf_ds = GD_UD | 3;
        tf->tf_es = GD_UD | 3;
        tf->tf_ss = GD_UD | 3;
-       tf->tf_esp = stack_top;
+       tf->tf_esp = stack_top-64;
        tf->tf_cs = GD_UT | 3;
        /* set the env's EFLAGSs to have interrupts enabled */
        tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
@@ -41,10 +33,32 @@ void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
        tf->tf_regs.reg_eax = vcoreid;
 }
 
-/* For cases that we won't return from a syscall via the normal path, and need
- * to set the syscall return value in the registers manually.  Like in a syscall
- * moving to RUNNING_M */
-void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value)
+void proc_secure_trapframe(struct trapframe *tf)
+{
+       /* we normally don't need to set the non-CS regs, but they could be
+        * gibberish and cause a GPF.  gs can still be gibberish, but we don't
+        * necessarily know what it ought to be (we could check, but that's a pain).
+        * the code protecting the kernel from TLS related things ought to be able
+        * to handle GPFs on popping gs. TODO: (TLSV) */
+       tf->tf_ds = GD_UD | 3;
+       tf->tf_es = GD_UD | 3;
+       tf->tf_fs = 0;
+       //tf->tf_gs = whatevs.  ignoring this.
+       tf->tf_ss = GD_UD | 3;
+       tf->tf_cs ? GD_UT | 3 : 0; // can be 0 for sysenter TFs.
+       tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
+}
+
+/* Called when we are currently running an address space on our core and want to
+ * abandon it.  We need a known good pgdir before releasing the old one.  We
+ * decref, since current no longer tracks the proc (and current no longer
+ * protects the cr3).  We also need to clear out the TLS registers (before
+ * unmapping the address space!) */
+void __abandon_core(void)
 {
-       tf->tf_regs.reg_eax = value;
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       asm volatile ("movw %%ax,%%gs; lldt %%ax" :: "a"(0));
+       lcr3(boot_cr3);
+       proc_decref(pcpui->cur_proc);
+       pcpui->cur_proc = 0;
 }