Example #1
0
File: env.c Project: gzs715/JOS
//
// Frees env e and all memory it uses.
// 
void
env_free(struct Env *e)
{
	pte_t *pt;
	uint32_t pdeno, pteno;
	physaddr_t pa;
	
	// If freeing the current environment, switch to boot_pgdir
	// before freeing the page directory, just in case the page
	// gets reused.
	if (e == curenv)
		lcr3(boot_cr3);

	// Note the environment's demise.
	// cprintf("[%08x] free env %08x\n", curenv ? curenv->env_id : 0, e->env_id);

	// Flush all mapped pages in the user portion of the address space
	static_assert(UTOP % PTSIZE == 0);
	for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {

		// only look at mapped page tables
		if (!(e->env_pgdir[pdeno] & PTE_P))
			continue;

		// find the pa and va of the page table
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
		pt = (pte_t*) KADDR(pa);

		// unmap all PTEs in this page table
		for (pteno = 0; pteno <= PTX(~0); pteno++) {
			if (pt[pteno] & PTE_P)
				page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
		}

		// free the page table itself
		e->env_pgdir[pdeno] = 0;
		page_decref(pa2page(pa));

	}

	// free the page directory
	pa = e->env_cr3;
	e->env_pgdir = 0;
	e->env_cr3 = 0;
	

	page_decref(pa2page(pa));
	

	// return the environment to the free list
	e->env_status = ENV_FREE;
	LIST_INSERT_HEAD(&env_free_list, e, env_link);
}
Example #2
0
File: en_rx.c Project: brho/akaros
static void mlx4_en_destroy_allocator(struct mlx4_en_priv *priv,
				      struct mlx4_en_rx_ring *ring)
{
	panic("Disabled");
#if 0 // AKAROS_PORT
	struct mlx4_en_rx_alloc *page_alloc;
	int i;

	for (i = 0; i < priv->num_frags; i++) {
		const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];

		page_alloc = &ring->page_alloc[i];
		en_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
		       i, page_count(page_alloc->page));

		dma_unmap_page(priv->ddev, page_alloc->dma,
				page_alloc->page_size, PCI_DMA_FROMDEVICE);
		while (page_alloc->page_offset + frag_info->frag_stride <
		       page_alloc->page_size) {
			page_decref(page_alloc->page);
			page_alloc->page_offset += frag_info->frag_stride;
		}
		page_alloc->page = NULL;
	}
