RE: identify a vitual address

Eli Cohen <eli-VPRAkNaXOzVS1MOuV/[email protected]>
Newsgroups gmane.linux.redhat.taroon
Message-ID <[email protected]>
Attached the implementation for AS 2.1

/*
 * Translate a virtual address to physical address
 *
 */
MT_phys_addr_t MOSAL_virt_to_phys_ex(const MT_virt_addr_t va, struct page
**page_pp)
{
  pgd_t *pgd;
  pmd_t *pmd;
  pte_t *pte;
  mem_map_t * page;
  MT_phys_addr_t pa; 
  spinlock_t *page_table_lock_p;
  pte_t *pte_b;

  if ( in_interrupt() ) {
    MTL_ERROR1(MT_FLFMT("%s: called in interrupt"), __func__);
    return INVAL_PHYS_ADDR;
  }

  /* advanced server 2.1 implementation */
  if ( va < PAGE_OFFSET ) {
    page_table_lock_p = &current->mm->page_table_lock;
    spin_lock(page_table_lock_p);
    pgd = pgd_offset(current->mm, va);
    if (pgd_none(*pgd) || pgd_bad(*pgd)) {
      spin_unlock(page_table_lock_p);
      MTL_ERROR1(MT_FLFMT("bad pgd"));
      return INVAL_PHYS_ADDR;
    }
  }
  else if ( va<(MT_virt_addr_t)high_memory ) {
    MTL_TRACE7(MT_FLFMT("kernel logical memory: va=0x"VIRT_ADDR_FMT",
virt_to_phys(va)=0x%lx"), va, virt_to_phys((void *)va));
    if ( page_pp ) *page_pp = &mem_map[(va-PAGE_OFFSET)>>PAGE_SHIFT];
    return virt_to_phys((void *)va);
  }
  else {
    page_table_lock_p = &init_mm.page_table_lock;
    spin_lock(page_table_lock_p);
    pgd = pgd_offset_k(va);
  }

  pmd = pmd_offset(pgd, va);
  if (pmd_bigpage(*pmd)) {
    MTL_TRACE7(MT_FLFMT("Big page !!!"));
    page =  pmd_page(*pmd) + (va & BIGPAGE_MASK) / PAGE_SIZE;
  }
  else {
    if (pmd_none(*pmd) || pmd_bad(*pmd)) {
      spin_unlock(page_table_lock_p);
      MTL_ERROR1(MT_FLFMT("bad pmd: va="VIRT_ADDR_FMT), va);
      return INVAL_PHYS_ADDR;
    }

    spin_unlock(page_table_lock_p); /* free the lock since kmap may block */
    pte_b = kmap(mem_map+(pmd_val(*pmd)>>PAGE_SHIFT));
    spin_lock(page_table_lock_p);
    if (!pte_b) {
      spin_unlock(page_table_lock_p);
      MTL_ERROR1(MT_FLFMT("%s: failed to map page table: va="VIRT_ADDR_FMT),
__func__, va);
      return INVAL_PHYS_ADDR;
    }

    pte = pte_b + __pte_offset(va);

    if ( !pte_present(*pte) ) {
      spin_unlock(page_table_lock_p);
      MTL_ERROR1(MT_FLFMT("pte points to a non present page frame !!!:
va="VIRT_ADDR_FMT), va);
      kunmap(mem_map+(pmd_val(*pmd)>>PAGE_SHIFT));
      return INVAL_PHYS_ADDR;
    }

    page = pte_page(*pte);
    kunmap(mem_map+(pmd_val(*pmd)>>PAGE_SHIFT));
  }
  spin_unlock(page_table_lock_p);

  if(!VALID_PAGE(page))
  {
      MTL_ERROR4("%s: invalid memory address va="VIRT_ADDR_FMT"\n",
__func__, va);
      return INVAL_PHYS_ADDR;
  }

  MTL_TRACE4("%s: page address=%p\n", __func__, page);

  if ( page_pp ) *page_pp = page;
  pa = ((MT_phys_addr_t)(page - mem_map) << PAGE_SHIFT) | (va & (PAGE_SIZE -
1));

  MTL_TRACE4("%s: va="VIRT_ADDR_FMT", pa="PHYS_ADDR_FMT"\n", __func__, va,
pa);

  return pa;
}

-----Original Message-----
From: Arjan van de Ven [mailto:[email protected]]
Sent: Tuesday, September 16, 2003 12:23 PM
To: [email protected]
Subject: Re: identify a vitual address


On Tue, 2003-09-16 at 11:10, Eli Cohen wrote:
> Hi,
> I have to implement a function that returns the physical address given
> the virtual address. I use a method similar to follow_page()
> implementation. 

can you post a pointer to the source of your module? That way it's more
obvious why you're trying to do what you do...,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.