Ejemplo n.º 1
0
void show_regs(struct pt_regs * regs)
{
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;

	printk("\n");
	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
	printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
	print_symbol("EIP is at %s\n", regs->eip);

	if (user_mode_vm(regs))
		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
	printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
	       regs->eflags, print_tainted(), system_utsname.release,
	       (int)strcspn(system_utsname.version, " "),
	       system_utsname.version);
	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->eax,regs->ebx,regs->ecx,regs->edx);
	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
		regs->esi, regs->edi, regs->ebp);
	printk(" DS: %04x ES: %04x\n",
		0xffff & regs->xds,0xffff & regs->xes);

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4_safe();
	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
	show_trace(NULL, regs, &regs->esp);
}
Ejemplo n.º 2
0
/*H:040
 * This is the i386-specific code to setup and run the Guest.  Interrupts
 * are disabled: we own the CPU.
 */
void lguest_arch_run_guest(struct lg_cpu *cpu)
{
	/*
	 * Remember the awfully-named TS bit?  If the Guest has asked to set it
	 * we set it now, so we can trap and pass that trap to the Guest if it
	 * uses the FPU.
	 */
	if (cpu->ts && user_has_fpu())
		stts();

	/*
	 * SYSENTER is an optimized way of doing system calls.  We can't allow
	 * it because it always jumps to privilege level 0.  A normal Guest
	 * won't try it because we don't advertise it in CPUID, but a malicious
	 * Guest (or malicious Guest userspace program) could, so we tell the
	 * CPU to disable it before running the Guest.
	 */
	if (boot_cpu_has(X86_FEATURE_SEP))
		wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);

	/*
	 * Now we actually run the Guest.  It will return when something
	 * interesting happens, and we can examine its registers to see what it
	 * was doing.
	 */
	run_guest_once(cpu, lguest_pages(raw_smp_processor_id()));

	/*
	 * Note that the "regs" structure contains two extra entries which are
	 * not really registers: a trap number which says what interrupt or
	 * trap made the switcher code come back, and an error code which some
	 * traps set.
	 */

	 /* Restore SYSENTER if it's supposed to be on. */
	 if (boot_cpu_has(X86_FEATURE_SEP))
		wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);

	/* Clear the host TS bit if it was set above. */
	if (cpu->ts && user_has_fpu())
		clts();

	/*
	 * If the Guest page faulted, then the cr2 register will tell us the
	 * bad virtual address.  We have to grab this now, because once we
	 * re-enable interrupts an interrupt could fault and thus overwrite
	 * cr2, or we could even move off to a different CPU.
	 */
	if (cpu->regs->trapnum == 14)
		cpu->arch.last_pagefault = read_cr2();
	/*
	 * Similarly, if we took a trap because the Guest used the FPU,
	 * we have to restore the FPU it expects to see.
	 * math_state_restore() may sleep and we may even move off to
	 * a different CPU. So all the critical stuff should be done
	 * before this.
	 */
	else if (cpu->regs->trapnum == 7 && !user_has_fpu())
		math_state_restore();
}
Ejemplo n.º 3
0
static void __save_processor_state(struct saved_context *ctxt)
{
	mtrr_save_fixed_ranges(NULL);
	kernel_fpu_begin();

	/*
	 * descriptor tables
	 */
	store_gdt(&ctxt->gdt);
	store_idt(&ctxt->idt);
	store_tr(ctxt->tr);

	/*
	 * segment registers
	 */
	savesegment(es, ctxt->es);
	savesegment(fs, ctxt->fs);
	savesegment(gs, ctxt->gs);
	savesegment(ss, ctxt->ss);

	/*
	 * control registers
	 */
	ctxt->cr0 = read_cr0();
	ctxt->cr2 = read_cr2();
	ctxt->cr3 = read_cr3();
	ctxt->cr4 = read_cr4_safe();
}
Ejemplo n.º 4
0
void
do_page_fault(struct pt_regs *regs, unsigned int vector)
{
	/* Kernel space exception fixup check */
	if (fixup_exception(regs))
		return;

	unsigned long cr2 = read_cr2();

#ifdef CONFIG_KGDB
	kgdb_breakpoint();
#endif

	struct siginfo s;
	memset(&s, 0, sizeof(struct siginfo));
	s.si_signo = SIGSEGV;
	s.si_errno = 0;
	s.si_addr  = (void *)cr2;
	s.si_code  = SEGV_ACCERR; // SEGV_MAPERR;

	int i = sigsend(current->aspace->id, ANY_ID, SIGSEGV, &s);
	printk(">> PAGE FAULT! Sent signal %d. CR2 is %p, cpu %d\n", i, (void *)cr2, this_cpu);
	show_registers(regs);

	/* If the fault occurred in kernel space, or the init_task, go down */
	if ( (regs->rip >= PAGE_OFFSET) ||
	     (current->aspace->id == INIT_ASPACE_ID)) 
	{
		local_irq_disable();
		halt();
	}
}
Ejemplo n.º 5
0
void PageTable::handle_fault(REGS * _r)
{
    /* Page fault handler */
    
    //Console::puts("Page Fault Handler Called\n");
    unsigned long addr = 0, page_dir_index = 0, page_table_index = 0, page_offset = 0;
    unsigned long page_fault_dir = read_cr2();
    //Console::puts("Virtual Address = ");
    Console::putui(page_fault_dir);

    /* Page directory index is stored in the first 10 bits of the virtual address */ 
    page_dir_index   = SHIFT_RIGHT (page_fault_dir, PAGE_DIR_SHIFT) & 0x3FF;

    /* Page table index is stored in the second 10 bits of the virtual address */ 
    page_table_index = SHIFT_RIGHT (page_fault_dir, PAGE_TABLE_SHIFT) & 0x3FF;

    /* Page offset is stored in the first 12 bits of the virtual address */
    page_offset = page_fault_dir & 0xFFF;

    if ((current_page_table->page_directory[page_dir_index] & 0x1) == 0)
    /* The page table is not present in the page directory. 
     * So allocate a frame from the kernel frame pool and mark the page as present.
     */
    {
        current_page_table->page_directory[page_dir_index] = ((PageTable::kernel_mem_pool->get_frame()) * PageTable::PAGE_SIZE ) | 3;    
    }
    ((unsigned long*)((current_page_table->page_directory[page_dir_index]) & 0xFFFFF000) )[page_table_index] = ( (PageTable::process_mem_pool->get_frame()) * (PageTable::PAGE_SIZE)) | 3;
    
}
void PageTable::handle_fault(REGS * _r)
{
	if(!(_r->err_code & 0x2))
			Console::puts("It's read only.\n");
	if(!(_r->err_code & 0x1)) //if the requested page is not in memory
	{
		unsigned long virtualaddr=read_cr2();
		unsigned long pdindex=virtualaddr>>22;           //we need first 10bit 
		unsigned long * pd=(unsigned long *)read_cr3(); //get physical memory address which is also vm address of page directory
		
		
		Console::putui((unsigned int)pd[pdindex]);
		if((pd[pdindex] & 0x1)==0) //pagetable is not present
		{
			
			pd[pdindex]=(kernel_mem_pool->get_frame()*4096) | 3; //request frame address for storing page table,
															//by calling kernel_mem_pool, we assume pagetable for a process reside in kernel memory
			/*pt=(unsigned long *)(pd[pdindex] & 0xFFFFF000); 
			for(unsigned long i;i<=1023;i++)
				pt[i]=2;*/
		} 
		unsigned long * pt=(unsigned long *)(pd[pdindex] & 0xFFFFF000); 
		//Console::putui((unsigned int)pd[pdindex]);
		unsigned long ptindex=(virtualaddr>>12) & 0x03FF;   //we need next 10bit in the middle
			
		pt[ptindex]=(process_mem_pool->get_frame()*4096) | 3; //request frame address for storing the page
		//Console::putui((unsigned int)pt[ptindex]);
		//for(;;);
	}
Ejemplo n.º 7
0
/*-------------------------------------------------------------------------
 * pfint - paging fault ISR
 *-------------------------------------------------------------------------
 */
SYSCALL pfint()
{
  kprintf("---------ISR----------\n");

  unsigned int pfaddr = read_cr2();// faulted address 
  //Check that pfaddr is a legal address ????

  unsigned int pdbaddr = read_cr3()&(~0xfff); //page directory base address
  
  unsigned int p = pfaddr >> 22; // upper ten bits of faulted address
  unsigned int q = (pfaddr >> 12)&0x3ff; // middle ten bits of faulted address
  unsigned int offset = pfaddr & 0xfff; // last twelve bits

  pd_t * pt = (pd_t *)pdbaddr + p ; //pth page table 
  //kprintf("%x\n",*pt);
  if(pt->pd_pres == 0)  // if page table is not present
  {
      int frm_num = get_frm(1,FR_TBL,pfaddr>>12);
      //kprintf("%d\n",frm_num);

      if(frm_num == SYSERR)
          return SYSERR;
      pt->pd_base = (0x00400000 + frm_num*4096) >> 12;
      pt->pd_pres = 1;
      write_cr3(pdbaddr);
        kprintf("faulted addr: %x xth page table: %x, content: %x\n",pfaddr,pt,p);
      return OK;
  }
Ejemplo n.º 8
0
/**	
	@brief Page fault handler
*/
asmregparm void do_page_fault(struct pt_regs * regs, long error_code)
{
	unsigned long error_address = read_cr2();	
	bool in_user = address_in_user(error_address);
	struct ko_thread *current;	 

	//printk("PAGE fault: eip %x addr %x code %x\n", regs->ip, error_address, error_code);
	/*
		Access violation.
		读、写和u/s异常
		如果是用户模式,那么访问核心层空间时崩溃,其他地方尝试修复
		如果是特权模式,都尝试修复
	*/
	if (error_code & PAGE_FAULT_U)
	{
		if (in_user == false)
			goto die_cur;
	}
	
	current = kt_current();
	if (unlikely(false == ks_exception(current, error_address, error_code)))
		goto die_cur;

	return;	

die_cur:
	printk("TODO: Thread deing :eip %x addr %x code %x\n", regs->ip, error_address, error_code);

	//TODO kill thread
	//fak_arch_x86_dump_register(regs);
	kt_delete_current();
}
Ejemplo n.º 9
0
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
    unsigned long addr = read_cr2();
    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };

    if ((error_code & TRAP_PF_WRITE) && handle_cow(addr))
	return;

    /* If we are already handling a page fault, and got another one
       that means we faulted in pagetable walk. Continuing here would cause
       a recursive fault */       
    if(handling_pg_fault == 1) 
    {
        printk("Page fault in pagetable walk (access to invalid memory?).\n"); 
        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
    }
    handling_pg_fault++;
    barrier();

    printk("Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx\n",
           addr, regs->rip, regs, regs->rsp, &addr, error_code);

    dump_regs(regs);
    //do_stack_walk(regs->rbp);
    dump_mem(regs->rsp);
    dump_mem(regs->rbp);
    dump_mem(regs->rip);
    page_walk(addr);
    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
    /* We should never get here ... but still */
    handling_pg_fault--;
}
Ejemplo n.º 10
0
void
do_page_fault(struct pt_regs *regs, unsigned int vector)
{
	/* Kernel space exception fixup check */
	if (fixup_exception(regs))
		return;

	unsigned long cr2 = read_cr2();

#ifdef CONFIG_KGDB
	kgdb_breakpoint();
#endif

	struct siginfo s;
	memset(&s, 0, sizeof(struct siginfo));
	s.si_signo = SIGSEGV;
	s.si_errno = 0;
	s.si_addr  = (void *)cr2;
	s.si_code  = SEGV_ACCERR; // SEGV_MAPERR;

	int i = sigsend(current->aspace->id, ANY_ID, SIGSEGV, &s);
	printk(">> PAGE FAULT! Sent signal %d: CR2 is %p\n", i, s.si_addr);
	show_registers(regs);

	while (1) {}
}
Ejemplo n.º 11
0
void __show_registers(struct pt_regs *regs, int all)
{
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;
	unsigned long sp;
	unsigned short ss, gs;

	if (user_mode_vm(regs)) {
		sp = regs->sp;
		ss = regs->ss & 0xffff;
		savesegment(gs, gs);
	} else {
		sp = (unsigned long) (&regs->sp);
		savesegment(ss, ss);
		savesegment(gs, gs);
	}

	printk("\n");
	printk("Pid: %d, comm: %s %s (%s %.*s)\n",
			task_pid_nr(current), current->comm,
			print_tainted(), init_utsname()->release,
			(int)strcspn(init_utsname()->version, " "),
			init_utsname()->version);

	printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
			(u16)regs->cs, regs->ip, regs->flags,
			smp_processor_id());
	print_symbol("EIP is at %s\n", regs->ip);

	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->ax, regs->bx, regs->cx, regs->dx);
	printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->si, regs->di, regs->bp, sp);
	printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss);

	if (!all)
		return;

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4_safe();
	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	get_debugreg(d0, 0);
	get_debugreg(d1, 1);
	get_debugreg(d2, 2);
	get_debugreg(d3, 3);
	printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);

	get_debugreg(d6, 6);
	get_debugreg(d7, 7);
	printk("DR6: %08lx DR7: %08lx\n",
			d6, d7);
}
Ejemplo n.º 12
0
void __show_regs(struct pt_regs *regs, int all)
{
#ifdef NOT_FOR_L4
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;
#endif
	unsigned long sp;
	unsigned short ss, gs;

	if (user_mode_vm(regs)) {
		sp = regs->sp;
		ss = regs->ss & 0xffff;
		gs = get_user_gs(regs);
	} else {
		sp = kernel_stack_pointer(regs);
		savesegment(ss, ss);
		savesegment(gs, gs);
	}

	show_regs_common();

	printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
			(u16)regs->cs, regs->ip, regs->flags,
			smp_processor_id());
	print_symbol("EIP is at %s\n", regs->ip);

	printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->ax, regs->bx, regs->cx, regs->dx);
	printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->si, regs->di, regs->bp, sp);
	printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss);

	if (!all)
		return;

