uml: fix page table data sizes

Get the sizes of various pieces of data right when using three-level
page tables.  pgd and pmd entries remain at 32 bits in a 32-bit
compilation because page tables will remain in low memory.  So,
PGDIR_SHIFT, the PTRS_PER_* values, set_pud, set_pmd are conditional
on 64BIT.

More use of phys_t is made when there are physical memory addresses
floating around.

ObCheckpatchViolationJustification - the new typedef is an alternate
definition of pmd_t, which I can't really live without.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Jeff Dike 2008-02-04 22:30:55 -08:00 committed by Linus Torvalds
parent a5a678c80b
commit 655e4ed0c5
4 changed files with 33 additions and 13 deletions

View File

@ -132,7 +132,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
if (pud_none(*pud)) if (pud_none(*pud))
one_md_table_init(pud); one_md_table_init(pud);
pmd = pmd_offset(pud, vaddr); pmd = pmd_offset(pud, vaddr);
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) {
one_page_table_init(pmd); one_page_table_init(pmd);
vaddr += PMD_SIZE; vaddr += PMD_SIZE;
} }
@ -191,22 +191,23 @@ static void __init fixaddr_user_init( void)
pud_t *pud; pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
unsigned long paddr, vaddr = FIXADDR_USER_START; phys_t p;
unsigned long v, vaddr = FIXADDR_USER_START;
if ( ! size ) if (!size)
return; return;
fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
paddr = (unsigned long)alloc_bootmem_low_pages( size); v = (unsigned long) alloc_bootmem_low_pages(size);
memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size); memcpy((void *) v , (void *) FIXADDR_USER_START, size);
paddr = __pa(paddr); p = __pa(v);
for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE, for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
paddr += PAGE_SIZE) { p += PAGE_SIZE) {
pgd = swapper_pg_dir + pgd_index(vaddr); pgd = swapper_pg_dir + pgd_index(vaddr);
pud = pud_offset(pgd, vaddr); pud = pud_offset(pgd, vaddr);
pmd = pmd_offset(pud, vaddr); pmd = pmd_offset(pud, vaddr);
pte = pte_offset_kernel(pmd, vaddr); pte = pte_offset_kernel(pmd, vaddr);
pte_set_val( (*pte), paddr, PAGE_READONLY); pte_set_val(*pte, p, PAGE_READONLY);
} }
#endif #endif
} }

View File

@ -30,7 +30,7 @@ struct page;
#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT) #if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT)
typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long pte_low, pte_high; } pte_t;
typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32)) #define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32))
@ -106,8 +106,8 @@ extern unsigned long uml_physmem;
#define __pa(virt) to_phys((void *) (unsigned long) (virt)) #define __pa(virt) to_phys((void *) (unsigned long) (virt))
#define __va(phys) to_virt((unsigned long) (phys)) #define __va(phys) to_virt((unsigned long) (phys))
#define phys_to_pfn(p) ((p) >> PAGE_SHIFT) #define phys_to_pfn(p) ((pfn_t) ((p) >> PAGE_SHIFT))
#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) #define pfn_to_phys(pfn) ((phys_t) ((pfn) << PAGE_SHIFT))
#define pfn_valid(pfn) ((pfn) < max_mapnr) #define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v))) #define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))

View File

@ -11,7 +11,11 @@
/* PGDIR_SHIFT determines what a third-level page table entry can map */ /* PGDIR_SHIFT determines what a third-level page table entry can map */
#ifdef CONFIG_64BIT
#define PGDIR_SHIFT 30 #define PGDIR_SHIFT 30
#else
#define PGDIR_SHIFT 31
#endif
#define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1)) #define PGDIR_MASK (~(PGDIR_SIZE-1))
@ -28,9 +32,15 @@
*/ */
#define PTRS_PER_PTE 512 #define PTRS_PER_PTE 512
#ifdef CONFIG_64BIT
#define PTRS_PER_PMD 512 #define PTRS_PER_PMD 512
#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
#define PTRS_PER_PGD 512 #define PTRS_PER_PGD 512
#else
#define PTRS_PER_PMD 1024
#define PTRS_PER_PGD 1024
#endif
#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0 #define FIRST_USER_ADDRESS 0
#define pte_ERROR(e) \ #define pte_ERROR(e) \
@ -49,7 +59,12 @@
#define pud_populate(mm, pud, pmd) \ #define pud_populate(mm, pud, pmd) \
set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd))) set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
#ifdef CONFIG_64BIT
#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval)) #define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval))
#else
#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
#endif
static inline int pgd_newpage(pgd_t pgd) static inline int pgd_newpage(pgd_t pgd)
{ {
return(pgd_val(pgd) & _PAGE_NEWPAGE); return(pgd_val(pgd) & _PAGE_NEWPAGE);
@ -57,7 +72,11 @@ static inline int pgd_newpage(pgd_t pgd)
static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; } static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
#ifdef CONFIG_64BIT
#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval)) #define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval))
#else
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
#endif
struct mm_struct; struct mm_struct;
extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);

View File

@ -262,7 +262,7 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys)) #define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
#define __virt_to_page(virt) phys_to_page(__pa(virt)) #define __virt_to_page(virt) phys_to_page(__pa(virt))
#define page_to_phys(page) pfn_to_phys(page_to_pfn(page)) #define page_to_phys(page) pfn_to_phys((pfn_t) page_to_pfn(page))
#define virt_to_page(addr) __virt_to_page((const unsigned long) addr) #define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
#define mk_pte(page, pgprot) \ #define mk_pte(page, pgprot) \