#endif
}
Example #3
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{	
	// Fill this function in
	struct PageInfo *pg;
	pte_t *pte;
	pte_t **pte_store=&pte;

	pg=page_lookup(pgdir,va,pte_store);
// If there is no physical page at that address, silently does nothing.
	if (!pg)
	{cprintf("page not found \n");
		return;}

//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
	
	page_decref(pg);
	//cprintf("page ref after decrement : %d \n",pg->pp_ref);
//- The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
	if(pte_store){
		**pte_store=0;
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
	tlb_invalidate(pgdir,va);	
	}
}
Example #4
0
File: env.c Project: anandab/akaros
// Initialize the kernel virtual memory layout for environment e.
// Allocate a page directory, set e->env_pgdir and e->env_cr3 accordingly,
// and initialize the kernel portion of the new environment's address space.
// Do NOT (yet) map anything into the user portion
// of the environment's virtual address space.
//
// Returns 0 on success, < 0 on error.  Errors include:
//	-ENOMEM if page directory or table could not be allocated.
//
int env_setup_vm(env_t *e)
{
	int i, ret;
	static page_t *shared_page = 0;

	if ((ret = arch_pgdir_setup(boot_pgdir, &e->env_pgdir)))
		return ret;
	/* TODO: verify there is nothing below ULIM */
	e->env_cr3 = arch_pgdir_get_cr3(e->env_pgdir);

	/* These need to be contiguous, so the kernel can alias them.  Note the
	 * pages return with a refcnt, but it's okay to insert them since we free
	 * them manually when the process is cleaned up. */
	if (!(e->procinfo = get_cont_pages(LOG2_UP(PROCINFO_NUM_PAGES), 0)))
		goto env_setup_vm_error_i;
	if (!(e->procdata = get_cont_pages(LOG2_UP(PROCDATA_NUM_PAGES), 0)))
		goto env_setup_vm_error_d;
	/* Normally we'd 0 the pages here.  We handle it in proc_init_proc*.  Don't
	 * start the process without calling those. */
	for (int i = 0; i < PROCINFO_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir, kva2page((void*)e->procinfo + i *
		                PGSIZE), (void*)(UINFO + i*PGSIZE), PTE_USER_RO) < 0)
			goto env_setup_vm_error;
	}
	for (int i = 0; i < PROCDATA_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir, kva2page((void*)e->procdata + i *
		                PGSIZE), (void*)(UDATA + i*PGSIZE), PTE_USER_RW) < 0)
			goto env_setup_vm_error;
	}
	for (int i = 0; i < PROCGINFO_NUM_PAGES; i++) {
		if (page_insert(e->env_pgdir,
		                kva2page((void*)&__proc_global_info + i * PGSIZE),
		                (void*)(UGINFO + i * PGSIZE), PTE_USER_RO) < 0)
			goto env_setup_vm_error;
	}
	/* Finally, set up the Global Shared Data page for all processes.  Can't be
	 * trusted, but still very useful at this stage for us.  Consider removing
	 * when we have real processes (TODO). 
	 *
	 * Note the page is alloced only the first time through, and its ref is
	 * stored in shared_page. */
	if (!shared_page) {
		if (upage_alloc(e, &shared_page, 1) < 0)
			goto env_setup_vm_error;
	}
	if (page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_USER_RW) < 0)
		goto env_setup_vm_error;

	return 0;

env_setup_vm_error:
	free_cont_pages(e->procdata, LOG2_UP(PROCDATA_NUM_PAGES));
env_setup_vm_error_d:
	free_cont_pages(e->procinfo, LOG2_UP(PROCINFO_NUM_PAGES));
