Beispiel #1
0
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;
}
Beispiel #2
0
void page_arch_init(void)
{
	if (config.cpu_active > 1) {
		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
		return;
	}

	uintptr_t cur;
	unsigned int identity_flags =
	    PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE | PAGE_READ;
		
	page_mapping_operations = &pt_mapping_operations;
		
	page_table_lock(AS_KERNEL, true);
		
	/*
	 * PA2KA(identity) mapping for all low-memory frames.
	 */
	for (cur = 0; cur < min(config.identity_size, config.physmem_end);
	    cur += FRAME_SIZE)
		page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
		
	page_table_unlock(AS_KERNEL, true);
		
	exc_register(14, "page_fault", true, (iroutine_t) page_fault);
	write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
}
Beispiel #3
0
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());
}
Beispiel #4
0
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;
}
Beispiel #5
0
int schedule(long system_timer_ms)
{
	TRACE_MSG(("called system timer: %s", current_process->name));
	
	///check to see if the process is finished with its timeslice
	if (current_process->timetorun-- <= 0)
	{
		///reset the current process' time to run count
		current_process->timetorun = (current_process->priority)*PRIORITY_TO_TIMETORUN;
		
		///look through the process queue until a non-sleeping thread is found
		processes = processes->next;
		while (processes->pid->sleep > 0)
		{
			processes->pid->sleep--;
			processes = processes->next;
		}
		///when found, point current_process to the
		///non-sleeping thread
		current_process = processes->pid;	
		TRACE_MSG(("switched process: %s [stack: @0x%x]", current_process->name, current_process->esp));

		//change cr3
		write_cr3(current_process->cr3);
	}
	
	///the new esp must be passed back to the scheduler isr!
	return current_process->esp;
}
Beispiel #6
0
void PageTable::load()
{
	/* load the current page table */
	current_page_table = this;
	/* write the dir addr to the CR3 register  */
	write_cr3((unsigned long)page_directory);
}
Beispiel #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;
  }
void PageTable::load()
{
	write_cr3((unsigned long)page_directory);
	//current_page_table = this;
	Console::putui((unsigned int)read_cr3());
	Console::puts("load Hello \n");
}
Beispiel #9
0
void pci_enumerate(void) {
	uint64_t ecam_address = segment_groups[0];

	// TODO: factor out temporary mappings
	extern uint64_t kernel_pml4[], pd_map[];
	for (int i = 0; i < 8; i += 2) {
		pd_map[1 + i / 2] =
			ecam_address | PAGE_PRESENT | PAGE_WRITE | PAGE_CACHE_UC | PAGE_LARGE | PAGE_GLOBAL;
	}
	write_cr3(PHYS_KERNEL(kernel_pml4));
	ecam = (volatile void*)0xffffffffc0200000;

	struct pci_function *root = function_address(0, 0, 0);
	if ((root->header_type & 0x80) == 0) {
		enumerate_bus(0);
	} else {
		for (uint8_t function_id = 0; function_id < 8; function_id++) {
			struct pci_function *bus = function_address(0, 0, function_id);
			if (bus->vendor_id != 0xffff) {
				break;
			}

			enumerate_bus(function_id);
		}
	}
}
Beispiel #10
0
static int __init x86_create_initial_map()
{
	unsigned long phy= 0; 
	unsigned long *p = (unsigned long *)FAK_ARCH_X86_INIT_PGTABLE;				//The kernel topmost table
	int i;
	for (i = 0; i < 1024; i++) p[i] = 0;

	/*
		Kernel part in 4mb page;
	*/
	for (i = 0; i < 1024; i++)
	{	
		if (i == get_loaded_base() / 0x400000) phy = 0;							//如果到了内核的地址,还是从0开始映射,因为内核装的物理地址实际是在开头;
		p[i] = phy | 0x83;														//0x183 is the global
		phy += 0x400000;
	}
	write_cr3((unsigned long)p);

	phy = read_cr4();
	phy |= X86_CR4_PSE | X86_CR4_PGE;											//允许4MB页
	write_cr4(phy);

	phy = read_cr0();
	phy |= X86_CR0_PG;															//打开页表;
	phy &= ~(X86_CR0_CD | X86_CR0_NW);											//允许缓存;
	write_cr0(phy);

	return 0;
}
Beispiel #11
0
/* Enable paging on the CPU. Typically, a CPU start with paging disabled, and
	memory is accessed by addressing physical memory directly. After paging is
	enabled, memory is addressed logically. */
