aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2007-05-02 13:27:13 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:13 -0400
commit3dc494e86d1c93afd4c66385f270899dbfae483d (patch)
tree6583b57492dc91ef7cc6c23a233f7d5bb95bb5f6 /arch/i386
parent45876233605c268e929a7875081e129debe34bdc (diff)
[PATCH] i386: PARAVIRT: Add pagetable accessors to pack and unpack pagetable entries
Add a set of accessors to pack, unpack and modify page table entries (at all levels). This allows a paravirt implementation to control the contents of pgd/pmd/pte entries. For example, Xen uses this to convert the (pseudo-)physical address into a machine address when populating a pagetable entry, and converting back to pphys address when an entry is read. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Acked-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/paravirt.c84
-rw-r--r--arch/i386/kernel/vmi.c6
2 files changed, 15 insertions, 75 deletions
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c
index 3fdbd1f62379..cba7a15ce1b0 100644
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -117,78 +117,6 @@ static void native_flush_tlb_single(u32 addr)
117 __native_flush_tlb_single(addr); 117 __native_flush_tlb_single(addr);
118} 118}
119 119
120#ifndef CONFIG_X86_PAE
121static void native_set_pte(pte_t *ptep, pte_t pteval)
122{
123 *ptep = pteval;
124}
125
126static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval)
127{
128 *ptep = pteval;
129}
130
131static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval)
132{
133 *pmdp = pmdval;
134}
135
136#else /* CONFIG_X86_PAE */
137
138static void native_set_pte(pte_t *ptep, pte_t pte)
139{
140 ptep->pte_high = pte.pte_high;
141 smp_wmb();
142 ptep->pte_low = pte.pte_low;
143}
144
145static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte)
146{
147 ptep->pte_high = pte.pte_high;
148 smp_wmb();
149 ptep->pte_low = pte.pte_low;
150}
151
152static void native_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
153{
154 ptep->pte_low = 0;
155 smp_wmb();
156 ptep->pte_high = pte.pte_high;
157 smp_wmb();
158 ptep->pte_low = pte.pte_low;
159}
160
161static void native_set_pte_atomic(pte_t *ptep, pte_t pteval)
162{
163 set_64bit((unsigned long long *)ptep,pte_val(pteval));
164}
165
166static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval)
167{
168 set_64bit((unsigned long long *)pmdp,pmd_val(pmdval));
169}
170
171static void native_set_pud(pud_t *pudp, pud_t pudval)
172{
173 *pudp = pudval;
174}
175
176static void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
177{
178 ptep->pte_low = 0;
179 smp_wmb();
180 ptep->pte_high = 0;
181}
182
183static void native_pmd_clear(pmd_t *pmd)
184{
185 u32 *tmp = (u32 *)pmd;
186 *tmp = 0;
187 smp_wmb();
188 *(tmp + 1) = 0;
189}
190#endif /* CONFIG_X86_PAE */
191
192/* These are in entry.S */ 120/* These are in entry.S */
193extern void native_iret(void); 121extern void native_iret(void);
194extern void native_irq_enable_sysexit(void); 122extern void native_irq_enable_sysexit(void);
@@ -282,14 +210,26 @@ struct paravirt_ops paravirt_ops = {
282 .set_pmd = native_set_pmd, 210 .set_pmd = native_set_pmd,
283 .pte_update = paravirt_nop, 211 .pte_update = paravirt_nop,
284 .pte_update_defer = paravirt_nop, 212 .pte_update_defer = paravirt_nop,
213
214 .ptep_get_and_clear = native_ptep_get_and_clear,
215
285#ifdef CONFIG_X86_PAE 216#ifdef CONFIG_X86_PAE
286 .set_pte_atomic = native_set_pte_atomic, 217 .set_pte_atomic = native_set_pte_atomic,
287 .set_pte_present = native_set_pte_present, 218 .set_pte_present = native_set_pte_present,
288 .set_pud = native_set_pud, 219 .set_pud = native_set_pud,
289 .pte_clear = native_pte_clear, 220 .pte_clear = native_pte_clear,
290 .pmd_clear = native_pmd_clear, 221 .pmd_clear = native_pmd_clear,
222
223 .pmd_val = native_pmd_val,
224 .make_pmd = native_make_pmd,
291#endif 225#endif
292 226
227 .pte_val = native_pte_val,
228 .pgd_val = native_pgd_val,
229
230 .make_pte = native_make_pte,
231 .make_pgd = native_make_pgd,
232
293 .irq_enable_sysexit = native_irq_enable_sysexit, 233 .irq_enable_sysexit = native_irq_enable_sysexit,
294 .iret = native_iret, 234 .iret = native_iret,
295 235
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index 8f3bac473450..ea77d93f59dd 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -443,13 +443,13 @@ static void vmi_release_pd(u32 pfn)
443 ((level) | (is_current_as(mm, user) ? \ 443 ((level) | (is_current_as(mm, user) ? \
444 (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0)) 444 (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0))
445 445
446static void vmi_update_pte(struct mm_struct *mm, u32 addr, pte_t *ptep) 446static void vmi_update_pte(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
447{ 447{
448 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); 448 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
449 vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); 449 vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
450} 450}
451 451
452static void vmi_update_pte_defer(struct mm_struct *mm, u32 addr, pte_t *ptep) 452static void vmi_update_pte_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
453{ 453{
454 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); 454 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
455 vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0)); 455 vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0));
@@ -462,7 +462,7 @@ static void vmi_set_pte(pte_t *ptep, pte_t pte)
462 vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT); 462 vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT);
463} 463}
464 464
465static void vmi_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) 465static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
466{ 466{
467 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); 467 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
468 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); 468 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));