Skip to content

Commit

Permalink
Fix long-standing switchuvm() inconsistency.
Browse files Browse the repository at this point in the history
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. :-)
  • Loading branch information
phf authored and kaashoek committed Jan 31, 2017
1 parent e916d66 commit 8d1f996
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down

0 comments on commit 8d1f996

Please sign in to comment.