void PageTable::enable_paging() {
	//write the page_directory address into CR3
	write_cr3((unsigned long)current_page_table->get_page_directory());

	//set paging bit in CR0 to 1
	write_cr0(read_cr0() | 0x80000000);
}
Beispiel #12
0
/*
 * Call this when reinitializing a CPU.  It fixes the following potential
 * problems:
 *
 * - The ASID changed from what cpu_tlbstate thinks it is (most likely
 *   because the CPU was taken down and came back up with CR3's PCID
 *   bits clear.  CPU hotplug can do this.
 *
 * - The TLB contains junk in slots corresponding to inactive ASIDs.
 *
 * - The CPU went so far out to lunch that it may have missed a TLB
 *   flush.
 */
void initialize_tlbstate_and_flush(void)
{
	int i;
	struct mm_struct *mm = this_cpu_read(cpu_tlbstate.loaded_mm);
	u64 tlb_gen = atomic64_read(&init_mm.context.tlb_gen);
	unsigned long cr3 = __read_cr3();

	/* Assert that CR3 already references the right mm. */
	WARN_ON((cr3 & CR3_ADDR_MASK) != __pa(mm->pgd));

	/*
	 * Assert that CR4.PCIDE is set if needed.  (CR4.PCIDE initialization
	 * doesn't work like other CR4 bits because it can only be set from
	 * long mode.)
	 */
	WARN_ON(boot_cpu_has(X86_FEATURE_PCID) &&
		!(cr4_read_shadow() & X86_CR4_PCIDE));

	/* Force ASID 0 and force a TLB flush. */
	write_cr3(build_cr3(mm->pgd, 0));

	/* Reinitialize tlbstate. */
	this_cpu_write(cpu_tlbstate.last_user_mm_ibpb, LAST_USER_MM_IBPB);
	this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0);
	this_cpu_write(cpu_tlbstate.next_asid, 1);
	this_cpu_write(cpu_tlbstate.ctxs[0].ctx_id, mm->context.ctx_id);
	this_cpu_write(cpu_tlbstate.ctxs[0].tlb_gen, tlb_gen);

	for (i = 1; i < TLB_NR_DYN_ASIDS; i++)
		this_cpu_write(cpu_tlbstate.ctxs[i].ctx_id, 0);
}
Beispiel #13
0
static inline void switch_to_tboot_pt(void)
{
#ifdef CONFIG_X86_32
	load_cr3(initial_page_table);
#else
	write_cr3(real_mode_header->trampoline_pgd);
#endif
}
Beispiel #14
0
void __init paging_init()
{
	init_rootmap();

	kprintf("# root pgdir=%x\n", root_map.m_pgdir);
	kprintf("# root pgtable=%x\n", root_map.m_pgtable);
	write_cr3((u32)root_map.m_pgdir);
	write_cr0(read_cr0() | 0x80000000);
}
Beispiel #15
0
uint32_t loader() {
	Elf32_Ehdr *elf;
	Elf32_Phdr *ph = NULL;

	uint8_t buf[4096];

#ifdef HAS_DEVICE
	ide_read(buf, ELF_OFFSET_IN_DISK, 4096);
#else
	ramdisk_read(buf, ELF_OFFSET_IN_DISK, 4096);
#endif

	elf = (void*)buf;

	/* TODO: fix the magic number with the correct one */
	const uint32_t elf_magic = 0x7f454c46;
	uint32_t *p_magic = (void *)buf;
	nemu_assert(*p_magic == elf_magic);

	/* Load each program segment */
	for(; true; ) {
		/* Scan the program header table, load each segment into memory */
		if(ph->p_type == PT_LOAD) {	//PT_LOAT=1, Loadable program segment 

			/* TODO: read the content of the segment from the ELF file 
			 * to the memory region [VirtAddr, VirtAddr + FileSiz)
			 */
			 
			 
			/* TODO: zero the memory region 
			 * [VirtAddr + FileSiz, VirtAddr + MemSiz)
			 */


#ifdef IA32_PAGE
			/* Record the program break for future use. */
			extern uint32_t brk;
			uint32_t new_brk = ph->p_vaddr + ph->p_memsz - 1;
			if(brk < new_brk) { brk = new_brk; }
#endif
		}
	}

	volatile uint32_t entry = elf->e_entry;

#ifdef IA32_PAGE
	mm_malloc(KOFFSET - STACK_SIZE, STACK_SIZE);

#ifdef HAS_DEVICE
	create_video_mapping();
#endif

	write_cr3(get_ucr3());
#endif

	return entry;
}
Beispiel #16
0
/* set up page tables for kernel */
void init_page(void) {
	CR0 cr0;
	CR3 cr3;
	PDE *pdir = (PDE *)va_to_pa(kpdir);
	PTE *ptable = (PTE *)va_to_pa(kptable);
	uint32_t pdir_idx;

	/* make all PDEs invalid */
	memset(pdir, 0, NR_PDE * sizeof(PDE));

	/* fill PDEs */
	for (pdir_idx = 0; pdir_idx < PHY_MEM / PT_SIZE; pdir_idx ++) {
		pdir[pdir_idx].val = make_pde(ptable);
		pdir[pdir_idx + KOFFSET / PT_SIZE].val = make_pde(ptable);

		ptable += NR_PTE;
	}

	/* fill PTEs */

	/* We use inline assembly here to fill PTEs for efficiency.
	 * If you do not understand it, refer to the C code below.
	 */

	asm volatile ("std;\
	 1: stosl;\
		subl %0, %%eax;\
		jge 1b;\
		cld" : :
		"i"(PAGE_SIZE), "a"((PHY_MEM - PAGE_SIZE) | 0x7), "D"(ptable - 1));


	/*
		===== referenced code for the inline assembly above =====

		uint32_t pframe_addr = PHY_MEM - PAGE_SIZE;
		ptable --;

		// fill PTEs reversely
		for (; pframe_addr >= 0; pframe_addr -= PAGE_SIZE) {
			ptable->val = make_pte(pframe_addr);
			ptable --;
		}
	*/


	/* make CR3 to be the entry of page directory */
	cr3.val = 0;
	cr3.page_directory_base = ((uint32_t)pdir) >> 12;
	write_cr3(cr3.val);

	/* set PG bit in CR0 to enable paging */
	cr0.val = read_cr0();
	cr0.paging = 1;
	write_cr0(cr0.val);
}
Beispiel #17
0
/* 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());
}
Beispiel #18
0
/*-------------------------------------------------------------------------
 * set_PDBR - set the page table base register.
 *-------------------------------------------------------------------------
 */
void set_PDBR(int pid){
  STATWORD ps;
  // Disable interrupts
  disable(ps);
  unsigned long pdbr = proctab[pid].pdbr;
  write_cr3(pdbr);
  if(GDB)
    kprintf("PDBR %8x set to the base register of proc[%d]: %s\n",pdbr, pid, proctab[pid].pname);
  restore(ps);
}
Beispiel #19
0
Datei: elf.c Projekt: cjc96/cjcPA
uint32_t loader() {
	Elf32_Ehdr *elf;
	Elf32_Phdr *ph = NULL;

	uint8_t buf[4096];

#ifdef HAS_DEVICE
	ide_read(buf, ELF_OFFSET_IN_DISK, 4096);
#else
	ramdisk_read(buf, ELF_OFFSET_IN_DISK, 4096);
#endif

	elf = (void*)buf;

	/* fix the magic number with the correct one */
	const uint32_t elf_magic = 0x464c457f;
	uint32_t *p_magic = (void *)buf;
	nemu_assert(*p_magic == elf_magic);
	/* Load each program segment */
	int i;
	for(i=0;i<elf->e_phnum;i++ ) {
		/* Scan the program header table, load each segment into memory */
		ph=(void *)(elf->e_phoff + i * elf->e_phentsize + buf);
		if(ph->p_type == PT_LOAD) {
		//Log("success");
#ifdef IA32_PAGE
			/* Record the program break for future use. */
			extern uint32_t brk;
			uint32_t new_brk = ph->p_vaddr + ph->p_memsz - 1;
     		if(brk < new_brk) { brk = new_brk; }
			uint32_t pa=mm_malloc(ph->p_vaddr,ph->p_memsz);
#endif  
#ifndef HAS_DEVICE
			ramdisk_read((void*)pa, ELF_OFFSET_IN_DISK + ph->p_offset, ph->p_filesz); 
#else
			ide_read((void*)pa, ELF_OFFSET_IN_DISK + ph->p_offset, ph->p_filesz);
#endif
			memset((void*)(pa + ph->p_filesz), 0, ph->p_memsz - ph->p_filesz);
		}
	}

	volatile uint32_t entry = elf->e_entry;

#ifdef IA32_PAGE
	mm_malloc(KOFFSET - STACK_SIZE, STACK_SIZE);

#ifdef HAS_DEVICE
	create_video_mapping();
#endif

	write_cr3(get_ucr3());
#endif

	return entry;
}
Beispiel #20
0
/*-------------------------------------------------------------------------
 * xmunmap - xmunmap
 *-------------------------------------------------------------------------
 */
