Esempio n. 1
0
/* Kontrollera alla adresser från och med start till och med den
 * adress som först innehåller ett noll-tecken, `\0'. (C-strängar
 * lagras på detta sätt.) */
bool verify_variable_length(char* buf)
{
  /*if(pagedir_get_page(thread_current()->pagedir, (buf)) == NULL)
    return false;*/
  int i=0;
  unsigned pg_last = pg_no(buf);
  while(true)
  {
    if(i==0 || pg_no(buf+i) != pg_last)
    {
      if(pagedir_get_page(thread_current()->pagedir, (buf+i)) == NULL)
          return false;
      if(is_end_of_string(buf+i))
        break;
    }
    else if(pg_no(buf+i) == pg_last)
    {
      if(is_end_of_string(buf+i))
        break;
    }
    pg_last = pg_no(buf+i);
    ++i;
  }
  return true;
}
Esempio n. 2
0
/* Frees the PAGE_CNT pages starting at PAGES. */
void
palloc_free_multiple (void *pages, size_t page_cnt) 
{
  struct pool *pool;
  size_t page_idx;

  ASSERT (pg_ofs (pages) == 0);
  if (pages == NULL || page_cnt == 0)
    return;

  if (page_from_pool (&kernel_pool, pages))
    pool = &kernel_pool;
  else if (page_from_pool (&user_pool, pages))
    pool = &user_pool;
  else
    NOT_REACHED ();

  page_idx = pg_no (pages) - pg_no (pool->base);

#ifndef NDEBUG
  memset (pages, 0xcc, PGSIZE * page_cnt);
#endif

  ASSERT (bitmap_all (pool->used_map, page_idx, page_cnt));
  bitmap_set_multiple (pool->used_map, page_idx, page_cnt, false);
}
Esempio n. 3
0
/* Returns true if PAGE was allocated from POOL,
   false otherwise. */
static bool
page_from_pool (const struct pool *pool, void *page) 
{
  size_t page_no = pg_no (page);
  size_t start_page = pg_no (pool->base);
  size_t end_page = start_page + bitmap_size (pool->used_map);

  return page_no >= start_page && page_no < end_page;
}
Esempio n. 4
0
/* Fill a frametable_entry with data
 */
void
frametable_entry_create(struct frametable_entry* fte,
                        struct pagetable_entry* pte,
                        tid_t tid,
                        void *virt_address,
                        bool pin) {
    fte->pte = pte;
    fte->tid = tid;
    fte->virt_address = pg_no(virt_address);
    fte->pin = pin;
}
Esempio n. 5
0
/*
 * Converts a pointer to any address into a number from
 * 0 to USER_PAGES-1 (the amount of pages in the userpool)
 * This can be used to as an index to access the frames
 * within the frame table.
 */
static uint32_t
page_to_pagenum(void *page) {
    // pages are consecutive and nothing can be before the base
    ASSERT(page >= frametable.base_addr);

    // remove offset within frame
    page = pg_round_down(page);
    // address shift relative to base addr
    page -= (uintptr_t) frametable.base_addr;
    return pg_no(page);
}
Esempio n. 6
0
/* Kontrollera alla adresser från och med start till och inte med
 * (start+length). */
bool verify_fix_length(void* buf, int length)
{
  /*if(buf == NULL)
    return false;*/
  /*if(pagedir_get_page(thread_current()->pagedir,buf) == NULL)
	 return false;*/
  int i=0;
  if(pagedir_get_page(thread_current()->pagedir, (buf)) == NULL)
    return false;
  unsigned pg_last = pg_no(buf);
  for(i=0;i<length;++i)
  {
    if(pg_no(buf) != pg_last)
    {
      if(pagedir_get_page(thread_current()->pagedir, (buf)) == NULL)
          return false;
    }
    pg_last = pg_no(buf);
    buf = (char*)buf + 1;
  }
  return true;
}
Esempio n. 7
0
/* Obtains a single free page and returns its kernel virtual
   address.
   If PAL_USER is set, the page is obtained from the user pool,
   otherwise from the kernel pool.  If PAL_ZERO is set in FLAGS,
   then the page is filled with zeros.  If no pages are
   available, returns a null pointer, unless PAL_ASSERT is set in
   FLAGS, in which case the kernel panics. */
void *
palloc_page (enum palloc_flags flags, void * upage, bool writable) 
{
   bool success = false;
   if(!(flags & PAL_USER))
   PANIC ("This function cannot be called without PAL_USER flag set\n");

   struct pool *pool = &frame_table.frame_pool;
   size_t page_idx;

   // empty page, and set to used
   lock_acquire (&pool->lock);
   page_idx = bitmap_scan_and_flip (pool->used_map, 0, 1, false);
   lock_release (&pool->lock);

   /* sets the members of cur_frame struct after is it allocated */
   struct frame_entry * cur_frame;
   cur_frame = frame_table.frames + page_idx;
   cur_frame->pid = thread_current()->tid;
   cur_frame->page_num = pg_no(upage);
   cur_frame->reference = true;  
   cur_frame->dirty = false;
   cur_frame->resident = true;
   success = install_page (upage, cur_frame->kpage, writable);

   if(DBG)printf("success after in mapping upage %p to kpage %p in palloc page = %d\n", upage, cur_frame->kpage, success);

   // execute flags
   if(!success)
   {
      if (flags & PAL_ASSERT)
         PANIC ("palloc_get: out of pages"); // change this?
      return NULL;
   }
   else if (flags & PAL_ZERO)
      memset (upage, 0, PGSIZE);

   return cur_frame->kpage;
}
Esempio n. 8
0
/* Validates all pointers between start and end in a few page table
   inspections as possible. Same notes as validate_byte(). */
static void validate_range(void *start, void *end) {
  int i;
  for(i = pg_no(end) - pg_no(start); i >= 0; i--)
    validate_byte(start + (PGSIZE * i));
}