Fix long-standing switchuvm() inconsistency.
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. :-)
This commit is contained in:
		
							parent
							
								
									e916d668f7
								
							
						
					
					
						commit
						8d1f99637a
					
				
					 1 changed files with 8 additions and 3 deletions
				
			
		
							
								
								
									
										11
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue