/* Paging Initialization */ void init_paging() { map_mem(); printf("before: %b,%b ---",read_cr0(),read_cr3()); write_cr3((unsigned long)page_directory); unsigned long cr0 = read_cr0(); cr0 = cr0 | 0x8000000; write_cr0(cr0); printf(" after: %b,%b\n",read_cr0(),read_cr3()); }
void set_pte_v2p(u32int vaddr, u32int pfn) { u32int pd_index, pt_index; u32int pde; u32int pte; u32int *page_table; printf_bochs("create vaddr:%x to pfn: %x\n", vaddr, pfn); pd_index = vaddr / 0x400000; pt_index = vaddr / 0x1000 % 1024; printf_bochs("pd_index:%x pt_index:%x\n", pd_index, pt_index); pde = page_directory[pd_index]; if(!pde) { u32int page_table_pfn; page_table_pfn = alloc_page_pfn();; // ocassionally frame for page table has not been mapped. set_pte_v2p(page_table_pfn<<12, page_table_pfn); pde = page_table_pfn << 12 | 0x23; page_directory[pd_index] = pde; page_table = (u32int*)(page_table_pfn<<12); } else { page_table = (u32int*)(pde & 0xFFFFF000); } pte = pfn << 12 | 0x23; page_table[pt_index] = pte; write_cr3(read_cr3()); }
/* Locates and clears a region for a new top level page table. */ void initialize_identity_maps(void) { /* Init mapping_info with run-time function/buffer pointers. */ mapping_info.alloc_pgt_page = alloc_pgt_page; mapping_info.context = &pgt_data; /* * It should be impossible for this not to already be true, * but since calling this a second time would rewind the other * counters, let's just make sure this is reset too. */ pgt_data.pgt_buf_offset = 0; /* * If we came here via startup_32(), cr3 will be _pgtable already * and we must append to the existing area instead of entirely * overwriting it. */ level4p = read_cr3(); if (level4p == (unsigned long)_pgtable) { debug_putstr("booted via startup_32()\n"); pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE; pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE; memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); } else { debug_putstr("booted via startup_64()\n"); pgt_data.pgt_buf = _pgtable; pgt_data.pgt_buf_size = BOOT_PGT_SIZE; memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); level4p = (unsigned long)alloc_pgt_page(&pgt_data); } }
/*------------------------------------------------------------------------- * 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; }
pgd_t * __init efi_call_phys_prolog(void) { unsigned long vaddress; pgd_t *save_pgd; int pgd; int n_pgds; if (!efi_enabled(EFI_OLD_MEMMAP)) { save_pgd = (pgd_t *)read_cr3(); write_cr3((unsigned long)efi_scratch.efi_pgt); goto out; } early_code_mapping_set_exec(1); n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); save_pgd = kmalloc_array(n_pgds, sizeof(*save_pgd), GFP_KERNEL); for (pgd = 0; pgd < n_pgds; pgd++) { save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE); vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); } out: __flush_tlb_all(); return save_pgd; }
static int relocate_restore_code(void) { pgd_t *pgd; pud_t *pud; relocated_restore_code = get_safe_page(GFP_ATOMIC); if (!relocated_restore_code) return -ENOMEM; memcpy((void *)relocated_restore_code, &core_restore_code, PAGE_SIZE); /* Make the page containing the relocated code executable */ pgd = (pgd_t *)__va(read_cr3()) + pgd_index(relocated_restore_code); pud = pud_offset(pgd, relocated_restore_code); if (pud_large(*pud)) { set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX)); } else { pmd_t *pmd = pmd_offset(pud, relocated_restore_code); if (pmd_large(*pmd)) { set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX)); } else { pte_t *pte = pte_offset_kernel(pmd, relocated_restore_code); set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_NX)); } } __flush_tlb_all(); return 0; }
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(;;); }
void PageTable::load() { write_cr3((unsigned long)page_directory); //current_page_table = this; Console::putui((unsigned int)read_cr3()); Console::puts("load Hello \n"); }
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, ®s->esp); }
efi_status_t efi_thunk_set_virtual_address_map( void *phys_set_virtual_address_map, unsigned long memory_map_size, unsigned long descriptor_size, u32 descriptor_version, efi_memory_desc_t *virtual_map) { efi_status_t status; unsigned long flags; u32 func; efi_sync_low_kernel_mappings(); local_irq_save(flags); efi_scratch.prev_cr3 = read_cr3(); write_cr3((unsigned long)efi_scratch.efi_pgt); __flush_tlb_all(); func = (u32)(unsigned long)phys_set_virtual_address_map; status = efi64_thunk(func, memory_map_size, descriptor_size, descriptor_version, virtual_map); write_cr3(efi_scratch.prev_cr3); __flush_tlb_all(); local_irq_restore(flags); return status; }
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(); }
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) (®s->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); }
void compat_show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs, int debug_stack_lines) { unsigned int i, *stack, addr, mask = STACK_SIZE; stack = (unsigned int *)(unsigned long)regs->_esp; printk("Guest stack trace from esp=%08lx:\n ", (unsigned long)stack); if ( !__compat_access_ok(v->domain, stack, sizeof(*stack)) ) { printk("Guest-inaccessible memory.\n"); return; } if ( v != current ) { struct vcpu *vcpu; unsigned long mfn; ASSERT(guest_kernel_mode(v, regs)); mfn = read_cr3() >> PAGE_SHIFT; for_each_vcpu( v->domain, vcpu ) if ( pagetable_get_pfn(vcpu->arch.guest_table) == mfn ) break; if ( !vcpu ) { stack = do_page_walk(v, (unsigned long)stack); if ( (unsigned long)stack < PAGE_SIZE ) { printk("Inaccessible guest memory.\n"); return; } mask = PAGE_SIZE; } } for ( i = 0; i < debug_stack_lines * 8; i++ ) { if ( (((long)stack - 1) ^ ((long)(stack + 1) - 1)) & mask ) break; if ( __get_user(addr, stack) ) { if ( i != 0 ) printk("\n "); printk("Fault while accessing guest memory."); i = 1; break; } if ( (i != 0) && ((i % 8) == 0) ) printk("\n "); printk(" %08x", addr); stack++; } if ( i == 0 ) printk("Stack empty."); printk("\n"); }
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 }
/*------------------------------------------------------------------------- * enable_paging - enable paging *------------------------------------------------------------------------- */ void enable_paging(){ unsigned long temp = read_cr0(); kprintf("cr3 : %x\n",read_cr3()); kprintf("cr0 prev: %x",temp); temp = temp | ( 0x1 << 31 ) | 0x1; write_cr0(temp); kprintf("cr0 after:%x",temp); }
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); }
/* Create a new PMD entry */ int __init early_make_pgtable(unsigned long address) { unsigned long physaddr = address - __PAGE_OFFSET; unsigned long i; pgdval_t pgd, *pgd_p; pudval_t pud, *pud_p; pmdval_t pmd, *pmd_p; /* Invalid address or early pgt is done ? */ if (physaddr >= MAXMEM || read_cr3() != __pa(early_level4_pgt)) return -1; again: pgd_p = &early_level4_pgt[pgd_index(address)].pgd; pgd = *pgd_p; /* * The use of __START_KERNEL_map rather than __PAGE_OFFSET here is * critical -- __PAGE_OFFSET would point us back into the dynamic * range and we might end up looping forever... */ if (pgd) pud_p = (pudval_t *)((pgd & PTE_PFN_MASK) + __START_KERNEL_map - phys_base); else { if (next_early_pgt >= EARLY_DYNAMIC_PAGE_TABLES) { reset_early_page_tables(); goto again; } pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++]; for (i = 0; i < PTRS_PER_PUD; i++) pud_p[i] = 0; *pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; } pud_p += pud_index(address); pud = *pud_p; if (pud) pmd_p = (pmdval_t *)((pud & PTE_PFN_MASK) + __START_KERNEL_map - phys_base); else { if (next_early_pgt >= EARLY_DYNAMIC_PAGE_TABLES) { reset_early_page_tables(); goto again; } pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++]; for (i = 0; i < PTRS_PER_PMD; i++) pmd_p[i] = 0; *pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; } pmd = (physaddr & PMD_MASK) + early_pmd_flags; pmd_p[pmd_index(address)] = pmd; return 0; }
static int __init init_cr3_pgd(void) { unsigned long cr3; unsigned long pgd = 0; cr3 = read_cr3(); printk("cr3----------------->0x%lx\n",cr3); pgd = __pa(read_pgd()); printk("pgd----------------->0x%lx\n",pgd); return 0; }
/*S:010 * We approach the Switcher. * * Remember that each CPU has two pages which are visible to the Guest when it * runs on that CPU. This has to contain the state for that Guest: we copy the * state in just before we run the Guest. * * Each Guest has "changed" flags which indicate what has changed in the Guest * since it last ran. We saw this set in interrupts_and_traps.c and * segments.c. */ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) { /* * Copying all this data can be quite expensive. We usually run the * same Guest we ran last time (and that Guest hasn't run anywhere else * meanwhile). If that's not the case, we pretend everything in the * Guest has changed. */ if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) { __this_cpu_write(lg_last_cpu, cpu); cpu->last_pages = pages; cpu->changed = CHANGED_ALL; } /* * These copies are pretty cheap, so we do them unconditionally: */ /* Save the current Host top-level page directory. */ #ifdef CONFIG_PAX_PER_CPU_PGD pages->state.host_cr3 = read_cr3(); #else pages->state.host_cr3 = __pa(current->mm->pgd); #endif /* * Set up the Guest's page tables to see this CPU's pages (and no * other CPU's pages). */ map_switcher_in_guest(cpu, pages); /* * Set up the two "TSS" members which tell the CPU what stack to use * for traps which do directly into the Guest (ie. traps at privilege * level 1). */ pages->state.guest_tss.sp1 = cpu->esp1; pages->state.guest_tss.ss1 = cpu->ss1; /* Copy direct-to-Guest trap entries. */ if (cpu->changed & CHANGED_IDT) copy_traps(cpu, pages->state.guest_idt, default_idt_entries); /* Copy all GDT entries which the Guest can change. */ if (cpu->changed & CHANGED_GDT) copy_gdt(cpu, pages->state.guest_gdt); /* If only the TLS entries have changed, copy them. */ else if (cpu->changed & CHANGED_GDT_TLS) copy_gdt_tls(cpu, pages->state.guest_gdt); /* Mark the Guest as unchanged for next time. */ cpu->changed = 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; } }
static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) #endif { unsigned long cr3 = read_cr3(); switch(ioctl_num) { case IOCTL_GET_CR3: put_user(cr3,(long *)ioctl_param); break; default: return -1; } return 0; }
void enable_paging (unsigned int pd) { unsigned long cr0; kprintf("load cr3\n"); write_cr3 (pd & ~NBPG); kprintf("enable paging\n"); cr0 = read_cr0 (); cr0 |= CR0_PG; write_cr0 (cr0); cr0 = read_cr0 (); kprintf("cr0: %x, cr3 %x\n", read_cr0(), read_cr3()); }
int multitasking_init(void) { if (BUILTIN_EXPECT(task_table[0].status != TASK_IDLE, 0)) { kputs("Task 0 is not an idle task\n"); return -ENOMEM; } task_table[0].prio = IDLE_PRIO; task_table[0].stack = (void*) &boot_stack; task_table[0].page_map = read_cr3(); // register idle task register_task(); return 0; }
void M68KPagingStructures040::Delete() { // remove from global list InterruptsSpinLocker locker(sPagingStructuresListLock); sPagingStructuresList.Remove(this); locker.Unlock(); #if 0 // this sanity check can be enabled when corruption due to // overwriting an active page directory is suspected uint32 activePageDirectory; read_cr3(activePageDirectory); if (activePageDirectory == pgdir_phys) panic("deleting a still active page directory\n"); #endif if (are_interrupts_enabled()) delete this; else deferred_delete(this); }
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); }
//wake up application processors (cores) in the system void xmhf_baseplatform_arch_x86vmx_wakeupAPs(void){ //step-1: setup AP boot-strap code at in the desired physical memory location //note that we need an address < 1MB since the APs are woken up in real-mode //we choose 0x10000 physical or 0x1000:0x0000 logical { _ap_cr3_value = read_cr3(); _ap_cr4_value = read_cr4(); #ifndef __XMHF_VERIFICATION__ memcpy((void *)0x10000, (void *)_ap_bootstrap_start, (u32)_ap_bootstrap_end - (u32)_ap_bootstrap_start + 1); #endif } #if defined (__DRT__) //step-2: wake up the APs sending the INIT-SIPI-SIPI sequence as per the //MP protocol. Use the APIC for IPI purposes. if(!txt_is_launched()) { // XXX TODO: Do actual GETSEC[WAKEUP] in here? printf("\nBSP: Using APIC to awaken APs..."); xmhf_baseplatform_arch_x86_wakeupAPs(); printf("\nBSP: APs should be awake."); }else{ //we ran SENTER, so do a GETSEC[WAKEUP] txt_heap_t *txt_heap; os_mle_data_t *os_mle_data; mle_join_t *mle_join; sinit_mle_data_t *sinit_mle_data; os_sinit_data_t *os_sinit_data; // sl.c unity-maps 0xfed00000 for 2M so these should work fine #ifndef __XMHF_VERIFICATION__ txt_heap = get_txt_heap(); //printf("\ntxt_heap = 0x%08x", (u32)txt_heap); os_mle_data = get_os_mle_data_start(txt_heap); (void)os_mle_data; //printf("\nos_mle_data = 0x%08x", (u32)os_mle_data); sinit_mle_data = get_sinit_mle_data_start(txt_heap); //printf("\nsinit_mle_data = 0x%08x", (u32)sinit_mle_data); os_sinit_data = get_os_sinit_data_start(txt_heap); //printf("\nos_sinit_data = 0x%08x", (u32)os_sinit_data); #endif // Start APs. Choose wakeup mechanism based on // capabilities used. MLE Dev Guide says MLEs should // support both types of Wakeup mechanism. // We are jumping straight into the 32-bit portion of the // unity-mapped trampoline that starts at 64K // physical. Without SENTER, or with AMD, APs start in // 16-bit mode. We get to skip that. printf("\nBSP: _mle_join_start = 0x%08x, _ap_bootstrap_start = 0x%08x", (u32)_mle_join_start, (u32)_ap_bootstrap_start); // enable SMIs on BSP before waking APs (which will enable them on APs) // because some SMM may take immediate SMI and hang if AP gets in first //printf("Enabling SMIs on BSP\n"); //__getsec_smctrl(); // MLE Join structure constructed in runtimesup.S. Debug print. #ifndef __XMHF_VERIFICATION__ mle_join = (mle_join_t*)((u32)_mle_join_start - (u32)_ap_bootstrap_start + 0x10000); // XXX magic number #endif //printf("\nBSP: mle_join.gdt_limit = %x", mle_join->gdt_limit); //printf("\nBSP: mle_join.gdt_base = %x", mle_join->gdt_base); //printf("\nBSP: mle_join.seg_sel = %x", mle_join->seg_sel); //printf("\nBSP: mle_join.entry_point = %x", mle_join->entry_point); #ifndef __XMHF_VERIFICATION__ write_priv_config_reg(TXTCR_MLE_JOIN, (uint64_t)(unsigned long)mle_join); if (os_sinit_data->capabilities.rlp_wake_monitor) { printf("\nBSP: joining RLPs to MLE with MONITOR wakeup"); printf("\nBSP: rlp_wakeup_addr = 0x%x", sinit_mle_data->rlp_wakeup_addr); *((uint32_t *)(unsigned long)(sinit_mle_data->rlp_wakeup_addr)) = 0x01; }else { printf("\nBSP: joining RLPs to MLE with GETSEC[WAKEUP]"); __getsec_wakeup(); printf("\nBSP: GETSEC[WAKEUP] completed"); } #endif } #else //!__DRT__ printf("\nBSP: Using APIC to awaken APs..."); xmhf_baseplatform_arch_x86_wakeupAPs(); printf("\nBSP: APs should be awake."); #endif }
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; } }
/*===========================================================================* * lin_lin_copy * *===========================================================================*/ static int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, struct proc *dstproc, vir_bytes dstlinaddr, vir_bytes bytes) { u32_t addr; proc_nr_t procslot; assert(vm_running); assert(nfreepdes >= MAX_FREEPDES); assert(get_cpulocal_var(ptproc)); assert(get_cpulocal_var(proc_ptr)); assert(read_cr3() == get_cpulocal_var(ptproc)->p_seg.p_cr3); procslot = get_cpulocal_var(ptproc)->p_nr; assert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES); if(srcproc) assert(!RTS_ISSET(srcproc, RTS_SLOT_FREE)); if(dstproc) assert(!RTS_ISSET(dstproc, RTS_SLOT_FREE)); assert(!RTS_ISSET(get_cpulocal_var(ptproc), RTS_SLOT_FREE)); assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v); if(srcproc) assert(!RTS_ISSET(srcproc, RTS_VMINHIBIT)); if(dstproc) assert(!RTS_ISSET(dstproc, RTS_VMINHIBIT)); while(bytes > 0) { phys_bytes srcptr, dstptr; vir_bytes chunk = bytes; int changed = 0; #ifdef CONFIG_SMP unsigned cpu = cpuid; if (GET_BIT(srcproc->p_stale_tlb, cpu)) { changed = 1; UNSET_BIT(srcproc->p_stale_tlb, cpu); } if (GET_BIT(dstproc->p_stale_tlb, cpu)) { changed = 1; UNSET_BIT(dstproc->p_stale_tlb, cpu); } #endif /* Set up 4MB ranges. */ srcptr = createpde(srcproc, srclinaddr, &chunk, 0, &changed); dstptr = createpde(dstproc, dstlinaddr, &chunk, 1, &changed); if(changed) reload_cr3(); /* Copy pages. */ PHYS_COPY_CATCH(srcptr, dstptr, chunk, addr); if(addr) { /* If addr is nonzero, a page fault was caught. */ if(addr >= srcptr && addr < (srcptr + chunk)) { return EFAULT_SRC; } if(addr >= dstptr && addr < (dstptr + chunk)) { return EFAULT_DST; } panic("lin_lin_copy fault out of range"); /* Not reached. */ return EFAULT; } /* Update counter and addresses for next iteration, if any. */ bytes -= chunk; srclinaddr += chunk; dstlinaddr += chunk; } if(srcproc) assert(!RTS_ISSET(srcproc, RTS_SLOT_FREE)); if(dstproc) assert(!RTS_ISSET(dstproc, RTS_SLOT_FREE)); assert(!RTS_ISSET(get_cpulocal_var(ptproc), RTS_SLOT_FREE)); assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v); return OK; }
PRIVATE void pagefault( struct proc *pr, struct exception_frame * frame, int is_nested) { int in_physcopy = 0; reg_t pagefaultcr2; message m_pagefault; int err; assert(frame); pagefaultcr2 = read_cr2(); #if 0 printf("kernel: pagefault in pr %d, addr 0x%lx, his cr3 0x%lx, actual cr3 0x%lx\n", pr->p_endpoint, pagefaultcr2, pr->p_seg.p_cr3, read_cr3()); #endif if(pr->p_seg.p_cr3) { assert(pr->p_seg.p_cr3 == read_cr3()); } in_physcopy = (frame->eip > (vir_bytes) phys_copy) && (frame->eip < (vir_bytes) phys_copy_fault); if((is_nested || iskernelp(pr)) && catch_pagefaults && in_physcopy) { #if 0 printf("pf caught! addr 0x%lx\n", pagefaultcr2); #endif if (is_nested) { frame->eip = (reg_t) phys_copy_fault_in_kernel; } else { pr->p_reg.pc = (reg_t) phys_copy_fault; pr->p_reg.retreg = pagefaultcr2; } return; } if(is_nested) { panic("pagefault in kernel at pc 0x%lx address 0x%lx", frame->eip, pagefaultcr2); } /* System processes that don't have their own page table can't * have page faults. VM does have its own page table but also * can't have page faults (because VM has to handle them). */ if((pr->p_endpoint <= INIT_PROC_NR && !(pr->p_misc_flags & MF_FULLVM)) || pr->p_endpoint == VM_PROC_NR) { /* Page fault we can't / don't want to * handle. */ printf("pagefault for process %d ('%s'), pc = 0x%x, addr = 0x%x, flags = 0x%x, is_nested %d\n", pr->p_endpoint, pr->p_name, pr->p_reg.pc, pagefaultcr2, frame->errcode, is_nested); proc_stacktrace(pr); printf("pc of pagefault: 0x%lx\n", frame->eip); panic("page fault in system process: %d", pr->p_endpoint); return; } /* Don't schedule this process until pagefault is handled. */ assert(pr->p_seg.p_cr3 == read_cr3()); assert(!RTS_ISSET(pr, RTS_PAGEFAULT)); RTS_SET(pr, RTS_PAGEFAULT); /* tell Vm about the pagefault */ m_pagefault.m_source = pr->p_endpoint; m_pagefault.m_type = VM_PAGEFAULT; m_pagefault.VPF_ADDR = pagefaultcr2; m_pagefault.VPF_FLAGS = frame->errcode; if ((err = mini_send(pr, VM_PROC_NR, &m_pagefault, FROM_KERNEL))) { panic("WARNING: pagefault: mini_send returned %d\n", err); } return; }
int main(int ac, char **av) { unsigned long i; unsigned int pkey = 0x2; unsigned int pkru_ad = 0x10; unsigned int pkru_wd = 0x20; if (!(cpuid_indexed(7, 0).c & (1 << X86_FEATURE_PKU))) { printf("PKU not enabled\n"); return report_summary(); } setup_vm(); setup_alt_stack(); set_intr_alt_stack(14, pf_tss); wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_LMA); for (i = 0; i < USER_BASE; i += PAGE_SIZE) { *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= ~PT_USER_MASK; *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) |= ((unsigned long)pkey << PTE_PKEY_BIT); invlpg((void *)i); } for (i = USER_BASE; i < 2 * USER_BASE; i += PAGE_SIZE) { *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= ~USER_BASE; *get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) |= ((unsigned long)pkey << PTE_PKEY_BIT); invlpg((void *)i); } write_cr4(read_cr4() | X86_CR4_PKE); write_cr3(read_cr3()); init_test(); set_cr0_wp(1); write_pkru(pkru_ad); test = 21; report("write to supervisor page when pkru is ad and wp == 1", pf_count == 0 && test == 21); init_test(); set_cr0_wp(0); write_pkru(pkru_ad); test = 22; report("write to supervisor page when pkru is ad and wp == 0", pf_count == 0 && test == 22); init_test(); set_cr0_wp(1); write_pkru(pkru_wd); test = 23; report("write to supervisor page when pkru is wd and wp == 1", pf_count == 0 && test == 23); init_test(); set_cr0_wp(0); write_pkru(pkru_wd); test = 24; report("write to supervisor page when pkru is wd and wp == 0", pf_count == 0 && test == 24); init_test(); write_pkru(pkru_wd); set_cr0_wp(0); USER_VAR(test) = 25; report("write to user page when pkru is wd and wp == 0", pf_count == 0 && test == 25); init_test(); write_pkru(pkru_wd); set_cr0_wp(1); USER_VAR(test) = 26; report("write to user page when pkru is wd and wp == 1", pf_count == 1 && test == 26 && save == 25); init_test(); write_pkru(pkru_ad); (void)USER_VAR(test); report("read from user page when pkru is ad", pf_count == 1 && save == 26); // TODO: implicit kernel access from ring 3 (e.g. int) return report_summary(); }