SYSCALL xmunmap(int virtpage )
{
  	
  	STATWORD ps;
  	
  	int getStoreValue, getPageNo;
  	bs_map_t* main_bs;
  	int getReturnValue, bs_no, page_no;
  	unsigned int temp;
  	
  	/* sanity check ! */
  	if ( (virtpage < 4096) )
  	{ 
	//	kprintf("xmummap call error: virtpage (%d) invalid! \n", virtpage);
		return SYSERR;
  	}

	disable(ps);
	//kprintf("\nInside xmunmap().. %d ", virtpage);

  
  	//getStoreValue = 20;
  
	getReturnValue = bsm_lookup(currpid, (virtpage*4096), &getStoreValue, &getPageNo);
    if (getReturnValue == SYSERR) {
       // kprintf("xmunmap(): could not find mapping!\n");
        restore(ps);
        return SYSERR;
    }
	
	// kprintf("\nxmunmap(): bs returned %d!\n", getStoreValue);

	bs_no = getStoreValue;
	page_no = getPageNo;
    // For all frames that are mapped decrease their refcnts
    bstore_dec_fr_refcnt(bs_no, virtpage);
    	
  	
  	getReturnValue = bsm_unmap(currpid, virtpage, bs_no);
  	if( getReturnValue == SYSERR )
  	{	
  		//kprintf("xmummap: bsm_unmap error");
  		restore(ps);
  		return(SYSERR);
  	}  	
  	
  	
  	//kprintf("\nxmummap: all OK");
  	
  	temp = ((proctab[currpid].pdbr)<<12);
	write_cr3(temp);
  	
  	restore(ps);
  	return(OK);
}
Beispiel #21
0
/* Wipe all early page tables except for the kernel symbol map */
static void __init reset_early_page_tables(void)
{
	unsigned long i;

	for (i = 0; i < PTRS_PER_PGD-1; i++)
		early_level4_pgt[i].pgd = 0;

	next_early_pgt = 0;

	write_cr3(__pa(early_level4_pgt));
}
Beispiel #22
0
void
schedule(void) {
  if (list_empty(&readyhead)) {
    current = &idle;
    return;
  }
  current=leaveProcQ(&readyhead, &readylen);
  enterProcQ(false, current, &readyhead);
  write_cr3(&(current->cr3));
  set_tss_esp0((uint32_t)(current->kstack+4095));
}
Beispiel #23
0
void PageTable::load()
{
    /*
     * Page table loaded into processor context
     * by loading the page directory address into 
     * the CR3 register
     */
    unsigned long *page_dir_addr = (unsigned long*) page_directory;
    current_page_table = this;
    write_cr3((long unsigned int)page_dir_addr);
}
Beispiel #24
0
/* Enable paging on the CPU. Typically, a CPU start with paging disabled, and
   memory is accessed by addressing physical memory directly. After paging is
   enabled, memory is addressed logically. 
*/
void PageTable::enable_paging()
{
	
    // put the page directory address into CR3.
    write_cr3((long unsigned int) current_page_table -> addressPageDirectory());
	
	//Set the paging bit in CR0 to 1. 	    
	write_cr0(read_cr0() | 0x80000000);

	//Set the paging_enabled bit to 1.
	paging_enabled = 1; 

	Console::puts("Page Table Enabled\n");
}
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());
}
Beispiel #26
0
/** Initialize segmentation - code/data/idt tables
 *
 */