#ifdef NOT_FOR_L4
	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4_safe();
	printk(KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	get_debugreg(d0, 0);
	get_debugreg(d1, 1);
	get_debugreg(d2, 2);
	get_debugreg(d3, 3);
	printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);

	get_debugreg(d6, 6);
	get_debugreg(d7, 7);
	printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n",
			d6, d7);
#endif
}
Ejemplo n.º 13
0
void fault(struct tcb *tcb, struct ccb *ccb) {
	
	if (tcb->ivect == 32) {
		ccb->lapic->eoi = 0;

		scheduler_schedule();

		return;
	}

	if (tcb->ivect == 0x100) {

		if (tcb->rdi == 0 && tcb->state != TCB_STATE_RUNNING) {
			ccb_unload_tcb();
		}

		scheduler_schedule();

		return;
	}

	if (tcb->ivect == 14) {
		extern uint64_t read_cr2(void);
		log(ERROR, "page fault at addr %p (ip %p, sp %p, id %d)", read_cr2(), tcb->rip, tcb->rsp, tcb->id);
		log(ERROR, "translation: %p %p", pcx_get_trans(NULL, read_cr2()), pcx_get_flags(NULL, read_cr2()));

		queue_pagefault(ccb_unload_tcb());
		interrupt_vector_fire(__PINION_INTERRUPT_PAGEFAULT);
		scheduler_schedule();
		return;
	}

	if (tcb->ivect == 8) {
		log(ERROR, "PANIC: double fault");
		for(;;);
	}

	if (tcb->ivect < 32) {
		queue_miscfault(ccb_unload_tcb());
		interrupt_vector_fire(__PINION_INTERRUPT_MISCFAULT);
		scheduler_schedule();
		return;
	}
}
Ejemplo n.º 14
0
void __show_regs(struct pt_regs *regs, int all)
{
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;
	unsigned long sp;
	unsigned short ss, gs;

	if (user_mode(regs)) {
		sp = regs->sp;
		ss = regs->ss & 0xffff;
		gs = get_user_gs(regs);
	} else {
		sp = kernel_stack_pointer(regs);
		savesegment(ss, ss);
		savesegment(gs, gs);
	}

	printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
			(u16)regs->cs, regs->ip, regs->flags,
			smp_processor_id());
	print_symbol("EIP is at %s\n", regs->ip);

	printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->ax, regs->bx, regs->cx, regs->dx);
	printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->si, regs->di, regs->bp, sp);
	printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss);

	if (!all)
		return;

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = __read_cr4_safe();
	printk(KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	get_debugreg(d0, 0);
	get_debugreg(d1, 1);
	get_debugreg(d2, 2);
	get_debugreg(d3, 3);
	get_debugreg(d6, 6);
	get_debugreg(d7, 7);

	/* Only print out debug registers if they are in their non-default state. */
	if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
	    (d6 == DR6_RESERVED) && (d7 == 0x400))
		return;

	printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);
	printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n",
			d6, d7);
}
Ejemplo n.º 15
0
void FH_page_fault(struct fault_ctx *fctx)
{
  uintptr_t fault_addr, fixup_addr;
  struct intr_stack_frame *stack_frame = fctx->istack_frame;

  fault_addr = read_cr2();
  fixup_addr = fixup_fault_address(stack_frame->rip);
  if (IS_KERNEL_FAULT(fctx) && !fixup_addr) {
    display_unhandled_pf_info(fctx, fault_addr);
    goto stop_cpu;
  }
  else {
    vmm_t *vmm = current_task()->task_mm;
    uint32_t errmask = 0;
    int ret = -EFAULT;

    if (!PFAULT_READ(fctx->errcode))
      errmask |= PFLT_WRITE;
    if (PFAULT_NXE(fctx->errcode))
      errmask |= PFLT_NOEXEC;
    if (PFAULT_PROTECT(fctx->errcode))
      errmask |= PFLT_PROTECT;
    else
      errmask |= PFLT_NOT_PRESENT;

    ret = vmm_handle_page_fault(vmm, fault_addr, errmask);
    if (!ret) {
      return;
    }

    if (fixup_addr) {
      goto handle_fixup;
    }

    display_unhandled_pf_info(fctx, fault_addr);
#ifdef CONFIG_DUMP_VMM_ON_FAULT
    kprintf_fault("========= [Vrages Tree] =========");
    vmranges_print_tree_dbg(vmm);
#endif /* CONFIG_DUMP_VMM_ON_FAULT */

#ifdef CONFIG_SEND_SIGSEGV_ON_FAULTS
    send_sigsegv(fault_addr, ret);
    return;
#endif /* CONFIG_SEND_SIGSEGV_ON_FAULTS */
  }

stop_cpu:
  __stop_cpu();

handle_fixup:
  kprintf_fault("FIXUP = %p\n", fixup_addr);
  stack_frame->rip = fixup_addr;
  return;

}
Ejemplo n.º 16
0
dotraplinkage void do_page_fault(struct pt_regs *regs, long error_code)
{
	unsigned long address = read_cr2();

	__do_page_fault(regs, error_code, address);

	printk("BUG: unable to handle kernel paging request at %#lx\n", address);
	printk("CPU: %d PID: %u Comm: %s\n", smp_processor_id(), current->pid, current->comm);
	show_regs(regs);
	panic("panic at #PF");
}
Ejemplo n.º 17
0
void dump_regs(struct irq_regs *regs)
{
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;
	unsigned long sp;

	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
			(u16)regs->xcs, regs->eip, regs->eflags);

	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->eax, regs->ebx, regs->ecx, regs->edx);
	printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->esi, regs->edi, regs->ebp, regs->esp);
	printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs, (u16)regs->xgs, (u16)regs->xss);

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4();

	printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	d0 = get_debugreg(0);
	d1 = get_debugreg(1);
	d2 = get_debugreg(2);
	d3 = get_debugreg(3);

	printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);

	d6 = get_debugreg(6);
	d7 = get_debugreg(7);
	printf("DR6: %08lx DR7: %08lx\n",
			d6, d7);

	printf("Stack:\n");
	sp = regs->esp;

	sp += 64;

	while (sp > (regs->esp - 16)) {
		if (sp == regs->esp)
			printf("--->");
		else
			printf("    ");
		printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp));
		sp -= 4;
	}
}
Ejemplo n.º 18
0
void page_fault(unsigned int n, istate_t *istate)
{
	uintptr_t badvaddr = read_cr2();
	
	if (istate->error_word & PFERR_CODE_RSVD)
		panic("Reserved bit set in page table entry.");
	
	pf_access_t access;
	
	if (istate->error_word & PFERR_CODE_RW)
		access = PF_ACCESS_WRITE;
	else if (istate->error_word & PFERR_CODE_ID)
		access = PF_ACCESS_EXEC;
	else
		access = PF_ACCESS_READ;
	
	(void) as_page_fault(badvaddr, access, istate);
}
Ejemplo n.º 19
0
void PageTable::handle_fault(REGS* _r)
{
	/* check what exception? */
	unsigned long faulting_addr = read_cr2();

	/* compute the index of the page dir and page table */
	int page_dir_index = faulting_addr >> 22;
	int page_table_index = (faulting_addr >> 12) & MASK;

	/* Perform the recursive page dir trick */
	unsigned long* virt_page_directory = (unsigned long*)0xFFFFF000; 
	unsigned long* virt_page_table = 0;

	/* check the present bit of the dir */
	if(virt_page_directory[page_dir_index] == 2)
	{
		/* create page table, assign new frame for the faulting address */

		unsigned long frame = process_mem_pool->get_frame();
		// mark as present
		virt_page_directory[page_dir_index] = frame | 3;

		frame = process_mem_pool->get_frame();
		virt_page_table = (unsigned long*)(0xFFC00000 | (page_dir_index << 12));

		for(int i = 0; i < 1024; i++)
		//  mark as absent
			virt_page_table[i] = 0 | 2; 
		// mark as present the page containing the faulting addr
		virt_page_table[page_table_index] = frame | 3; 
	}
	else
	{
		// page table present, assign page

		unsigned long new_frame = process_mem_pool->get_frame_address(process_mem_pool->get_frame());
//		unsigned long new_frame = process_mem_pool->get_frame();
		virt_page_table = (unsigned long*)(0xFFC00000 | (page_dir_index << 12));
		// page containing the faulting address to be marked present	
		virt_page_table[page_table_index] = new_frame | 3; 
	}
}
Ejemplo n.º 20
0
void lguest_arch_run_guest(struct lg_cpu *cpu)
{
	if (cpu->ts)
		unlazy_fpu(current);

	if (boot_cpu_has(X86_FEATURE_SEP))
		wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);

	run_guest_once(cpu, lguest_pages(raw_smp_processor_id()));


	 
	 if (boot_cpu_has(X86_FEATURE_SEP))
		wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);

	if (cpu->regs->trapnum == 14)
		cpu->arch.last_pagefault = read_cr2();
	else if (cpu->regs->trapnum == 7)
		math_state_restore();
}
Ejemplo n.º 21
0
Archivo: isr.cpp Proyecto: tica/TimbOS
/* All of our Exception handling Interrupt Service Routines will
*  point to this function. This will tell us what exception has
*  happened! Right now, we simply halt the system by hitting an
*  endless loop. All ISRs disable interrupts while they are being
*  serviced as a 'locking' mechanism to prevent an IRQ from
*  happening and messing up kernel data structures */
extern "C" void fault_handler(struct cpu_state *r)
{
    if (r->int_no < 32)
    {
        bool handled = false;

        switch( r->int_no )
        {
        case 14: // Page fault
            handled = paging_handle_fault( r, read_cr2() );
            break;
        default:
            debug_bochs_printf( "EXCEPTION!" );
            debug_bochs_printf( " (%x) (err_code = %x)\n", r->int_no, r->err_code );
            debug_bochs_printf( "%s Exception\n", exception_messages[r->int_no] );
            break;
        }

        if( !handled )
        {
            debug_bochs_printf( "\nRegister dump:\n" );

            /*
            unsigned int gs, fs, es, ds;
            unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
            unsigned int int_no, err_code;
            unsigned int eip, cs, eflags, useresp, ss;
            */
            debug_bochs_printf( "EAX = %x EBX = %x ECX = %x EDX = %x\n", r->eax, r->ebx, r->ecx, r->edx );
            debug_bochs_printf( "ESP = %x EBP = %x ESI = %x EDI = %x\n", r->esp, r->ebp, r->esi, r->edi );
            debug_bochs_printf( "GS  = %x FS  = %x ES  = %x DS  = %x\n", r->gs, r->fs, r->es, r->ds );
            debug_bochs_printf( "EIP = %x CS  = %x EFLAGS = %x SS = %x\n", r->eip, r->cs, r->eflags, r->ss );

            debug_bochs_printf( "System Halted!\n" );


            for (;;);
        }
    }
}
Ejemplo n.º 22
0
/*-------------------------------------------------------------------------
 * pfint - paging fault ISR
 *-------------------------------------------------------------------------
 */
