]> Devi Nivas Git - cs3210-lab1.git/commitdiff
Fix long-standing switchuvm() inconsistency.
authorPeter Froehlich <peter.hans.froehlich@gmail.com>
Fri, 23 Dec 2016 01:26:37 +0000 (20:26 -0500)
committerFrans Kaashoek <kaashoek@mit.edu>
Tue, 31 Jan 2017 00:31:24 +0000 (19:31 -0500)
switchuvm() is supposed to switch the TSS and page table to the
process p it is passed. Alas, instead of using p to access the
kstack field, it used the global proc. This worked fine because
(a) most uses of switchuvm() pass proc anyway and (b) because in
the schedule, where we call switchuvm with the newly scheduled
process, we actually set the global proc before the call. But I
think it's still a bug, even if it never broke a test case. :-)

vm.c

diff --git a/vm.c b/vm.c
index 764512cfec66b11b1d360a72515c57c6a3466e7e..9db8b67826e22f56cbf9bd2823806c283323a08b 100644 (file)
--- a/vm.c
+++ b/vm.c
@@ -163,17 +163,22 @@ switchkvm(void)
 void
 switchuvm(struct proc *p)
 {
+  if(p == 0)
+    panic("switchuvm: no process");
+  if(p->kstack == 0)
+    panic("switchuvm: no kstack");
+  if(p->pgdir == 0)
+    panic("switchuvm: no pgdir");
+
   pushcli();
   cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0);
   cpu->gdt[SEG_TSS].s = 0;
   cpu->ts.ss0 = SEG_KDATA << 3;
-  cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE;
+  cpu->ts.esp0 = (uint)p->kstack + KSTACKSIZE;
   // setting IOPL=0 in eflags *and* iomb beyond the tss segment limit
   // forbids I/O instructions (e.g., inb and outb) from user space
   cpu->ts.iomb = (ushort) 0xFFFF;
   ltr(SEG_TSS << 3);
-  if(p->pgdir == 0)
-    panic("switchuvm: no pgdir");
   lcr3(V2P(p->pgdir));  // switch to process's address space
   popcli();
 }