Trap.c
unknown
plain_text
5 months ago
5.1 kB
11
Indexable
void trap(struct trapframe *tf) { int va; char* mem; if(tf->trapno == T_SYSCALL){ if(myproc()->killed) exit(); myproc()->tf = tf; syscall(); if(myproc()->killed) exit(); return; } switch(tf->trapno){ case T_IRQ0 + IRQ_TIMER: if(cpuid() == 0){ acquire(&tickslock); ticks++; wakeup(&ticks); release(&tickslock); } lapiceoi(); break; case T_IRQ0 + IRQ_IDE: ideintr(); lapiceoi(); break; case T_IRQ0 + IRQ_IDE+1: // Bochs generates spurious IDE1 interrupts. break; case T_IRQ0 + IRQ_KBD: kbdintr(); lapiceoi(); break; case T_IRQ0 + IRQ_COM1: uartintr(); lapiceoi(); break; case T_IRQ0 + 7: case T_IRQ0 + IRQ_SPURIOUS: cprintf("cpu%d: spurious interrupt at %x:%x\n", cpuid(), tf->cs, tf->eip); lapiceoi(); break; case T_PGFLT: #ifdef LAZY va = rcr2(); struct proc *curproc = myproc(); //cprintf("[LAZY] Pagefault Occured for pid: %d\n", curproc->pid); va = PGROUNDDOWN(va); if(va <= curproc->sz){ mem = kalloc(); if(mem == 0){ //cprintf("[LAZY] Out of memory for pid %d\n", curproc->pid); myproc()->killed = 1; }else{ memset(mem, 0, PGSIZE); if(mappages(curproc->pgdir, (char*)va, PGSIZE, V2P(mem), PTE_W|PTE_U) < 0){ //cprintf("[LAZY] Mapping failed for pid %d at va %x\n", curproc->pid, va); myproc()->killed = 1; }else{ //cprintf("[LAZY] Allocated and mapped page: pid %d va %x\n", curproc->pid, va); break; } } }else{ cprintf("pid %d %s: trap %d err %d on cpu %d " "eip 0x%x addr 0x%x--kill proc\n", myproc()->pid, myproc()->name, tf->trapno, tf->err, cpuid(), tf->eip, rcr2()); myproc()->killed = 1; } #endif #ifdef LOCALITY va = rcr2(); // Get the faulting virtual address from CR2 register struct proc *curproc = myproc(); // Current process //cprintf("[LOCALITY] Pagefault Occured for pid: %d\n", curproc->pid); va = PGROUNDDOWN(va); // Align the address to the nearest page boundary // Check if the faulting address is valid if (va >= curproc->sz || va >= KERNBASE) { //cprintf("[LOCALITY] Invalid page fault address: pid %d va %x\n", curproc->pid, va); curproc->killed = 1; // Kill the process for invalid access break; } // Allocate and map the faulting page and two subsequent pages for (int i = 0; i < 3; i++) { uint new_va = va + i * PGSIZE; // Compute the virtual address for each page // Ensure the new address is within the process size /*if (new_va > curproc->sz){ cprintf("[LOCALITY] Cannot allocate new address(%d) > process size(%d)\n",new_va, curproc->sz); break; }*/ // Check if the page is already mapped pte_t *pte = walkpgdir(curproc->pgdir, (void*)new_va, 0); if (pte && (*pte & PTE_P)) // Skip if already mapped continue; // Allocate physical memory mem = kalloc(); if (mem == 0) { //cprintf("[LOCALITY] Out of memory for pid %d\n", curproc->pid); curproc->killed = 1; // Kill process on memory allocation failure break; } memset(mem, 0, PGSIZE); // Clear the allocated memory // Map the page to the process's address space if (mappages(curproc->pgdir, (void*)new_va, PGSIZE, V2P(mem), PTE_W | PTE_U) < 0) { kfree(mem); // Free memory if mapping fails //cprintf("[LOCALITY] Mapping failed for pid %d at va %x\n", curproc->pid, new_va); curproc->killed = 1; break; } /*else{ //cprintf("[LOCALITY] Allocated and mapped page: pid %d va %x\n", curproc->pid, new_va); //break; }*/ } #endif break; //PAGEBREAK: 13 default: if(myproc() == 0 || (tf->cs&3) == 0){ // In kernel, it must be our mistake. cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", tf->trapno, cpuid(), tf->eip, rcr2()); panic("trap"); } // In user space, assume process misbehaved. cprintf("pid %d %s: trap %d err %d on cpu %d " "eip 0x%x addr 0x%x--kill proc\n", myproc()->pid, myproc()->name, tf->trapno, tf->err, cpuid(), tf->eip, rcr2()); myproc()->killed = 1; } // Force process exit if it has been killed and is in user space. // (If it is still executing in the kernel, let it keep running // until it gets to the regular system call return.) if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER) exit(); #if !defined(SJF) && !defined(PRIORITY) // Force process to give up CPU on clock tick. // If interrupts were on while locks held, would need to check nlock. if(myproc() && myproc()->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) yield(); #endif // Check if the process has been killed since we yielded if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER) exit(); }
Editor is loading...
Leave a Comment