SYSCALL pfint() {
    STATWORD ps;
    disable(ps);
    
    int vp, p, q;
    int i;
    
    unsigned long fault_addr;
    
    int store, pageth;
    int new_frame, m_frame = -1;
    
   
    pt_t *ptr_pt;
    fault_addr = read_cr2();
    vp = (fault_addr & ~(NBPG - 1)) >> 12;
    
    //If  process tries to access bs that it has not got using getbs.
    if (bsm_lookup(currpid, fault_addr, &store, &pageth) == SYSERR) {
        kill(currpid);
    }


    pd_t *ptr_pd = (pd_t *) (proctab[currpid].pdbr);
    p = (fault_addr & 0xFFC00000) >> 22;
    q = (fault_addr & 0x003FF000) >> 12;

    ptr_pd = ptr_pd + p;
    if (ptr_pd->pd_pres == 0) {
        get_frm(&new_frame);

        frm_tab[new_frame].fr_pid = currpid; 
        frm_tab[new_frame].fr_type = FR_TBL;

        new_frame = new_frame + FRAME0;
        add_page_dir(ptr_pd, new_frame, ((proctab[currpid].pdbr & ~(NBPG - 1)) >> 12) - FRAME0);
       
    } else
Ejemplo n.º 23
0
void dump_regs(struct irq_regs *regs)
{
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;

	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
			(u16)regs->xcs, regs->eip, regs->eflags);

	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->eax, regs->ebx, regs->ecx, regs->edx);
	printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->esi, regs->edi, regs->ebp, regs->esp);
	printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs, (u16)regs->xgs, (u16)regs->xss);

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4();

	printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	d0 = get_debugreg(0);
	d1 = get_debugreg(1);
	d2 = get_debugreg(2);
	d3 = get_debugreg(3);

	printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);

	d6 = get_debugreg(6);
	d7 = get_debugreg(7);
	printf("DR6: %08lx DR7: %08lx\n",
			d6, d7);
}
Ejemplo n.º 24
0
SYSCALL pfint()
{
  	unsigned long cr2,physical_addr;
  	virt_addr_t * vaddr;
    int vp,s,o,avail,*store,*pageth;
  	unsigned int p,q,pt;
    pd_t *pd;
    pt_t *new_pt;
    STATWORD ps;
	// Disable interrupts
    disable(ps);
    if(GDB)
      kprintf("\n*************pfint is running!************\n");
  // Get the faulted address. The processor loads the CR2 register
  // with the 32-bit address that generated the exception.
  /* 1. Get the faulted address. */
    cr2 = read_cr2();
    vaddr = (virt_addr_t *)(&cr2); 
    if(GDB)
      kprintf("&cr2=%x, cr2=%x, &vaddr=%x, vaddr=%x\n",&cr2,cr2,&vaddr,vaddr);
  /* 2. Let 'vp' be the virtual page number of the page containing of the faulted address */
    vp = a2pno(cr2);
    if(GDB)
      kprintf("vp=%d,\n",vp);
  /* 3. Let pd point to the current page directory. */
    pd = proctab[currpid].pdbr;
    if(GDB)
      kprintf("pd=%x,\n",pd);
  /* 4. Check that a is a legal address (i.e., it has been mapped). 
     If it is not, print an error message and kill the process. */  
    pageth = getmem( sizeof(int *) );
    store = getmem( sizeof(int *) );
    if( SYSERR == bsm_lookup(currpid, vp, store, pageth)){
      kprintf("ERROR: This virtual address hasn't been mapped!\n");
      kill(currpid);
    }
  /* 5. Let p be the upper ten bits of a. [p represents page dirctory offset] */
  /* 6. Let q be the bits [21:12] of a. [p represents page table offset.]
  /* 7.1 Let pt point to the pth page table.*/
    p = vaddr->pd_offset;
    q = vaddr->pt_offset;
    pt = vaddr->pg_offset;
    if(GDB)
      kprintf("p=%d,q=%d,pt=%d\n",p,q,pt);
  /* 7.2  If the pth page table does not exist obtain a frame for it and initialize it. */
    if(pd[p].pd_pres != 1){
      if(GDB)
        kprintf("**obtain a frame for the new page table. \n");
      avail = get_frm();  //get the id of a new frame from frm_tab[];
      if (avail == -1) {
            if(GDB)
              kprintf("Could not create page table!\n");
            restore(ps);
            return SYSERR;
      }
      //initialize frame[avail], update the process_id and frame_type of this frame.
      init_frm(avail, currpid, FR_TBL);
      frm_tab[avail].fr_upper_t = pa2frid((unsigned long) pd);
      if(GDB)
        kprintf("upper page table @frame[%d]  pd=%x, a2pno(pd)=%d\n",frm_tab[avail].fr_upper_t, pd, a2pno((unsigned long) pd));
      new_pt = frid2pa(avail);
      init_pt(new_pt);
      //update this page_table_entry in the page_directory.
      pd[p].pd_pres = 1;
      pd[p].pd_write = 1;
      pd[p].pd_user = 0; // not sure about the usage;
      pd[p].pd_pwt = 0;
      pd[p].pd_pcd = 0;
      pd[p].pd_acc = 0;
      pd[p].pd_mbz = 0;
      pd[p].pd_fmb = 0;
      pd[p].pd_global = 0;
      pd[p].pd_avail = 0; // not in use right now.
      pd[p].pd_base = a2pno((unsigned long) new_pt);  /* location of page table */
      if(GDB)
        kprintf("New page_table(%x)@frame[%d] updated in page_directory[%d]@(frame[%d])\n",
        new_pt, avail, p, frm_tab[avail].fr_upper_t);
      if(GDB)
        kprintf("q=%d, new_pt[q]=%x, new_pt=%x, pd[p].pd_base=%d\n",
        q, new_pt[q], new_pt, pd[p].pd_base);
    }
    //if the page table has already existed, just need to refcnt++;
    else
    {
      int avail = pd[p].pd_base -1024;
      frm_tab[avail].fr_refcnt++;
      if(GDB)
        kprintf("frm_tab[%d].fr_refcnt = %d, frame_type: %d\n",avail, frm_tab[avail].fr_refcnt, frm_tab[avail].fr_type);
    }
/* 8.1 Using the backing store map, find the store s and page offset o which correspond to vp. */
    //already saved in 'store' and 'pageth'
    s = *store;
    o = *pageth;
/* 8.2 In the inverted page table increment the reference count of the frame which holds pt. 
   This indicates that one more of pt's entries is marked "present." */
    avail = find_frm(currpid,vp);
    if (avail == -1)
    {
      if(GDB)
        kprintf("allocating a page for the page fault\n");

      avail = get_frm();
      if(avail == -1)
      {
        if(GDB)
          kprintf("ATTENTION! Frames full. ###Replacement NEEDED!###\n");
        int frame_number = proctab[currpid].nframes-1;
        int frame_id = proc_frames[currpid][0];
        //update_proc_frames(pid,frame_number);
        int i;
        for (i = 0; i+1 < frame_number; ++i)
        {
          proc_frames[currpid][i] = proc_frames[currpid][i+1];
        }
        proctab[currpid].nframes = frame_number;

        int pid = frm_tab[frame_id].fr_pid;
        int upper_id = frm_tab[frame_id].fr_upper_t;    
        vp = frm_tab[frame_id].fr_vpno;
        if(GDB)
          kprintf("currpid=%d, frame[%d].pid=%d .vpno=%d, upper_frame[%d].ref=%d\n",currpid,frame_id,pid,vp,upper_id,frm_tab[upper_id].fr_refcnt);
        p = vp>>10;
        q = vp &0x003ff;        
        new_pt = vp2pa(pd[p].pd_base);
        new_pt[q].pt_pres  = 0;
        new_pt[q].pt_write = 1;
        new_pt[q].pt_base  = 0;
        if(GDB)
          kprintf("pd_offset=%d, pt_offset=%d, pt_dirty=%d\n",p,q,new_pt[q].pt_dirty);
        if(new_pt[q].pt_dirty == 1)
        {
          //write back and 
          pageth = getmem( sizeof(int *) );
          store = getmem( sizeof(int *) );
          if( SYSERR == bsm_lookup(currpid, vp, store, pageth)){
            kprintf("ERROR: This virtual address hasn't been mapped!\n");
            kill(currpid);
          }
          if(GDB)
            kprintf("maping found: {pid: %d, vpno: %d, store: %d, pageth: %d}\n",currpid,vp,*store,*pageth);
          write_bs((char *)new_pt, *store, *pageth);
        }
        init_pt(new_pt);
        reset_frm(frame_id);

        frm_tab[upper_id].fr_refcnt -= 2; //it is 2, not 1.
        if(frm_tab[upper_id].fr_refcnt <= 0){
          //mark the appropriate entry in pd as being not present, and free pt.
        }

        //invalidate the TLB entry for the page vp using the invlpg instruction
        if(pid == currpid) {
          set_PDBR(currpid);
        }
      }
      else
      {
        init_frm(avail, currpid, FR_PAGE);
        frm_tab[avail].fr_upper_t = pd[p].pd_base-FRAME0;
        if(GDB)
          kprintf("upper page table @frame[%d]\n",frm_tab[avail].fr_upper_t);
        frm_tab[avail].fr_vpno = vp;
        

        int counter =  proctab[currpid].nframes;      
        proc_frames[currpid][counter] = frm_tab[avail].fr_id;
        proctab[currpid].nframes++;
        if(GDB)
          kprintf("proc_frames[%d][%d] = frame[%d]\n",currpid,counter,avail);


        // Add this frame to head of the frame list within the bs of this process
        //(frm_tab[avail].bs_next)->fr_vpno
        //, proctab[currpid].bsmap[s].frames->bs_next
        if(GDB)
          kprintf("&frm_tab[avail].bs_next = %x\n",frm_tab[avail].bs_next, &frm_tab[avail].bs_next);
        if(GDB)
          kprintf("proctab[%d].bsmap[%d].frames = %x, ->vpno=%d, ->bs_next=%x\n",currpid, s, proctab[currpid].bsmap[s].frames, proctab[currpid].bsmap[s].frames->fr_vpno, proctab[currpid].bsmap[s].frames->bs_next);
        frm_tab[avail].bs_next = getmem(sizeof(fr_map_t *));
        frm_tab[avail].bs_next =  proctab[currpid].bsmap[s].frames;
        proctab[currpid].bsmap[s].frames = &frm_tab[avail];
        fr_map_t *frame = proctab[currpid].bsmap[s].frames;
        int i = frame->fr_vpno;
        if(GDB)
          kprintf("i = %d\n",i);
        if(GDB)
          kprintf("~~~frame[%d] linked to frame[%d]\n", avail, frame->bs_next==NULL?-1:frame->bs_next->fr_id);
        if(GDB)
          kprintf("frame[%d].bs_next = %x, &**=%x\n",avail,frm_tab[avail].bs_next, &frm_tab[avail].bs_next);
        if(GDB)
          kprintf("proctab[%d].bsmap[%d].frames = %x, ->vpno=%d, ->bs_next=%x\n",currpid, s, proctab[currpid].bsmap[s].frames, proctab[currpid].bsmap[s].frames->fr_vpno, proctab[currpid].bsmap[s].frames->bs_next);

        
        if(GDB)
          kprintf("Mapping frame[%d](ppno[%d]) to {pid[%d], vpno[%d]} -> {bs[%d],offset:%d}\n",
          avail,frid2vpno(avail),currpid,vp,s,o);

        physical_addr = frid2pa(avail);
        read_bs(physical_addr,s,o);
        if(GDB)
          kprintf("copied from bs[%d]:offset[%d] to vp[%d]@(%x)\n",s,o,vp,vp2pa(vp));
      }
    }
Ejemplo n.º 25
0
/* The page fault handler. */
void PageTable::handle_fault(REGS * _r) {
	unsigned int err_code = _r->err_code & 1;
	unsigned long fault_address = read_cr2();
	switch(err_code) {
		case KERNEL_READ_PAGE_NOT_PRESENT:
		case KERNEL_WRITE_PAGE_NOT_PRESENT:
			unsigned long page_directory_index = fault_address >> 22; //constify this
			unsigned long page_table_index = (fault_address & 0x003FFFFF) >> 12; //constify this
			unsigned long *page_directory = current_page_table->get_page_directory();
			
			if(page_directory[page_directory_index] & 1) { //constify this
				//page table entry is present in the directory
				unsigned long *page_table = (unsigned long *)(page_directory[page_directory_index] & (0xFFFFF000));
				if(page_table[page_table_index] & 1) {
					//page entry is present in the page table
					//why did the page fault occur? :P
				}
				else {

					//constify the 3 - PT entry control bits
					unsigned long *requested_page_from_framepool;
					if(fault_address >= shared_size) {
						requested_page_from_framepool =
							(unsigned long *)(process_mem_pool->get_frame() * PAGE_SIZE);
					} else {
						requested_page_from_framepool =
							(unsigned long *)(kernel_mem_pool->get_frame() * PAGE_SIZE);
					}
					
					create_page_table_entry(requested_page_from_framepool,
																	page_table,
																	page_table_index,
																	3);

					//handle the fault by reading/writing to that location or do what is required

				}
			} else {
				//create page table
				unsigned long *requested_page_from_framepool =
									(unsigned long *)(kernel_mem_pool->get_frame() * PAGE_SIZE);

				create_page_table_entry(requested_page_from_framepool,
																page_directory,
																page_directory_index,
																3);

				unsigned long *page_table = (unsigned long *)(page_directory[page_directory_index] & (0xFFFFF000));
				
				if(fault_address >= shared_size) {
					requested_page_from_framepool =
							(unsigned long *)(process_mem_pool->get_frame() * PAGE_SIZE);
				} else {
					requested_page_from_framepool =
							(unsigned long *)(kernel_mem_pool->get_frame() * PAGE_SIZE);
				}

				create_page_table_entry(requested_page_from_framepool,
																page_table,
																page_table_index,
																3);
				//handle the fault by reading/writing to that location or do what is required
			}
			break;
	}
	/*
	switch(err_code) {
		case KERNEL_READ_PAGE_NOT_PRESENT:
			break;
		case KERNEL_READ_PROTECTION_FAULT:
			break;
		case KERNEL_WRITE_PAGE_NOT_PRESENT:
			break;
		case KERNEL_WRITE_PROTECTION_FAULT:
			break;
		case USER_READ_PAGE_NOT_PRESENT:
			break;
		case USER_READ_PROTECTION_FAULT:
			break;
		case USER_WRITE_PAGE_NOT_PRESENT:
			break;
		case USER_WRITE_PROTECTION_FAULT:
			break;
	}*/
}
Ejemplo n.º 26
0
/*-------------------------------------------------------------------------
 * pfint - paging fault ISR
 *-------------------------------------------------------------------------
 */
SYSCALL pfint()
{
    STATWORD ps;
    disable(ps);
    unsigned long int eip = read_cr2();
    
    unsigned long int pd_offset = eip >> 22;
    unsigned long int pt_offset = eip >>12;
    pt_offset = pt_offset & 1023;
    unsigned long offset = eip;
    offset = offset & 4095;
    
    eip = eip >> 12; //vpno
    
    int i = 0, flag = 0;
    int backing_store_page, bs_id;
    
    for(i = 0 ; i < NBS; i++)
    {
        if(proctab[currpid].map[i].bs_pid == currpid)
        {
            if(proctab[currpid].map[i].next == NULL)
            {
                if(proctab[currpid].map[i].bs_vpno == eip) //we found the exact page
                {
                    backing_store_page = proctab[currpid].map[i].starting_page;
                    flag = 1;
                }
                else if(proctab[currpid].map[i].bs_vpno < eip && (proctab[currpid].map[i].bs_vpno+proctab[currpid].map[i].bs_npages) >= eip)
                {
                    backing_store_page = proctab[currpid].map[i].starting_page + eip - proctab[currpid].map[i].bs_vpno;
                    flag = 1;
                }
            }
            else
            {
                bs_map_t *move = &(proctab[currpid].map[i]);
                while(move != NULL)
                {
                    if(move->bs_vpno == eip) //we found the exact page
                    {
                        backing_store_page = move->starting_page;
                        flag = 1;
                        break;
                    }
                    else if(move->bs_vpno < eip && (move->bs_npages+move->bs_vpno) >= eip)
                    {
                        backing_store_page = move->starting_page + eip - move->bs_vpno;
                        flag = 1;
                        break;
                    }
                    move = move->next;
                }
            }
        }
        
        if(flag==1)
        {
            bs_id = i;
            break;
        }
        
    }
    
    unsigned long *bs_addr = (unsigned long *)(backing_store_page*NBPG);
    
    //populate page table
    //checking if page dir is empty
    
    pd_t *ptr1 = (pd_t *)(proctab[currpid].pdbr);
    ptr1 += pd_offset;
    pt_t *ptr;
    if(ptr1->pd_pres == 1) //page table exists hence add entry to that
    {
        ptr = (pt_t *)((ptr1->pd_base)*NBPG);
        frm_tab[(ptr1->pd_base)-FRAME0].refcnt++;
        frm_map[(ptr1->pd_base)-FRAME0].fr_refcnt++;
    }
    else //we need to create a page table, add our free_frame entry to it and add the page table entry to the directory
    {
        //kprintf("\nin else %d\n",ptr1);
        
        int pt_frame = get_frm();
        frm_tab[pt_frame-FRAME0].status = FRM_PGT;
        frm_tab[pt_frame-FRAME0].refcnt++;
        
        frm_map[pt_frame-FRAME0].fr_status = FRM_MAPPED;
        frm_map[pt_frame-FRAME0].fr_pid = currpid;
        frm_map[pt_frame-FRAME0].fr_refcnt++;
        frm_map[pt_frame-FRAME0].fr_type = FR_TBL;
        
        ptr = (pt_t*)(pt_frame*NBPG);
        
        //add the above table to page directory
        ptr1->pd_pres = 1;
        ptr1->pd_write = 1;
        ptr1->pd_user = 0;
        ptr1->pd_pwt = 0;
        ptr1->pd_pcd = 0;
        ptr1->pd_acc = 0;
        ptr1->pd_mbz = 0;
        ptr1->pd_fmb = 0;
        ptr1->pd_global = 0;
        ptr1->pd_avail = 0;
        ptr1->pd_base = pt_frame;
        
    }
    //add entry to page table
    ptr += pt_offset;
    ptr->pt_pres = 1;
    ptr->pt_write = 1;
    ptr->pt_user = 0;
    ptr->pt_pwt = 0;
    ptr->pt_pcd = 0;
    ptr->pt_acc = 0;
    ptr->pt_dirty = 0;
    ptr->pt_mbz = 0;
    ptr->pt_global = 0;
    ptr->pt_avail = 0;
    
    //getting a free frame an setting the frame mappings
    int free_frame;
    if(page_table[backing_store_page-total_bs_available] != -1)
    {
        free_frame = page_table[backing_store_page-total_bs_available];
        frm_map[free_frame-FRAME0].fr_refcnt++;
        frm_tab[free_frame-FRAME0].refcnt++;
        
        fr_map_t *map = (fr_map_t *)getmem(sizeof(fr_map_t));
        map->fr_pid = currpid;
        map->fr_vpno = eip;
        map->shared = NULL;
        
        fr_map_t *next = (fr_map_t *)getmem(sizeof(fr_map_t));
        next = &(frm_map[free_frame-FRAME0]);
        
        while(next->shared != NULL)
            next = next->shared;
        
        next->shared = map;

    }
    else
    {
        //obtain free frame
        free_frame = get_frm();
        
        frm_tab[free_frame-FRAME0].status = FRM_BS;
        frm_tab[free_frame-FRAME0].refcnt++;
        frm_tab[free_frame-FRAME0].bs = bs_id;
        frm_tab[free_frame-FRAME0].bs_page = backing_store_page;
        frm_tab[free_frame-FRAME0].bs_next = NULL;
        frm_tab[free_frame-FRAME0].fifo = NULL;
        frm_tab[free_frame-FRAME0].age = 128;
        frm_map[free_frame-FRAME0].fr_status = FRM_MAPPED;
        frm_map[free_frame-FRAME0].fr_pid = currpid;
        frm_map[free_frame-FRAME0].fr_vpno = eip;
        frm_map[free_frame-FRAME0].fr_refcnt++;
        frm_map[free_frame-FRAME0].fr_type = FR_PAGE;
        frm_map[free_frame-FRAME0].bs_page_num = backing_store_page;
        
        page_table[backing_store_page-total_bs_available] = free_frame;
        
        //set bs mappings
        if(bs_tab[bs_id].frm == NULL)
            bs_tab[bs_id].frm = &frm_tab[free_frame-FRAME0];
        else
        {
            frame_t *move = (frame_t *)getmem(sizeof(frame_t));
            move = bs_tab[bs_id].frm;
            while(move->bs_next != NULL)
            {
                move = move->bs_next;
            }
            
            move->bs_next = &frm_tab[free_frame-FRAME0];
        }
        
        //adding this frame to the fifo queue
        if(fifo_head == NULL)
        {
            //queue is empty
            fifo_head = &frm_tab[free_frame-FRAME0];
            fifo_tail = fifo_head;
        }
        else
        {
            fifo_tail->fifo = &frm_tab[free_frame-FRAME0];
            fifo_tail = &frm_tab[free_frame-FRAME0];
        }
    }
    
    unsigned long *dest_addr = (unsigned long *)(free_frame*NBPG);
    
    //copy page from bs to phy
    for(i = 0; i < NBPG/sizeof(unsigned long); i++)
    {
        *dest_addr = *bs_addr;
        dest_addr++;
        bs_addr++;
        
    }
    
    ptr->pt_base = free_frame;
    
    restore(ps);
    return OK;
}
Ejemplo n.º 27
0
static void dump_regs(struct irq_regs *regs)
{
	unsigned long cs, eip, eflags;
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
	unsigned long d0, d1, d2, d3, d6, d7;
	unsigned long sp;

	/*
	 * Some exceptions cause an error code to be saved on the current stack
	 * after the EIP value. We should extract CS/EIP/EFLAGS from different
	 * position on the stack based on the exception number.
	 */
	switch (regs->irq_id) {
	case EXC_DF:
	case EXC_TS:
	case EXC_NP:
	case EXC_SS:
	case EXC_GP:
	case EXC_PF:
	case EXC_AC:
		cs = regs->context.ctx2.xcs;
		eip = regs->context.ctx2.eip;
		eflags = regs->context.ctx2.eflags;
		/* We should fix up the ESP due to error code */
		regs->esp += 4;
		break;
	default:
		cs = regs->context.ctx1.xcs;
		eip = regs->context.ctx1.eip;
		eflags = regs->context.ctx1.eflags;
		break;
	}

	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
			(u16)cs, eip, eflags);
	if (gd->flags & GD_FLG_RELOC)
		printf("Original EIP :[<%08lx>]\n", eip - gd->reloc_off);

	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
		regs->eax, regs->ebx, regs->ecx, regs->edx);
	printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
		regs->esi, regs->edi, regs->ebp, regs->esp);
	printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
	       (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs,
	       (u16)regs->xgs, (u16)regs->xss);

	cr0 = read_cr0();
	cr2 = read_cr2();
	cr3 = read_cr3();
	cr4 = read_cr4();

	printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
			cr0, cr2, cr3, cr4);

	d0 = get_debugreg(0);
	d1 = get_debugreg(1);
	d2 = get_debugreg(2);
	d3 = get_debugreg(3);

	printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
			d0, d1, d2, d3);

	d6 = get_debugreg(6);
	d7 = get_debugreg(7);
	printf("DR6: %08lx DR7: %08lx\n",
			d6, d7);

	printf("Stack:\n");
	sp = regs->esp;

	sp += 64;

	while (sp > (regs->esp - 16)) {
		if (sp == regs->esp)
			printf("--->");
		else
			printf("    ");
		printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp));
		sp -= 4;
	}
}
Ejemplo n.º 28
0
/*******************************************************************************
 * Name:    pf_handler 
 *
 * Desc:    High level page fault handling code. The low level page fault
 *          interrupt handler is written in assembly. It'll setup the required
 *          registers (faulted address in CR2) and the stack frame with the 
 *          error code. This routine is responsible for the following:
 *          1. Read the faulted address and lookup BS to find if this address is
 *              mapped. If so, get the BS id and the offset within the BS. If 
 *              not, this is an illegal access - kill the process and move on.
 *          2. Actual paging starts here. Lookup the proctab to find the pid's
 *              pdir base. From the faulted address, we can get the pdir offset.
 *              Using these two, check if a page table exist for the faulted
 *              address. If not create one.
 *          3. If the page table is presnet, get the ptbl offset from the 
 *              faulted vaddr. This points to the location of the page table
 *              entry. Now, check if the frame assoicated with this page is
 *              already present in the memory (shared pages). If so, update the
 *              page table's 'pres' bit to reflect this and increment the 
 *              frame's refcount. If not, allocate a new frame and update the
 *              page table entry to reflect that the frame is present.
 *          4. Processor caches the paging entries (TLB) maintained by software
 *              and uses them whenever possible. When a pgt entry's 'pres' bit
 *              is cleared, we need to flush the entry from the processor 
 *              cache so that the proceessor would use the updated software
 *              data. This is described in detail in section 4.8 of Intel IA32 
 *              software developer manual (vol 3). There are many ways to force
 *              the processor to use the software tables, than hardware cache.
 *              One such way is to reload teh CR0 register. So, if any of the
 *              'pres' bits are modified, we reload the CR0 register.
 *
 * Params:  None.
 *
 * Returns: SYSCALL
 *  OK      - on success
 *  SYSERR  - on error
 ******************************************************************************/