void pm_init(void)
{
	descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
	tss_descriptor_t *tss_desc;
	
	/*
	 * Each CPU has its private GDT and TSS.
	 * All CPUs share one IDT.
	 */
	
	if (config.cpu_active == 1) {
		idt_init();
		/*
		 * NOTE: bootstrap CPU has statically allocated TSS, because
		 * the heap hasn't been initialized so far.
		 */
		tss_p = &tss;
	} else {
		/* We are going to use malloc, which may return
		 * non boot-mapped pointer, initialize the CR3 register
		 * ahead of page_init */
		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
		
		tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
		if (!tss_p)
			panic("Cannot allocate TSS.");
	}
	
	tss_initialize(tss_p);
	
	tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
	tss_desc->present = 1;
	tss_desc->type = AR_TSS;
	tss_desc->dpl = PL_KERNEL;
	
	gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
	gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
	
	gdtr_load(&gdtr);
	idtr_load(&idtr);
	/*
	 * As of this moment, the current CPU has its own GDT pointing
	 * to its own TSS. We just need to load the TR register.
	 */
	tr_load(GDT_SELECTOR(TSS_DES));
}
Beispiel #27
0
void __init efi_call_phys_epilog(pgd_t *save_pgd)
{
	/*
	 * After the lock is released, the original page table is restored.
	 */
	int pgd_idx, i;
	int nr_pgds;
	pgd_t *pgd;
	p4d_t *p4d;
	pud_t *pud;

	if (!efi_enabled(EFI_OLD_MEMMAP)) {
		write_cr3((unsigned long)save_pgd);
		__flush_tlb_all();
		return;
	}

	nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);

	for (pgd_idx = 0; pgd_idx < nr_pgds; pgd_idx++) {
		pgd = pgd_offset_k(pgd_idx * PGDIR_SIZE);
		set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]);

		if (!(pgd_val(*pgd) & _PAGE_PRESENT))
			continue;

		for (i = 0; i < PTRS_PER_P4D; i++) {
			p4d = p4d_offset(pgd,
					 pgd_idx * PGDIR_SIZE + i * P4D_SIZE);

			if (!(p4d_val(*p4d) & _PAGE_PRESENT))
				continue;

			pud = (pud_t *)p4d_page_vaddr(*p4d);
			pud_free(&init_mm, pud);
		}

		p4d = (p4d_t *)pgd_page_vaddr(*pgd);
		p4d_free(&init_mm, p4d);
	}

	kfree(save_pgd);

	__flush_tlb_all();
	early_code_mapping_set_exec(0);
}
Beispiel #28
0
static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush)
{
	unsigned long new_mm_cr3;

	if (need_flush) {
		invalidate_user_asid(new_asid);
		new_mm_cr3 = build_cr3(pgdir, new_asid);
	} else {
		new_mm_cr3 = build_cr3_noflush(pgdir, new_asid);
	}

	/*
	 * Caution: many callers of this function expect
	 * that load_cr3() is serializing and orders TLB
	 * fills with respect to the mm_cpumask writes.
	 */
	write_cr3(new_mm_cr3);
}
Beispiel #29
0
static void __restore_processor_state(struct saved_context *ctxt)
{
	/*
	 * control registers
	 */
	/* cr4 was introduced in the Pentium CPU */
	if (ctxt->cr4)
		write_cr4(ctxt->cr4);
	write_cr3(ctxt->cr3);
	write_cr2(ctxt->cr2);
	write_cr0(ctxt->cr0);

	/*
	 * now restore the descriptor tables to their proper values
	 * ltr is done i fix_processor_context().
	 */
	load_gdt(&ctxt->gdt);
	load_idt(&ctxt->idt);

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

	/*
	 * sysenter MSRs
	 */
	if (boot_cpu_has(X86_FEATURE_SEP))
		enable_sep_cpu();

	/*
	 * restore XCR0 for xsave capable cpu's.
	 */
	if (cpu_has_xsave)
		xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);

	fix_processor_context();
	do_fpu_end();
	mtrr_ap_init();
	mcheck_init(&boot_cpu_data);
}
Beispiel #30
0
/**
	@brief Switch memory context
*/
void km_arch_ctx_switch(struct km * pre_ctx, struct km * next_ctx)
{
	unsigned long cr3_physical;

	/* Get physical base of cr3 */
	cr3_physical = HAL_GET_BASIC_PHYADDRESS(next_ctx->translation_table);
	//TODO: not use this macro

	/* Write to cr3 to switch */
	write_cr3(cr3_physical);

#if 0
	/*load the LDT, if the LDT is different*/
	if(unlikely(pre_ctx->ldt!=new_ctx->ldt))
	{
		//printk("\nnew_ctx->ldt :%h,%d.",new_ctx->ldt,new_ctx->ldt_entries);
		set_ldt(new_ctx->ldt,new_ctx->ldt_entries);
	}
#endif
}