env_setup_vm_error_i:
	page_decref(shared_page);
	env_user_mem_free(e, 0, UVPT);
	env_pagetable_free(e);
	return -ENOMEM;
}
Example #5
0
void
vector_clear(Vector *v)
{
    assert(v->elem != NULL);
   
    page_decref(kva2page(v->elem));
    
    v->elem = NULL;
    v->size = v->capacity = 0;
}
Example #6
0
int exit_mm(struct mm_struct *mm)
{
	pmd_t *pmd;
	pgd_t *pgd;
	uint32_t pgdno, pmdno;
	physaddr_t pa;

	struct vm_area_struct* vma = mm->mmap;
	struct page *page;
	
	if(!mm || !mm->mm_pgd)
		return 0;

	if(!atomic_dec_and_test(&mm->mm_count))
		return 0;

	delete_all_vma(mm);

	for (pgdno = 0; pgdno < pgd_index(KERNEL_BASE_ADDR); pgdno++) {
		pgd = mm->mm_pgd + pgdno;
		if(!pgd_present(*pgd) || pgd_none(*pgd))
			continue;
		pmd_t* tmp = (pmd_t *)pgd_page_vaddr(*pgd);
		
		for (pmdno = 0; pmdno < PTRS_PER_PMD; pmdno++) {
			pmd = tmp +  pmdno;
			if(!pmd_present(*pmd) || pmd_none(*pmd))
				continue;
			struct page* p = virt2page(pmd_page_vaddr(*pmd));
			page_decref(p);
			pmd_set(pmd,0,0);
		}
		struct page* p = virt2page(pgd_page_vaddr(*pgd));
		page_decref(p);
		pgd_set(pgd,0,0);
	}

	page = virt2page((viraddr_t)mm->mm_pgd);
	page_free(page);
	kfree(mm);

	return 0;
}
Example #7
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, uintptr_t va)
{
	pte_t *pte;
	Page *pp = page_lookup(pgdir, va, &pte);
	if (pp != NULL) {
		page_decref(pp);
		*pte = *pte & ~0x1;
		tlb_invalidate(pgdir, va);
	}
}
Example #8
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
//  tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
   // Fill this function in
   pte_t *pte;
   struct PageInfo *pp = page_lookup(pgdir, va, &pte);
   if (!pp || !(*pte & PTE_P)) return;
   page_decref(pp);
   *pte = 0;
   tlb_invalidate(pgdir, va);
}
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
        pte_t *tmppte;
        struct PageInfo *tmp = page_lookup(pgdir, va, &tmppte);
        if( tmp != NULL && (*tmppte & PTE_P)) {
                page_decref(tmp);
                *tmppte = 0;
        }
        tlb_invalidate(pgdir, va);
}
Example #10
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
	void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t* pte_store = NULL;
	struct PageInfo* pg = page_lookup(pgdir, va, &pte_store); 
	if (!pg) 
		return;
	page_decref(pg);	
	tlb_invalidate(pgdir, va);
	*pte_store = 0;
}
Example #11
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
    pte_t * pte_page;
    struct Page * page = page_lookup(pgdir, va, &pte_page);
    if(page) {
      page_decref(page);
      (* pte_page) = 0;
      tlb_invalidate(pgdir, va);
    }
}
Example #12
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t *pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	
	if (pp) {
		page_decref(pp);
		*pte = 0;
		tlb_invalidate(pgdir, va);
	}
}
Example #13
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
//     tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
    pte_t *table_entry;
    struct PageInfo *page = page_lookup(pgdir, va, &table_entry);
    if (page) {
        // Decrement/free page, reset table entry, and invalidate TLB entry.
        page_decref(page);
        *table_entry = 0x0;
        tlb_invalidate(pgdir, va);
    }
}
Example #14
0
File: pmap.c Project: ajsbu/cse506
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
	void