SYSCALL
pf_handler(void)
{
    int bs_id = EMPTY;
    int bs_offset = EMPTY;
    int fr_id = EMPTY;
    uint32_t pdir_offset = 0;
    uint32_t ptbl_offset = 0;
    uint32_t page_offset = 0;
    uint32_t fault_addr = 0;
    pd_t *pdir = NULL;
    pt_t *ptbl = NULL;
    frm_map_t *frptr = NULL;
    frm_map_t *pt_frptr = NULL;
    virt_addr_t  *fault_vaddr = NULL;
    STATWORD ps; 

    disable(ps);
    DTRACE_START;

    DTRACE("DBG$ %d %s> inside high-level page fault handler\n",    \
            currpid, __func__);

    /* vaddr   : pdir_offset : ptbl_offset : page_offset
     * 32 bits : 10 bits     : 10 bits     : 12 bits
     */
    fault_addr = read_cr2();

    /* The virtual address is 32-bits. So, we directly read the required set of 
     * bits by assigining it to a strcutre with appropriate bit-fields.
     */
    fault_vaddr = (virt_addr_t *) (&fault_addr);
    pdir_offset = (uint32_t) fault_vaddr->pd_offset;
    ptbl_offset = (uint32_t) fault_vaddr->pt_offset;
    page_offset = (uint32_t) fault_vaddr->pg_offset;
    DTRACE("DBG$ %d %s> faulted vaddr 0x%08x, vpage %d\n",  \
            currpid, __func__, fault_addr, VADDR_TO_VPAGE(fault_addr));
    DTRACE("DBG$ %d %s> pd %d, pt %d, pg %d\n",  \
            currpid, __func__, pdir_offset, ptbl_offset, page_offset);


    /* Check the BS for a mapping for the faulted vaddr and the pid. If present,
     * record the BS id and the offset within the BS. If not present, it's
     * illeagal memory access. Kill the process and return.
     */
    if (SYSERR == bsm_lookup(currpid, fault_addr, &bs_id, &bs_offset, 
                                NULL, NULL)) {
        DTRACE("DBG$ %d %s> bsm_lookup() failed\n", currpid, __func__);
        DTRACE("DBG$ %d %s> pid %d will be killed\n",   \
                currpid, __func__, currpid);
        kprintf("\n\n");
        kprintf("FATAL ERROR: Process '%s' with pid '%d' is trying to access " \
                "virtual memory out of its range! \nThe process will be "      \
                "terminated.\n", P_GET_PNAME(currpid), currpid);
        kprintf("\n\n");
        sleep(9);
        DTRACE_END;
        restore(ps);
        kill(currpid);
        goto RESTORE_AND_RETURN_ERROR;
    }   

    /* Get the currpid's page directory and index to the appropriate pgt. If pgt
     * isn't present, create one.
     */
    pdir = P_GET_PDIR(currpid);
    if (FALSE == PD_GET_PRES(pdir, pdir_offset)) {
        DTRACE("DBG$ %d %s> pgt not present for pid %d, pd offset %d, "     \
                "pt offset %d, pg offset %d, vaddr 0x%08x\n", currpid,      \
                __func__, currpid, pdir_offset, ptbl_offset, page_offset,   \
                fault_addr);
        ptbl = new_pgt();
        if (NULL == ptbl) {
            DTRACE("DBG$ %d %s> new_pgt() failed\n", currpid, __func__);
            goto RESTORE_AND_RETURN_ERROR;
        }

        /* Fill-in few meta-data for the pgt frame just created. */
        pt_frptr = FR_GET_FPTR(FR_PA_TO_ID(ptbl));
        pt_frptr->fr_pid = currpid;

        /* Set the 'pres' and 'write' bits alone. Rest would've been zeroed
         * out by new_pgt(). Also, set the base of the new page table.
         */
        pdir[pdir_offset].pd_pres = 1;
        pdir[pdir_offset].pd_write = 1;
        pdir[pdir_offset].pd_base = VADDR_TO_VPAGE((unsigned) ptbl);
    } else {
        DTRACE("DBG$ %d %s> ptbl already present at 0x%08x, fr id %d\n",  \
            currpid, __func__, VPAGE_TO_VADDR(PD_GET_BASE(pdir, pdir_offset)),\
            FR_PA_TO_ID(VPAGE_TO_VADDR(PD_GET_BASE(pdir, pdir_offset))));
    }
    ptbl = (pt_t *) VPAGE_TO_VADDR(PD_GET_BASE(pdir, pdir_offset));
    DTRACE("DBG$ %d %s> ptbl present at 0x%08x, fr id %d\n",  \
            currpid, __func__, ptbl, FR_PA_TO_ID(ptbl));

    /* Find if a frame representing the same BS id and offset is present in the
     * memory (shared pages). If so, just update the page table entry and
     * increment teh refcount.
     */
    if (EMPTY == (fr_id = is_frm_present(bs_id, bs_offset))) {
        DTRACE("DBG$ %d %s> frame not present.. creating a new frame\n",    \
                currpid, __func__);

        frptr = get_frm(FR_PAGE);
        if (NULL == frptr) {
            DTRACE("DBG$ %d %s> get_frm() failed\n", currpid, __func__);
            goto RESTORE_AND_RETURN_ERROR;
        }
        fr_id = frptr->fr_id;
        frm_pidmap_oper(fr_id, getpid(), FR_OP_PMAP_SET);
        frm_record_details(fr_id, getpid(), VADDR_TO_VPAGE(fault_addr));

        /* Read the appropriate page from BS onto the new frame. */
        if (SYSERR == read_bs((char *) FR_ID_TO_PA(fr_id), bs_id, bs_offset)) {
            DTRACE("DBG$ %d %s> read_bs() failed for fr id %d, bs %d, "     \
                    "offset %d\n", currpid, __func__, fr_id, bs_id, bs_offset);
            goto RESTORE_AND_RETURN_ERROR;
        } else {
            DTRACE("DBG$ %d %s> reading for fr id %d, bs %d, offset %d\n",  \
                    currpid, __func__, fr_id, bs_id, bs_offset);
        }

        /* Fill-in the new BS details in the frame. */
        frptr->fr_type = FR_PAGE;
        frptr->fr_bs = bs_id;
        frptr->fr_bsoffset = bs_offset;
        inc_frm_refcount(fr_id);
#ifdef DBG_ON
        print_frm_id(fr_id);
#endif
    } else {
        /* A frame representing the same BS and offset is already present in the 
         * memory. So, just increment the refcount of the frame.
         */
        frm_pidmap_oper(fr_id, getpid(), FR_OP_PMAP_SET);
        frm_record_details(fr_id, getpid(), VADDR_TO_VPAGE(fault_addr));
        inc_frm_refcount(fr_id);
    }

    /* In both cases (frame present and frame not present), we need to update
     * the page table entry as at this point, the frame is loaded onto the
     * memory. Do the following w.r.t. the pgt frame:
     *      1. Set the 'pres' bit in the page table entry corresponding to the
     *          newly loaded page to reflect that the page is present in the
     *          memory. 
     *      2. Set the 'write' bit (as given in PA3 description). 
     *      3. Update the 'base' of the page entry corresponding to the newly 
     *          created page to point to the frame.
     *      4. Increment the refcount of the pgt frame. Unlike data frames, where
     *          refocunt denotes the # of processes that map to the actual
     *          physical frame, pgt frame's refcount reflects the # of pages
     *          (that are part of this pgt) that are present in the memory. 
     *          This will be decremented when a frame is paged out and the 
     *          pgt frame will be freed when the refcount reaches zero.
     */
    ptbl[ptbl_offset].pt_pres = 1;
    ptbl[ptbl_offset].pt_write = 1;
    ptbl[ptbl_offset].pt_base = FR_ID_TO_VPAGE(fr_id);
    inc_frm_refcount(FR_PA_TO_ID(ptbl));

    /* Reload the CR0 register would force the processor to flush the tables
     * that the processor maintains in hardware cache and to use the updated
     * software tables.
     */
    enable_paging();

    DTRACE("DBG$ %d %s> returning OK\n", currpid, __func__);
    DTRACE_END;
    restore(ps);
    return OK;

RESTORE_AND_RETURN_ERROR:
    DTRACE("DBG$ %d %s> returning SYSERR\n", currpid, __func__);
    DTRACE_END;
    restore(ps);
    return SYSERR;
}
Ejemplo n.º 29
0
/*-------------------------------------------------------------------------
 * pfint - paging fault ISR
 *-------------------------------------------------------------------------
 */
