]> Devi Nivas Git - cs3210-lab1.git/commitdiff
overkill: use segments to catch stack overflow (delete before next year)
authorrsc <rsc>
Thu, 27 Sep 2007 19:39:10 +0000 (19:39 +0000)
committerrsc <rsc>
Thu, 27 Sep 2007 19:39:10 +0000 (19:39 +0000)
proc.c
proc.h
swtch.S

diff --git a/proc.c b/proc.c
index d060445db959b6d23a672e907192da91c1476336..b80a08ec9cf2be6d1dc2f2328f4581f7a605d87f 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -73,7 +73,7 @@ setupsegs(struct proc *p)
   
   splhi();
   c = &cpus[cpu()];
-  c->ts.ss0 = SEG_KDATA << 3;
+  c->ts.ss0 = SEG_PROCSTACK << 3;
   if(p)
     c->ts.esp0 = (uint)(p->kstack + KSTACKSIZE);
   else
@@ -84,12 +84,15 @@ setupsegs(struct proc *p)
   c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
   c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0);
   c->gdt[SEG_TSS].s = 0;
+  c->gdt[SEG_CPUSTACK] = SEG(STA_W|STA_E, 0, (uint)c->stack, 0);
   if(p){
     c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)p->mem, p->sz-1, DPL_USER);
     c->gdt[SEG_UDATA] = SEG(STA_W, (uint)p->mem, p->sz-1, DPL_USER);
+    c->gdt[SEG_PROCSTACK] = SEG(STA_W|STA_E, 0, (uint)p->kstack, 0);
   } else {
     c->gdt[SEG_UCODE] = SEG_NULL;
     c->gdt[SEG_UDATA] = SEG_NULL;
+    c->gdt[SEG_PROCSTACK] = SEG_NULL;
   }
 
   lgdt(c->gdt, sizeof(c->gdt));
@@ -140,6 +143,7 @@ copyproc(struct proc *p)
   memset(&np->context, 0, sizeof(np->context));
   np->context.eip = (uint)forkret;
   np->context.esp = (uint)np->tf;
+  np->context.ss = SEG_PROCSTACK<<3;
 
   // Clear %eax so that fork system call returns 0 in child.
   np->tf->eax = 0;
diff --git a/proc.h b/proc.h
index 57fb4d96711b265481e8d27ca33f6368424773d0..285f6bf210c75fca78567d70a8000f07f0f0775b 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -4,7 +4,9 @@
 #define SEG_UCODE 3
 #define SEG_UDATA 4
 #define SEG_TSS   5  // this process's task state
-#define NSEGS     6
+#define SEG_CPUSTACK 6
+#define SEG_PROCSTACK 7
+#define NSEGS     8
 
 // Saved registers for kernel context switches.
 // Don't need to save all the %fs etc. segment registers,
@@ -22,6 +24,7 @@ struct context {
   int esi;
   int edi;
   int ebp;
+  int ss;
 };
 
 enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
diff --git a/swtch.S b/swtch.S
index 786e9ac3c1e3de377c349f08b86fc61fc416ee6b..8aa4c2edcc7ac684b9ae42170acfa34d136f6ebc 100644 (file)
--- a/swtch.S
+++ b/swtch.S
@@ -16,10 +16,14 @@ swtch:
   movl %esi, 20(%eax)
   movl %edi, 24(%eax)
   movl %ebp, 28(%eax)
+  movl %ss, %ebx
+  movl %ebx, 32(%eax)
 
   # Load new registers
   movl 4(%esp), %eax  # not 8(%esp) - popped return address above
 
+  movl 32(%eax), %ebx
+  movl %ebx, %ss
   movl 28(%eax), %ebp
   movl 24(%eax), %edi
   movl 20(%eax), %esi