page_remove(pml4e_t *pml4e, void *va)
{
	// Fill this function in
	pte_t* pte = NULL;
	struct Page *page = page_lookup(pml4e, va, &pte);
	if(page != 0){
		page_decref(page);
		*pte = 0;
		tlb_invalidate(pml4e, va);
	}
}
//
// Invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
//
void
tlb_invalidate(pde_t *pgdir, void *va)
{
	// Flush the entry only if we're modifying the current address space.
	// For now, there is only one address space, so always invalidate.
        pte_t *tmppte;
        struct PageInfo *tmp = page_lookup(pgdir, va, &tmppte);
        if( tmp != NULL) {
                page_decref(tmp);
                *tmppte = 0;
        }
	invlpg(va);
}
Example #16
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t* pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	
	if (pp != NULL) {
		*pte = 0;
		page_decref(pp);
		tlb_invalidate(pgdir, va);
	}
}
Example #17
0
File: pmap.c Project: yuki252111/os
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t* pte;
	struct Page* res;
	res=page_lookup(pgdir,va,&pte);
	if(res!=NULL)
	{
		page_decref(res);
		*pte=0;
		tlb_invalidate(pgdir,va);
	}
}
static void free_ept_level(epte_t* eptrt, int level) {
    epte_t* dir = eptrt;
    int i;

    for(i=0; i<NPTENTRIES; ++i) {
        if(level != 0) {
            if(epte_present(dir[i])) {
                physaddr_t pa = epte_addr(dir[i]);
                free_ept_level((epte_t*) KADDR(pa), level-1);
                // free the table.
                page_decref(pa2page(pa));
            }
        } else {
            // Last level, free the guest physical page.
            if(epte_present(dir[i])) {
                physaddr_t pa = epte_addr(dir[i]);                
                page_decref(pa2page(pa));
            }
        }
    }
    return;
}
Example #19
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	//bluesea
	struct PageInfo *page = NULL;
	pte_t *ptep = NULL;
	if ((page = page_lookup(pgdir, va, &ptep)) != NULL){
		page_decref(page);
		*ptep = *ptep & (0xfff & ~PTE_P);
		tlb_invalidate(pgdir, va);
	}
}
Example #20
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
    // Lookup the page and store into page_table_entry
    pte_t * page_table_entry = NULL;
    struct PageInfo * page_info = page_lookup(pgdir, va, &page_table_entry);

    if (page_info != NULL) {
        // Decrement the counter and free if the refcount reaches zero
        page_decref(page_info);
        *page_table_entry = 0;
        tlb_invalidate(pgdir, va);
    }
}
Example #21
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t *pte_store;
	struct PageInfo *pp = page_lookup(pgdir, va, &pte_store);
	
	if(!pte_store || !(pte_store[0] & PTE_P)){
		return ;
	}
	page_decref(pp);
	*pte_store = 0;
	tlb_invalidate(pgdir, va);
}
Example #22
0
void page_remove(pgd_t* pgdir, viraddr_t va) 
{
	assert(pgdir);
	page_t *pf;
	pte_t *pte_store;
	pf = page_lookup(pgdir, va, &pte_store);

	if( pf == NULL ) return;
	
	//printk("free:%x\n",va);
	page_decref(pf);
	pte_set(*pte_store,0);
	refresh_tlb(pgdir, va);
}
Example #23
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	/*stone's solution for lab2*/
	pte_t* pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	if (pp != NULL){
		*pte = 0;
		page_decref(pp);
		tlb_invalidate(pgdir, va);		
	}
	return;
}
Example #24
0
File: map.c Project: spectrec/ann
void page_remove(pml4e_t *pml4, uintptr_t va)
{
	struct page *p;
	pte_t *pte;

	p = page_lookup(pml4, va, &pte);
	if (p == NULL)
		// nothing to do
		return;

	page_decref(p);
	*pte = 0;

	invlpg((void *)va);
}
Example #25
0
File: pmap.c Project: kelwin/6.828
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t *pte;
	struct Page *pp;

	if (!(pp = page_lookup(pgdir, va, &pte)))
		return;
	page_decref(pp);
	assert(pte);
	*pte = 0;
	tlb_invalidate(pgdir, va);

}
Example #26
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t *pte;
	struct PageInfo *pg = page_lookup(pgdir, va, &pte);
	if (!pg || !(*pte & PTE_P)) return;	//page not exist
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
	page_decref(pg);
//   - The pg table entry corresponding to 'va' should be set to 0.
	*pte = 0;
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
	tlb_invalidate(pgdir, va);
}
Example #27
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t *pte = pgdir_walk(pgdir,va,0);
	if (pte == NULL || !(*pte & PTE_P))
	{
		cprintf("remove an empty pte!\n");
		return ;
	}
	struct Page *pp = page_lookup(pgdir,va,0);
	*pte = 0;
	page_decref(pp);
	tlb_invalidate(pgdir,va);

}
Example #28
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t *ptep;
	struct PageInfo *pp = page_lookup(pgdir, va, &ptep);
	
	if(!pp) {
		return;
	}
	
	page_decref(pp);
	assert(ptep != NULL);
	*ptep = 0;
	tlb_invalidate(pgdir, va);
}
Example #29
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	// SUNUS, 28, October, 2013
	struct PageInfo *page;
	pte_t *pte = NULL;
	page = page_lookup(pgdir, va, &pte);
	if (!page)
		return ;
	page_decref(page);
	if (pte) {
		*pte = 0;
        }
	tlb_invalidate(pgdir, va);
}
Example #30
0
File: pmap.c Project: yahu/JOS
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
    // Fill this function in
    pte_t* pte=pgdir_walk(pgdir,va,0);
    struct Page* pg;

    if(!pte && !(*pte) )
        return ;

    pg=pa2page(PTE_ADDR(*pte));

    *pte=0;
    tlb_invalidate(pgdir, va);

    page_decref(pg);
}