aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-01-30 07:32:58 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:32:58 -0500
commit4891645e764d2e181b834509a689fcd12e890c10 (patch)
treef347227c2d5a5b112bca8fe76b149ccc5157ef84 /include
parent8405b122ad0dd75354b3bfed4de9a96514fd40cb (diff)
x86: unify paravirt pagetable accessors
Put all the defines for mapping pagetable operations to their native versions (for the non-paravirt case) into one place. Make the corresponding changes to paravirt.h. The tricky part here is that when a pagetable entry can't be updated atomically (ie, 32-bit PAE), we need special handlers for pte_clear, set_pte_atomic and set_pte_present. However, the other two modes don't need special handling for these, and can use a common set_pte(_at) path. [ mingo@elte.hu: fixes ] Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/asm-x86/paravirt.h21
-rw-r--r--include/asm-x86/pgtable-2level.h30
-rw-r--r--include/asm-x86/pgtable-3level.h15
-rw-r--r--include/asm-x86/pgtable.h63
-rw-r--r--include/asm-x86/pgtable_64.h64
5 files changed, 121 insertions, 72 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 24385decbd47..4aa06b929e48 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -1039,6 +1039,27 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
1039{ 1039{
1040 PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd); 1040 PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd);
1041} 1041}
1042
1043static inline void pmd_clear(pmd_t *pmdp)
1044{
1045 set_pmd(pmdp, __pmd(0));
1046}
1047
1048static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
1049{
1050 set_pte_at(mm, addr, ptep, __pte(0));
1051}
1052
1053static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
1054{
1055 set_pte(ptep, pte);
1056}
1057
1058static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
1059 pte_t *ptep, pte_t pte)
1060{
1061 set_pte(ptep, pte);
1062}
1042#endif /* CONFIG_X86_PAE */ 1063#endif /* CONFIG_X86_PAE */
1043 1064
1044/* Lazy mode for batching updates / context switch */ 1065/* Lazy mode for batching updates / context switch */
diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h
index 65cdc8f9e3b3..ce486bdbbbb7 100644
--- a/include/asm-x86/pgtable-2level.h
+++ b/include/asm-x86/pgtable-2level.h
@@ -15,29 +15,31 @@ static inline void native_set_pte(pte_t *ptep , pte_t pte)
15{ 15{
16 *ptep = pte; 16 *ptep = pte;
17} 17}
18static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, 18
19 pte_t *ptep , pte_t pte)
20{
21 native_set_pte(ptep, pte);
22}
23static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) 19static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
24{ 20{
25 *pmdp = pmd; 21 *pmdp = pmd;
26} 22}
27#ifndef CONFIG_PARAVIRT
28#define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
29#define set_pte_at(mm,addr,ptep,pteval) native_set_pte_at(mm, addr, ptep, pteval)
30#define set_pmd(pmdptr, pmdval) native_set_pmd(pmdptr, pmdval)
31#endif
32 23
33#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) 24static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
34#define set_pte_present(mm,addr,ptep,pteval) set_pte_at(mm,addr,ptep,pteval) 25{
26 native_set_pte(ptep, pte);
27}
28
29static inline void native_set_pte_present(struct mm_struct *mm, unsigned long addr,
30 pte_t *ptep, pte_t pte)
31{
32 native_set_pte(ptep, pte);
33}
35 34
36#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) 35static inline void native_pmd_clear(pmd_t *pmdp)
36{
37 native_set_pmd(pmdp, __pmd(0));
38}
37 39
38static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp) 40static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp)
39{ 41{
40 *xp = __pte(0); 42 *xp = native_make_pte(0);
41} 43}
42 44
43#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
index a123e687112f..5af7a44ed902 100644
--- a/include/asm-x86/pgtable-3level.h
+++ b/include/asm-x86/pgtable-3level.h
@@ -39,11 +39,6 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte)
39 smp_wmb(); 39 smp_wmb();
40 ptep->pte_low = pte.pte_low; 40 ptep->pte_low = pte.pte_low;
41} 41}
42static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr,
43 pte_t *ptep , pte_t pte)
44{
45 native_set_pte(ptep, pte);
46}
47 42
48/* 43/*
49 * Since this is only called on user PTEs, and the page fault handler 44 * Since this is only called on user PTEs, and the page fault handler
@@ -94,16 +89,6 @@ static inline void native_pmd_clear(pmd_t *pmd)
94 *(tmp + 1) = 0; 89 *(tmp + 1) = 0;
95} 90}
96 91
97#ifndef CONFIG_PARAVIRT
98#define set_pte(ptep, pte) native_set_pte(ptep, pte)
99#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
100#define set_pte_present(mm, addr, ptep, pte) native_set_pte_present(mm, addr, ptep, pte)
101#define set_pte_atomic(ptep, pte) native_set_pte_atomic(ptep, pte)
102#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd)
103#define set_pud(pudp, pud) native_set_pud(pudp, pud)
104#define pmd_clear(pmd) native_pmd_clear(pmd)
105#endif
106
107/* 92/*
108 * Pentium-II erratum A13: in PAE mode we explicitly have to flush 93 * Pentium-II erratum A13: in PAE mode we explicitly have to flush
109 * the TLB via cr3 if the top-level pgd is changed... 94 * the TLB via cr3 if the top-level pgd is changed...
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index eb14a70a4728..a1eeacdf9d8c 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -178,6 +178,39 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
178 return __pte(val); 178 return __pte(val);
179} 179}
180 180
181#ifdef CONFIG_PARAVIRT
182#include <asm/paravirt.h>
183#else /* !CONFIG_PARAVIRT */
184#define set_pte(ptep, pte) native_set_pte(ptep, pte)
185#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
186
187#define set_pte_present(mm, addr, ptep, pte) \
188 native_set_pte_present(mm, addr, ptep, pte)
189#define set_pte_atomic(ptep, pte) \
190 native_set_pte_atomic(ptep, pte)
191
192#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd)
193
194#ifndef __PAGETABLE_PUD_FOLDED
195#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd)
196#define pgd_clear(pgd) native_pgd_clear(pgd)
197#endif
198
199#ifndef set_pud
200# define set_pud(pudp, pud) native_set_pud(pudp, pud)
201#endif
202
203#ifndef __PAGETABLE_PMD_FOLDED
204#define pud_clear(pud) native_pud_clear(pud)
205#endif
206
207#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep)
208#define pmd_clear(pmd) native_pmd_clear(pmd)
209
210#define pte_update(mm, addr, ptep) do { } while (0)
211#define pte_update_defer(mm, addr, ptep) do { } while (0)
212#endif /* CONFIG_PARAVIRT */
213
181#endif /* __ASSEMBLY__ */ 214#endif /* __ASSEMBLY__ */
182 215
183#ifdef CONFIG_X86_32 216#ifdef CONFIG_X86_32
@@ -188,6 +221,22 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
188 221
189#ifndef __ASSEMBLY__ 222#ifndef __ASSEMBLY__
190 223
224/* local pte updates need not use xchg for locking */
225static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
226{
227 pte_t res = *ptep;
228
229 /* Pure native function needs no input for mm, addr */
230 native_pte_clear(NULL, 0, ptep);
231 return res;
232}
233
234static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr,
235 pte_t *ptep , pte_t pte)
236{
237 native_set_pte(ptep, pte);
238}
239
191#ifndef CONFIG_PARAVIRT 240#ifndef CONFIG_PARAVIRT
192/* 241/*
193 * Rules for using pte_update - it must be called after any PTE update which 242 * Rules for using pte_update - it must be called after any PTE update which
@@ -206,16 +255,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
206#define pte_update_defer(mm, addr, ptep) do { } while (0) 255#define pte_update_defer(mm, addr, ptep) do { } while (0)
207#endif 256#endif
208 257
209/* local pte updates need not use xchg for locking */
210static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
211{
212 pte_t res = *ptep;
213
214 /* Pure native function needs no input for mm, addr */
215 native_pte_clear(NULL, 0, ptep);
216 return res;
217}
218
219/* 258/*
220 * We only update the dirty/accessed state if we set 259 * We only update the dirty/accessed state if we set
221 * the dirty bit by hand in the kernel, since the hardware 260 * the dirty bit by hand in the kernel, since the hardware
@@ -287,10 +326,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
287 pte_update(mm, addr, ptep); 326 pte_update(mm, addr, ptep);
288} 327}
289 328
290#ifndef CONFIG_PARAVIRT
291#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep)
292#endif /* !CONFIG_PARAVIRT */
293
294#include <asm-generic/pgtable.h> 329#include <asm-generic/pgtable.h>
295#endif /* __ASSEMBLY__ */ 330#endif /* __ASSEMBLY__ */
296 331
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index 435e17187eb6..29fdeb8111bb 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -63,51 +63,59 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
63#define pgd_none(x) (!pgd_val(x)) 63#define pgd_none(x) (!pgd_val(x))
64#define pud_none(x) (!pud_val(x)) 64#define pud_none(x) (!pud_val(x))
65 65
66static inline void set_pte(pte_t *dst, pte_t val) 66struct mm_struct;
67
68static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
69 pte_t *ptep)
67{ 70{
68 *dst = val; 71 *ptep = native_make_pte(0);
69} 72}
70#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
71 73
72static inline void set_pmd(pmd_t *dst, pmd_t val) 74static inline void native_set_pte(pte_t *ptep, pte_t pte)
73{ 75{
74 *dst = val; 76 *ptep = pte;
75} 77}
76 78
77static inline void set_pud(pud_t *dst, pud_t val) 79static inline pte_t native_ptep_get_and_clear(pte_t *xp)
78{ 80{
79 *dst = val; 81#ifdef CONFIG_SMP
82 return native_make_pte(xchg(&xp->pte, 0));
83#else
84 /* native_local_ptep_get_and_clear, but duplicated because of cyclic dependency */
85 pte_t ret = *xp;
86 native_pte_clear(NULL, 0, xp);
87 return ret;
88#endif
80} 89}
81 90
82static inline void pud_clear (pud_t *pud) 91static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
83{ 92{
84 set_pud(pud, __pud(0)); 93 *pmdp = pmd;
85} 94}
86 95
87static inline void set_pgd(pgd_t *dst, pgd_t val) 96static inline void native_pmd_clear(pmd_t *pmd)
88{ 97{
89 *dst = val; 98 native_set_pmd(pmd, native_make_pmd(0));
90} 99}
91 100
92static inline void pgd_clear (pgd_t * pgd) 101static inline void native_set_pud(pud_t *pudp, pud_t pud)
93{ 102{
94 set_pgd(pgd, __pgd(0)); 103 *pudp = pud;
95} 104}
96 105
97#define native_ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0)) 106static inline void native_pud_clear(pud_t *pud)
107{
108 native_set_pud(pud, native_make_pud(0));
109}
98 110
99struct mm_struct; 111static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
112{
113 *pgdp = pgd;
114}
100 115
101static inline pte_t native_ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) 116static inline void native_pgd_clear(pgd_t * pgd)
102{ 117{
103 pte_t pte; 118 native_set_pgd(pgd, native_make_pgd(0));
104 if (full) {
105 pte = *ptep;
106 *ptep = __pte(0);
107 } else {
108 pte = native_ptep_get_and_clear(ptep);
109 }
110 return pte;
111} 119}
112 120
113#define pte_same(a, b) ((a).pte == (b).pte) 121#define pte_same(a, b) ((a).pte == (b).pte)
@@ -151,7 +159,6 @@ static inline unsigned long pmd_bad(pmd_t pmd)
151 159
152#define pte_none(x) (!pte_val(x)) 160#define pte_none(x) (!pte_val(x))
153#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) 161#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
154#define native_pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
155 162
156#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this right? */ 163#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) /* FIXME: is this right? */
157#define pte_page(x) pfn_to_page(pte_pfn(x)) 164#define pte_page(x) pfn_to_page(pte_pfn(x))
@@ -196,7 +203,6 @@ static inline unsigned long pmd_bad(pmd_t pmd)
196 pmd_index(address)) 203 pmd_index(address))
197#define pmd_none(x) (!pmd_val(x)) 204#define pmd_none(x) (!pmd_val(x))
198#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) 205#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
199#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
200#define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) 206#define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
201#define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) 207#define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
202 208