From 4f76cd382213b29dd3658e3e1ea47c0c2be06f3c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:36:55 -0700 Subject: x86: add common mm/pgtable.c Add a common arch/x86/mm/pgtable.c file for common pagetable functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index 5886eed05886..ea9d27ad7f4e 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -1,5 +1,23 @@ +#ifndef _ASM_X86_PGALLOC_H +#define _ASM_X86_PGALLOC_H + +#include +#include /* for struct page */ +#include + +/* + * Allocate and free page tables. + */ +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); + +extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); + #ifdef CONFIG_X86_32 # include "pgalloc_32.h" #else # include "pgalloc_64.h" #endif + +#endif /* _ASM_X86_PGALLOC_H */ -- cgit v1.2.2 From 1d262d3a4932b5ae7222c8d9900696650ee95188 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:36:56 -0700 Subject: x86: put paravirt stubs into common asm/pgalloc.h Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index ea9d27ad7f4e..28773594f741 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -5,6 +5,16 @@ #include /* for struct page */ #include +#ifdef CONFIG_PARAVIRT +#include +#else +#define paravirt_alloc_pt(mm, pfn) do { } while (0) +#define paravirt_alloc_pd(mm, pfn) do { } while (0) +#define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0) +#define paravirt_release_pt(pfn) do { } while (0) +#define paravirt_release_pd(pfn) do { } while (0) +#endif + /* * Allocate and free page tables. */ -- cgit v1.2.2 From 397f687ab7f840dbe50353c4b60108672b653d0c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:36:57 -0700 Subject: x86: move pte functions into common asm/pgalloc.h Common definitions for 2-level pagetable functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index 28773594f741..0d15e21eefec 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -24,6 +24,22 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); +/* Should really implement gc for free page table pages. This could be + done with a reference count in struct page. */ + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + BUG_ON((unsigned long)pte & (PAGE_SIZE-1)); + free_page((unsigned long)pte); +} + +static inline void pte_free(struct mm_struct *mm, struct page *pte) +{ + __free_page(pte); +} + +extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte); + #ifdef CONFIG_X86_32 # include "pgalloc_32.h" #else -- cgit v1.2.2 From 170fdff7057d4247e3f28cca96d0db1fbc854e3b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:36:58 -0700 Subject: x86: move pmd functions into common asm/pgalloc.h Common definitions for 3-level pagetable functions. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index 0d15e21eefec..ae23839db20b 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -40,6 +40,39 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte) extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte); +static inline void pmd_populate_kernel(struct mm_struct *mm, + pmd_t *pmd, pte_t *pte) +{ + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) +{ + unsigned long pfn = page_to_pfn(pte); + + paravirt_alloc_pt(mm, pfn); + set_pmd(pmd, __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE)); +} + +#define pmd_pgtable(pmd) pmd_page(pmd) + +#if PAGETABLE_LEVELS > 2 +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); +} + +static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) +{ + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + free_page((unsigned long)pmd); +} + +extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); +#endif /* PAGETABLE_LEVELS > 2 */ + #ifdef CONFIG_X86_32 # include "pgalloc_32.h" #else -- cgit v1.2.2 From 5a5f8f42241cf09caec5530a7639cfa8dccc3a7b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:36:59 -0700 Subject: x86: move pgalloc pud and pgd operations into common place Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index ae23839db20b..73e5b0318476 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -71,12 +71,36 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) } extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); -#endif /* PAGETABLE_LEVELS > 2 */ -#ifdef CONFIG_X86_32 -# include "pgalloc_32.h" -#else -# include "pgalloc_64.h" -#endif +#ifdef CONFIG_X86_PAE +extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); +#else /* !CONFIG_X86_PAE */ +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT); + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))); +} +#endif /* CONFIG_X86_PAE */ + +#if PAGETABLE_LEVELS > 3 +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +{ + set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud))); +} + +static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); +} + +static inline void pud_free(struct mm_struct *mm, pud_t *pud) +{ + BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); + free_page((unsigned long)pud); +} + +extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud); +#endif /* PAGETABLE_LEVELS > 3 */ +#endif /* PAGETABLE_LEVELS > 2 */ #endif /* _ASM_X86_PGALLOC_H */ -- cgit v1.2.2 From 6944a9c8945212a0cc1de3589736d59ec542c539 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:37:01 -0700 Subject: x86: rename paravirt_alloc_pt etc after the pagetable structure Rename (alloc|release)_(pt|pd) to pte/pmd to explicitly match the name of the appropriate pagetable level structure. [ x86.git merge work by Mark McLoughlin ] Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Mark McLoughlin Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index 73e5b0318476..a25d54029874 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -8,11 +8,11 @@ #ifdef CONFIG_PARAVIRT #include #else -#define paravirt_alloc_pt(mm, pfn) do { } while (0) -#define paravirt_alloc_pd(mm, pfn) do { } while (0) -#define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0) -#define paravirt_release_pt(pfn) do { } while (0) -#define paravirt_release_pd(pfn) do { } while (0) +#define paravirt_alloc_pte(mm, pfn) do { } while (0) +#define paravirt_alloc_pmd(mm, pfn) do { } while (0) +#define paravirt_alloc_pmd_clone(pfn, clonepfn, start, count) do { } while (0) +#define paravirt_release_pte(pfn) do { } while (0) +#define paravirt_release_pmd(pfn) do { } while (0) #endif /* @@ -43,7 +43,7 @@ extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte); static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { - paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT); set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); } @@ -52,7 +52,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, { unsigned long pfn = page_to_pfn(pte); - paravirt_alloc_pt(mm, pfn); + paravirt_alloc_pte(mm, pfn); set_pmd(pmd, __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE)); } @@ -77,7 +77,7 @@ extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); #else /* !CONFIG_X86_PAE */ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { - paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT); + paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT); set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))); } #endif /* CONFIG_X86_PAE */ -- cgit v1.2.2 From 2761fa0920756dc471d297843646a4a9bca6656f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:37:02 -0700 Subject: x86: add pud_alloc for 4-level pagetables Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index a25d54029874..60e7f514ea01 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -11,8 +11,10 @@ #define paravirt_alloc_pte(mm, pfn) do { } while (0) #define paravirt_alloc_pmd(mm, pfn) do { } while (0) #define paravirt_alloc_pmd_clone(pfn, clonepfn, start, count) do { } while (0) +#define paravirt_alloc_pud(mm, pfn) do { } while (0) #define paravirt_release_pte(pfn) do { } while (0) #define paravirt_release_pmd(pfn) do { } while (0) +#define paravirt_release_pud(pfn) do { } while (0) #endif /* @@ -85,6 +87,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) #if PAGETABLE_LEVELS > 3 static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) { + paravirt_alloc_pud(mm, __pa(pud) >> PAGE_SHIFT); set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud))); } -- cgit v1.2.2 From 286cd49456ef980c4b9904064ef34c36017b8351 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 17 Mar 2008 16:37:06 -0700 Subject: x86: demacro pgalloc paravirt stubs Turn paravirt stubs into inline functions, so that the arguments are still typechecked. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgalloc.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'include/asm-x86/pgalloc.h') diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index 60e7f514ea01..91e4641f3f31 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -8,13 +8,14 @@ #ifdef CONFIG_PARAVIRT #include #else -#define paravirt_alloc_pte(mm, pfn) do { } while (0) -#define paravirt_alloc_pmd(mm, pfn) do { } while (0) -#define paravirt_alloc_pmd_clone(pfn, clonepfn, start, count) do { } while (0) -#define paravirt_alloc_pud(mm, pfn) do { } while (0) -#define paravirt_release_pte(pfn) do { } while (0) -#define paravirt_release_pmd(pfn) do { } while (0) -#define paravirt_release_pud(pfn) do { } while (0) +static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn) {} +static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn) {} +static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn, + unsigned long start, unsigned long count) {} +static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn) {} +static inline void paravirt_release_pte(unsigned long pfn) {} +static inline void paravirt_release_pmd(unsigned long pfn) {} +static inline void paravirt_release_pud(unsigned long pfn) {} #endif /* -- cgit v1.2.2