Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 655e4ed0 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

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: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a5a678c8
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
		if (pud_none(*pud))
			one_md_table_init(pud);
		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);
			vaddr += PMD_SIZE;
		}
@@ -191,22 +191,23 @@ static void __init fixaddr_user_init( void)
	pud_t *pud;
	pmd_t *pmd;
	pte_t *pte;
	unsigned long paddr, vaddr = FIXADDR_USER_START;
	phys_t p;
	unsigned long v, vaddr = FIXADDR_USER_START;

	if (!size)
		return;

	fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
	paddr = (unsigned long)alloc_bootmem_low_pages( size);
	memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size);
	paddr = __pa(paddr);
	v = (unsigned long) alloc_bootmem_low_pages(size);
	memcpy((void *) v , (void *) FIXADDR_USER_START, size);
	p = __pa(v);
	for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
		      paddr += PAGE_SIZE) {
		      p += PAGE_SIZE) {
		pgd = swapper_pg_dir + pgd_index(vaddr);
		pud = pud_offset(pgd, vaddr);
		pmd = pmd_offset(pud, vaddr);
		pte = pte_offset_kernel(pmd, vaddr);
		pte_set_val( (*pte), paddr, PAGE_READONLY);
		pte_set_val(*pte, p, PAGE_READONLY);
	}
#endif
}
+3 −3
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ struct page;
#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT)

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;
#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 __va(phys) to_virt((unsigned long) (phys))

#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
#define phys_to_pfn(p) ((pfn_t) ((p) >> PAGE_SHIFT))
#define pfn_to_phys(pfn) ((phys_t) ((pfn) << PAGE_SHIFT))

#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
+20 −1
Original line number Diff line number Diff line
@@ -11,7 +11,11 @@

/* PGDIR_SHIFT determines what a third-level page table entry can map */

#ifdef CONFIG_64BIT
#define PGDIR_SHIFT	30
#else
#define PGDIR_SHIFT	31
#endif
#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
#define PGDIR_MASK	(~(PGDIR_SIZE-1))

@@ -28,9 +32,15 @@
 */

#define PTRS_PER_PTE 512
#ifdef CONFIG_64BIT
#define PTRS_PER_PMD 512
#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
#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 pte_ERROR(e) \
@@ -49,7 +59,12 @@
#define pud_populate(mm, pud, 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))
#else
#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
#endif

static inline int pgd_newpage(pgd_t pgd)
{
	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; }

#ifdef CONFIG_64BIT
#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;
extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
+1 −1
Original line number Diff line number Diff line
@@ -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 __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 mk_pte(page, pgprot) \