Example #1
0
inline static void *malloc_pages(size_t len, size_t alignment)
{
  void *p;

  CHECK_USED_AGAINST_MAX(len);

  p = smemalign(alignment, len);
  memset(p, 0, len);

  ACTUALLY_ALLOCATING_PAGES(len);
  LOGICALLY_ALLOCATING_PAGES(len);

  return p;
}
Example #2
0
/** @brief Function deals with the page fault
 *
 *  This is an amazing function.
 *
 *  @param  void
 *  @return void
 */
void page_fault_handler(void){

	int fault_addr = get_cr2();
	
	mutex_lock(&cur_task->pcb_mutex);

	uint32_t align_addr = fault_addr & PGALIGN_MASK;
	uint32_t *ptep = NULL;
	Page *phy_page = NULL;
	phy_page = page_lookup(cur_task->task_pgdir, align_addr, &ptep);
	uint32_t pte = *ptep;
	
	/** Catch COW page fualt */
	if((ptep != NULL) &&(pte & PTE_P) && (pte & PTE_COW))
	{	
		mutex_lock(&mtx_m.frame_mutex);
		if(phy_page->pp_ref == 1)
		{
			*ptep = (pte | PTE_W) &(~PTE_COW);
			mutex_unlock(&mtx_m.frame_mutex);
		}
		else{
			mutex_unlock(&mtx_m.frame_mutex);
			if(pte & PTE_RWMARK){
				lprintf("ERROR: Cannot access TXT or ro_data area!");
				mutex_unlock(&cur_task->pcb_mutex);
				sys_vanish();
				return;
			}
			Page *new_page = page_alloc();
			if(new_page == NULL){
	 		lprintf("ERROR: No pages for COW in page_fault_handler");
				mutex_unlock(&cur_task->pcb_mutex);
				sys_vanish();
				return;
			}
		  
			uint32_t *temp_page = smemalign(PAGE_SIZE, PAGE_SIZE);
			if (temp_page == NULL){
			lprintf("ERROR: No memory for temp_page in page_fault_handler!");
				mutex_unlock(&cur_task->pcb_mutex);
				sys_vanish();
				return;
			}

			/* Copy the physical page to a temporary page in kernel space */
			memcpy((void*)temp_page, (void*)align_addr, PAGE_SIZE);
			
			if(page_insert(cur_task->task_pgdir, new_page, align_addr, 
				PTE_P | PTE_U | PTE_W) < 0)
			{
			lprintf("ERROR: No memory for COW in page_fault_handler");
				mutex_unlock(&cur_task->pcb_mutex);
				sys_vanish();
				return;
			}
			/* Copy the content to the new mapped physical page */
			memcpy((void*)align_addr, (void*)temp_page, PAGE_SIZE);

			/* Free the temp physical page */
			sfree(temp_page, PAGE_SIZE);
			
			mutex_lock(&mtx_m.frame_mutex);
			phy_page->pp_ref--;
			mutex_unlock(&mtx_m.frame_mutex);
		}
	}
	/** Catch the ZFOD */
	else if ((ptep != NULL) &&(pte & PTE_P) && (pte & PTE_ZFOD))
	{
		Page *pg = page_alloc();
		if(pg == NULL){
	 	lprintf("ERROR: No pages for ZFOD in page_fault_handler");
			mutex_unlock(&cur_task->pcb_mutex);
			sys_vanish();
			return;
		}
		uint32_t perm = PTE_P | PTE_U | PTE_W;
		if(page_insert(cur_task->task_pgdir, pg, align_addr, perm) < 0)
		{
		lprintf("ERROR: No memory for ZFOD in page_fault_handler");	
			mutex_unlock(&cur_task->pcb_mutex);
			sys_vanish();
			return;
		}
		bzero((void*)align_addr, PAGE_SIZE);
	}
	/* Check if installed swexn handler can fix this up */
	else if(cur_thread->swexn_eip != NULL)
	{
		mutex_unlock(&cur_task->pcb_mutex);
		swexn_handler(HAS_ERROR_CODE, SWEXN_CAUSE_PAGEFAULT);
		return;
	}
	else{
		mutex_unlock(&cur_task->pcb_mutex);
		sys_vanish();
		return;
	}
	mutex_unlock(&cur_task->pcb_mutex);
	return;
}