SYSCALL pfint()
{
		STATWORD ps;
	disable(ps);
  unsigned long int eip = read_cr2();

	//kprintf("\n\n#PF in %s, cr2:%x",proctab[currpid].pname, eip);
  unsigned long int pd_offset = eip >> 22;
  unsigned long int pt_offset = eip >>12;
  pt_offset = pt_offset & 1023;
  unsigned long offset = eip;
  offset = offset & 4095;

	//kprintf("\nEIP read is %lu\n",eip);
  eip = eip >> 12; //vpno
  //kprintf("\nEIP shifted is %lu\n",eip);

  int i = 0, flag = 0;
  int backing_store_page, bs_id;

  for(i = 0 ; i < NBS; i++)
  {
		if(proctab[currpid].map[i].pid == currpid)
		{
			//kprintf("\nif\n");
			if(proctab[currpid].map[i].next == NULL)
			{
				//kprintf("\nif if\n");
				if(proctab[currpid].map[i].vpno == eip) //we found the exact page
				{
					backing_store_page = proctab[currpid].map[i].base_page;
					flag = 1;
					//kprintf("\nif if if\n");
				}
				else if(proctab[currpid].map[i].vpno < eip && (proctab[currpid].map[i].vpno+proctab[currpid].map[i].npages) >= eip) //we found the page in the range of base_page - npages
				{
					backing_store_page = proctab[currpid].map[i].base_page + eip - proctab[currpid].map[i].vpno;
					flag = 1;
					//kprintf("\nif if else if\n");
				}
			}
			else
			{
				//kprintf("\nelse\n");
				bs_map_t *jump = &(proctab[currpid].map[i]);
				while(jump != NULL)
				{
					//kprintf("\nwhile\n");
					if(jump->vpno == eip) //we found the exact page
					{
						backing_store_page = jump->base_page;
						flag = 1;
						//kprintf("\nif else if\n");
						break;
					}
					else if(jump->vpno < eip && (jump->npages+jump->vpno) >= eip) //we found the page in the range of base_page - npages
					{
						backing_store_page = jump->base_page + eip - jump->vpno;
						flag = 1;
						//kprintf("\nif else else if\n");
						break;
					}
					jump = jump->next;
				}
			}
		}
		if(flag)
		{
			bs_id = i;
			break;
		}

  }
  //kprintf("\nin pfint bs %d, bs_page %d",bs_id,backing_store_page);

  unsigned long *bs_addr = (unsigned long *)(backing_store_page*NBPG);

	//populate page table
	//checking if page dir is empty
	
	pd_t *ptr1 = (pd_t *)(proctab[currpid].pdbr);
	//kprintf("\nbefore %d, %lu\n",ptr1,pd_offset);
	ptr1 += pd_offset; 
	pt_t *ptr;
	if(ptr1->pd_pres == 1) //page table exists hence add entry to that
	{
		ptr = (pt_t *)((ptr1->pd_base)*NBPG);
		frm_tab[(ptr1->pd_base)-FRAME0].refcnt++;
		frm_map[(ptr1->pd_base)-FRAME0].fr_refcnt++;
	}
	else //we need to create a page table, add our free_frm entry to it and add the page table entry to the directory
	{
		//kprintf("\nin else %d\n",ptr1);

		int pt_frame = get_frm();
		frm_tab[pt_frame-FRAME0].status = FRM_PGT;
		frm_tab[pt_frame-FRAME0].refcnt++;

		frm_map[pt_frame-FRAME0].fr_status = FRM_MAPPED;
		frm_map[pt_frame-FRAME0].fr_pid = currpid;
		frm_map[pt_frame-FRAME0].fr_refcnt++;
		frm_map[pt_frame-FRAME0].fr_type = FR_TBL;

		ptr = (pt_t*)(pt_frame*NBPG);

		//add the above table to page directory
		ptr1->pd_pres = 1;
		ptr1->pd_write = 1;
		ptr1->pd_user = 0;
		ptr1->pd_pwt = 0;
		ptr1->pd_pcd = 0;
		ptr1->pd_acc = 0;
		ptr1->pd_mbz = 0;
		ptr1->pd_fmb = 0;
		ptr1->pd_global = 0;
		ptr1->pd_avail = 0;
		ptr1->pd_base = pt_frame;

		//kprintf("\nget_frm return frame %d. To be page table for process %s",pt_frame, proctab[currpid].pname);

	}
	//add entry to page table
	ptr += pt_offset;
	ptr->pt_pres = 1;
	ptr->pt_write = 1;
	ptr->pt_user = 0;
	ptr->pt_pwt = 0;
	ptr->pt_pcd = 0;
	ptr->pt_acc = 0;
	ptr->pt_dirty = 0;
	ptr->pt_mbz = 0;
	ptr->pt_global = 0;
	ptr->pt_avail = 0;

	  //getting a free frame an setting the frame mappings
  int free_frm;
  if(ni_page_table[backing_store_page-total_bs_left] != -1) // if backing store is already mapped then we share the frame
	{
		free_frm = ni_page_table[backing_store_page-total_bs_left];
		//kprintf("\nIN NI frm = %d, ni = %d\n",free_frm, ni_page_table[backing_store_page-total_bs_left]);
		frm_map[free_frm-FRAME0].fr_refcnt++;
		frm_tab[free_frm-FRAME0].refcnt++;

		//adding this vpno and pid to the shared frame map list
		fr_map_t *map = (fr_map_t *)getmem(sizeof(fr_map_t));
		map->fr_pid = currpid;
		map->fr_vpno = eip;
		map->shared = NULL;

		fr_map_t *next = (fr_map_t *)getmem(sizeof(fr_map_t));
		next = &(frm_map[free_frm-FRAME0]);

		while(next->shared != NULL)
				next = next->shared;

		next->shared = map;

		//printing the list
		/*kprintf("\nSHARED VPNO: ");
		next = &(frm_map[free_frm-FRAME0]);
		while(next != NULL)
		{
			kprintf("%d -> ",next->fr_vpno);
			next = next->shared;
		}*/
	}
	else
	{
		free_frm = get_frm();
		
		frm_tab[free_frm-FRAME0].status = FRM_BS;
		frm_tab[free_frm-FRAME0].refcnt++;
		frm_tab[free_frm-FRAME0].bs = bs_id;
		frm_tab[free_frm-FRAME0].bs_page = backing_store_page;
		frm_tab[free_frm-FRAME0].bs_next = NULL;
		frm_tab[free_frm-FRAME0].fifo = NULL;
		frm_tab[free_frm-FRAME0].age = 128;
 		frm_map[free_frm-FRAME0].fr_status = FRM_MAPPED;
		frm_map[free_frm-FRAME0].fr_pid = currpid;
		frm_map[free_frm-FRAME0].fr_vpno = eip;
		frm_map[free_frm-FRAME0].fr_refcnt++;
		frm_map[free_frm-FRAME0].fr_type = FR_PAGE;
		frm_map[free_frm-FRAME0].bs_page_num = backing_store_page;

		ni_page_table[backing_store_page-total_bs_left] = free_frm;
		
		//set bs mappings
		if(bs_tab[bs_id].frm == NULL)
				  bs_tab[bs_id].frm = &frm_tab[free_frm-FRAME0];
		else
		{
			//frame_t *jump = &frm_tab[free_frm-FRAME0];
			frame_t *jump = (frame_t *)getmem(sizeof(frame_t)); 
			jump = bs_tab[bs_id].frm;
			while(jump->bs_next != NULL)
			{
				jump = jump->bs_next;
				//kprintf("\njumping\n");
			}

			jump->bs_next = &frm_tab[free_frm-FRAME0];
		}

		//adding this frame to the fifo queue
		if(fifo_head == NULL)
		{
			//queue is empty
			fifo_head = &frm_tab[free_frm-FRAME0];
			fifo_tail = fifo_head;
		}
		else
		{
			fifo_tail->fifo = &frm_tab[free_frm-FRAME0];
			fifo_tail = &frm_tab[free_frm-FRAME0];
		}
	}
	//kprintf("\nget_frm return frame %d.", free_frm);
	
  unsigned long *dst_addr = (unsigned long *)(free_frm*NBPG);

  //kprintf("\n\n Virtual page %d mapped to bs page %d, bs id %d, mapped to frame %d, %lu",eip, backing_store_page, bs_id, free_frm,dst_addr);

	/*frame_t *next = fifo_head;
	kprintf("\nFIFO : ");
	while(next != NULL)
	{
		kprintf("%d-> ",next->frame_num);
		next = next->fifo;
	}
	kprintf("\n");*/

	
   //copy page from bs to phy
   for(i = 0; i < NBPG/sizeof(unsigned long); i++)
   {
		*dst_addr = *bs_addr;
		dst_addr++;
		bs_addr++;

   }
   
	ptr->pt_base = free_frm;

	restore(ps);

	//kprintf("\nmap bs%d/page: %d to frame %d",bs_id, (backing_store_page-proctab[currpid].map[bs_id].base_page), free_frm);
  return OK;
}
Ejemplo n.º 30
0
/*-------------------------------------------------------------------------
 * pfint - paging fault ISR
 *-------------------------------------------------------------------------
 */
