Add a helper function to convert an arbitrary mapped virtual address to a physical frame number. Adapted from code by Chris Wright, added support for large pages. Because of the placement, this needs to be a macro; pgd_offset_k requires init_mm to be defined, and getting the include files right seemed more complicated than a macroized implementation. A more proper location would be in asm/page.h, but that gets confounded by the use of pgd_offset_k() again. Signed-off-by: Zachary Amsden <zach@xxxxxxxxxx> Index: linux-2.6.13/include/asm-i386/pgtable.h =================================================================== --- linux-2.6.13.orig/include/asm-i386/pgtable.h 2005-08-24 09:43:27.000000000 -0700 +++ linux-2.6.13/include/asm-i386/pgtable.h 2005-08-24 09:47:38.000000000 -0700 @@ -388,6 +388,28 @@ static inline pte_t pte_modify(pte_t pte extern pte_t *lookup_address(unsigned long address); /* + * Helper function that returns physical page for virtual address. + * This assumes the mapping is valid. + */ +#define virt_to_pfn(_address) \ +({ \ + unsigned long long __paddr; \ + pgd_t *pgd = pgd_offset_k(_address); \ + pud_t *pud = pud_offset(pgd, (_address)); \ + pmd_t *pmd = pmd_offset(pud, (_address)); \ + if (pmd_large(*pmd)) \ + __paddr = (pmd_val(*pmd) & LARGE_PAGE_MASK) | \ + ((_address) & ~LARGE_PAGE_MASK); \ + else { \ + pte_t *pte = pte_offset_kernel(pmd, (_address));\ + __paddr = (pte_val(*pte) & PAGE_MASK) | \ + ((_address) & ~PAGE_MASK); \ + } \ + __paddr >>= PAGE_SHIFT; \ + __paddr; \ +}) + +/* * Make a given kernel text page executable/non-executable. * Returns the previous executability setting of that page (which * is used to restore the previous state). Used by the SMP bootup code.