SYSCALL pfint() {

	STATWORD ps;
	disable(ps);
	int store, pageth;
	unsigned long vaddr = read_cr2();
	unsigned int p_offset = (vaddr & 0xFFC00000) >> 22;
	unsigned int q_offset = (vaddr & 0x3FF000) >> 12;
	
	bsm_lookup(currpid, vaddr, &store, &pageth);

	frame_t *frame_backing_store = obtain_frame();

	bs_tab[store].pg_to_frm_map[pageth] = frame_backing_store->frm_num;
	frame_backing_store->bs = store;
	frame_backing_store->bs_page = pageth;
	frame_backing_store->status = FRM_BS;
	frame_backing_store->fr_type = FR_PAGE;
	read_bs((char *)(frame_backing_store->frm_num * 4096), store, pageth );
	frame_t * obtained_free_frame = frame_backing_store;

	
//	unsigned long pdbr = add_pg_dir_entry_for_pg_fault(currpid, p_offset, q_offset, obtained_free_frame);

	unsigned long page_to_frame;
	int avail = 0;
	struct pentry *pptr = &proctab[currpid];
	frame_t *directory = pptr->pd;
	pd_t *table_descriptor = (pd_t *) ((4096 * directory->frm_num) + p_offset * sizeof(pd_t));
	if (table_descriptor->pd_pres == 1) 
	{

	frame_t *page_frame;
	int i = 0;
	for (i = 0; i < NFRAMES; i++) {
		if (frm_tab[i].frm_num == table_descriptor->pd_base)
		{
		 page_frame= &frm_tab[i];
		}
	}	

	pt_t *offset_value = (pt_t *) (4096 * page_frame->frm_num );
	offset_value =offset_value+q_offset;
	pt_t ptr;
	ptr.pt_pres = 1;
	ptr.pt_write = 1;
	ptr.pt_user = 0;
	ptr.pt_pwt = 0;
	ptr.pt_pcd = 0;
	ptr.pt_acc = 0;
	ptr.pt_dirty = 0;
	ptr.pt_mbz = 0;
	ptr.pt_global = 0;
	ptr.pt_avail = 0;
	ptr.pt_base = obtained_free_frame->frm_num;
	*offset_value = ptr;


	}
	else
	{
	
	frame_t *page_frame = obtain_frame();
	page_frame->status = FRM_PGT;
	page_frame->fr_type = FRM_PGT;
	page_frame->fr_pid = currpid;

	pd_t *table_descriptor = (pd_t *) (4096 * directory->frm_num);
	table_descriptor =table_descriptor+p_offset;
	pd_t ptr1;
	ptr1.pd_pres = 1;
	ptr1.pd_write = 1;
	ptr1.pd_user = 0;
	ptr1.pd_pwt = 0;
	ptr1.pd_pcd = 0;
	ptr1.pd_acc = 0;
	ptr1.pd_mbz = 0;
	ptr1.pd_fmb = 0;
	ptr1.pd_global = 0;
	ptr1.pd_avail = 0;
	ptr1.pd_base = page_frame->frm_num;
	*table_descriptor = ptr1;

	pt_t *offset_value = (pt_t *) (4096 * page_frame->frm_num );
	offset_value =offset_value+q_offset;
	pt_t ptr;
	ptr.pt_pres = 1;
	ptr.pt_write = 1;
	ptr.pt_user = 0;
	ptr.pt_pwt = 0;
	ptr.pt_pcd = 0;
	ptr.pt_acc = 0;
	ptr.pt_dirty = 0;
	ptr.pt_mbz = 0;
	ptr.pt_global = 0;
	ptr.pt_avail = 0;
	ptr.pt_base = obtained_free_frame->frm_num;
	*offset_value = ptr;
	page_to_frame = page_frame->frm_num ;
	}

	unsigned long pdbr= pptr->pdbr;


	struct pentry *pptr1 = &proctab[currpid];
	bs_map_t *map = &(pptr1->map[store]);
	if(map->frm == NULL)
		map->frm = obtained_free_frame;
	else{
		frame_t *tmp = map->frm;
		while(tmp->bs_next != NULL)
			tmp = tmp->bs_next;
		tmp->bs_next = obtained_free_frame;
	}
	obtained_free_frame->fr_vpno = map->vpno + obtained_free_frame->bs_page;
	obtained_free_frame->fr_pid = currpid;

	write_cr3(pdbr * NBPG);
	restore(ps);
	return OK;
}