Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / arch / x86 / include / mach-xen / asm / pgtable.h
1 #ifndef _ASM_X86_PGTABLE_H
2 #define _ASM_X86_PGTABLE_H
3
4 #include <asm/page.h>
5 #include <asm/e820.h>
6
7 #include <asm/pgtable_types.h>
8
9 /*
10  * Macro to mark a page protection value as UC-
11  */
12 #define pgprot_noncached(prot)                                  \
13         ((boot_cpu_data.x86 > 3)                                \
14          ? (__pgprot(pgprot_val(prot) | _PAGE_CACHE_UC_MINUS))  \
15          : (prot))
16
17 #ifndef __ASSEMBLY__
18
19 #include <asm/x86_init.h>
20
21 /*
22  * ZERO_PAGE is a global shared page that is always zero: used
23  * for zero-mapped memory areas etc..
24  */
25 extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
26 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
27
28 extern spinlock_t pgd_lock;
29 extern struct list_head pgd_list;
30
31 extern struct mm_struct *pgd_page_get_mm(struct page *page);
32
33 #define set_pte(ptep, pte)              xen_set_pte(ptep, pte)
34 #define set_pte_at(mm, addr, ptep, pte) xen_set_pte_at(mm, addr, ptep, pte)
35 #define set_pmd_at(mm, addr, pmdp, pmd) xen_set_pmd_at(mm, addr, pmdp, pmd)
36
37 #define set_pmd(pmdp, pmd)              xen_set_pmd(pmdp, pmd)
38
39 #ifndef __PAGETABLE_PUD_FOLDED
40 #define set_pgd(pgdp, pgd)              xen_set_pgd(pgdp, pgd)
41 #define pgd_clear(pgd)                  xen_pgd_clear(pgd)
42 #endif
43
44 #ifndef set_pud
45 # define set_pud(pudp, pud)             xen_set_pud(pudp, pud)
46 #endif
47
48 #ifndef __PAGETABLE_PMD_FOLDED
49 #define pud_clear(pud)                  xen_pud_clear(pud)
50 #endif
51
52 #define pte_clear(mm, addr, ptep)       xen_pte_clear(mm, addr, ptep)
53 #define pmd_clear(pmd)                  xen_pmd_clear(pmd)
54
55 #define pte_update(mm, addr, ptep)              do { } while (0)
56 #define pte_update_defer(mm, addr, ptep)        do { } while (0)
57 #define pmd_update(mm, addr, ptep)              do { } while (0)
58 #define pmd_update_defer(mm, addr, ptep)        do { } while (0)
59
60 #define pgd_val(x)      xen_pgd_val(x)
61 #define __pgd(x)        xen_make_pgd(x)
62
63 #ifndef __PAGETABLE_PUD_FOLDED
64 #define pud_val(x)      xen_pud_val(x)
65 #define __pud(x)        xen_make_pud(x)
66 #endif
67
68 #ifndef __PAGETABLE_PMD_FOLDED
69 #define pmd_val(x)      xen_pmd_val(x)
70 #define __pmd(x)        xen_make_pmd(x)
71 #endif
72
73 #define pte_val(x)      xen_pte_val(x)
74 #define __pte(x)        xen_make_pte(x)
75
76 #define arch_end_context_switch(prev)   do {} while(0)
77
78 /*
79  * The following only work if pte_present() is true.
80  * Undefined behaviour if not..
81  */
82 static inline int pte_dirty(pte_t pte)
83 {
84         return pte_flags(pte) & _PAGE_DIRTY;
85 }
86
87 static inline int pte_young(pte_t pte)
88 {
89         return pte_flags(pte) & _PAGE_ACCESSED;
90 }
91
92 static inline int pmd_young(pmd_t pmd)
93 {
94         return pmd_flags(pmd) & _PAGE_ACCESSED;
95 }
96
97 static inline int pte_write(pte_t pte)
98 {
99         return pte_flags(pte) & _PAGE_RW;
100 }
101
102 static inline int pte_file(pte_t pte)
103 {
104         return pte_flags(pte) & _PAGE_FILE;
105 }
106
107 static inline int pte_huge(pte_t pte)
108 {
109         return pte_flags(pte) & _PAGE_PSE;
110 }
111
112 static inline int pte_global(pte_t pte)
113 {
114         return 0;
115 }
116
117 static inline int pte_exec(pte_t pte)
118 {
119         return !(pte_flags(pte) & _PAGE_NX);
120 }
121
122 static inline int pte_special(pte_t pte)
123 {
124         return pte_flags(pte) & _PAGE_SPECIAL;
125 }
126
127 #define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
128         __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
129 #define pte_pfn(_pte) ((_pte).pte_low & _PAGE_IOMAP ? max_mapnr : \
130                        (_pte).pte_low & _PAGE_PRESENT ?           \
131                        mfn_to_local_pfn(__pte_mfn(_pte)) :        \
132                        __pte_mfn(_pte))
133
134 #define pte_page(pte)   pfn_to_page(pte_pfn(pte))
135
136 static inline unsigned long pmd_pfn(pmd_t pmd)
137 {
138         return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
139 }
140
141 static inline int pmd_large(pmd_t pte)
142 {
143         return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
144                 (_PAGE_PSE | _PAGE_PRESENT);
145 }
146
147 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
148 static inline int pmd_trans_splitting(pmd_t pmd)
149 {
150         return pmd_val(pmd) & _PAGE_SPLITTING;
151 }
152
153 static inline int pmd_trans_huge(pmd_t pmd)
154 {
155         return pmd_val(pmd) & _PAGE_PSE;
156 }
157
158 static inline int has_transparent_hugepage(void)
159 {
160         return cpu_has_pse;
161 }
162 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
163
164 static inline pte_t pte_set_flags(pte_t pte, pteval_t set)
165 {
166         pteval_t v = __pte_val(pte);
167
168         return __pte_ma(v | set);
169 }
170
171 static inline pte_t pte_clear_flags(pte_t pte, pteval_t clear)
172 {
173         pteval_t v = __pte_val(pte);
174
175         return __pte_ma(v & ~clear);
176 }
177
178 static inline pte_t pte_mkclean(pte_t pte)
179 {
180         return pte_clear_flags(pte, _PAGE_DIRTY);
181 }
182
183 static inline pte_t pte_mkold(pte_t pte)
184 {
185         return pte_clear_flags(pte, _PAGE_ACCESSED);
186 }
187
188 static inline pte_t pte_wrprotect(pte_t pte)
189 {
190         return pte_clear_flags(pte, _PAGE_RW);
191 }
192
193 static inline pte_t pte_mkexec(pte_t pte)
194 {
195         return pte_clear_flags(pte, _PAGE_NX);
196 }
197
198 static inline pte_t pte_mkdirty(pte_t pte)
199 {
200         return pte_set_flags(pte, _PAGE_DIRTY);
201 }
202
203 static inline pte_t pte_mkyoung(pte_t pte)
204 {
205         return pte_set_flags(pte, _PAGE_ACCESSED);
206 }
207
208 static inline pte_t pte_mkwrite(pte_t pte)
209 {
210         return pte_set_flags(pte, _PAGE_RW);
211 }
212
213 static inline pte_t pte_mkhuge(pte_t pte)
214 {
215         return pte_set_flags(pte, _PAGE_PSE);
216 }
217
218 static inline pte_t pte_clrhuge(pte_t pte)
219 {
220         return pte_clear_flags(pte, _PAGE_PSE);
221 }
222
223 static inline pte_t pte_mkglobal(pte_t pte)
224 {
225         return pte;
226 }
227
228 static inline pte_t pte_clrglobal(pte_t pte)
229 {
230         return pte;
231 }
232
233 static inline pte_t pte_mkspecial(pte_t pte)
234 {
235         return pte_set_flags(pte, _PAGE_SPECIAL);
236 }
237
238 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
239 static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
240 {
241         pmdval_t v = native_pmd_val(pmd);
242
243         return __pmd(v | set);
244 }
245
246 static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)
247 {
248         pmdval_t v = native_pmd_val(pmd);
249
250         return __pmd(v & ~clear);
251 }
252
253 static inline pmd_t pmd_mkold(pmd_t pmd)
254 {
255         return pmd_clear_flags(pmd, _PAGE_ACCESSED);
256 }
257
258 static inline pmd_t pmd_wrprotect(pmd_t pmd)
259 {
260         return pmd_clear_flags(pmd, _PAGE_RW);
261 }
262
263 static inline pmd_t pmd_mkdirty(pmd_t pmd)
264 {
265         return pmd_set_flags(pmd, _PAGE_DIRTY);
266 }
267
268 static inline pmd_t pmd_mkhuge(pmd_t pmd)
269 {
270         return pmd_set_flags(pmd, _PAGE_PSE);
271 }
272
273 static inline pmd_t pmd_mkyoung(pmd_t pmd)
274 {
275         return pmd_set_flags(pmd, _PAGE_ACCESSED);
276 }
277
278 static inline pmd_t pmd_mkwrite(pmd_t pmd)
279 {
280         return pmd_set_flags(pmd, _PAGE_RW);
281 }
282
283 static inline pmd_t pmd_mknotpresent(pmd_t pmd)
284 {
285         return pmd_clear_flags(pmd, _PAGE_PRESENT);
286 }
287 #endif
288
289 /*
290  * Mask out unsupported bits in a present pgprot.  Non-present pgprots
291  * can use those bits for other purposes, so leave them be.
292  */
293 static inline pgprotval_t massage_pgprot(pgprot_t pgprot)
294 {
295         pgprotval_t protval = pgprot_val(pgprot);
296
297         if (protval & _PAGE_PRESENT)
298                 protval &= __supported_pte_mask;
299
300         return protval;
301 }
302
303 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
304 {
305         return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) |
306                      massage_pgprot(pgprot));
307 }
308
309 static inline pte_t pfn_pte_ma(phys_addr_t page_nr, pgprot_t pgprot)
310 {
311         return __pte_ma((page_nr << PAGE_SHIFT) | massage_pgprot(pgprot));
312 }
313
314 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
315 {
316         return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) |
317                      massage_pgprot(pgprot));
318 }
319
320 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
321 {
322         pteval_t val = pte_val(pte) & _PAGE_CHG_MASK;
323
324         val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK;
325
326         return __pte(val);
327 }
328
329 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
330 static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
331 {
332         pmdval_t val = pmd_val(pmd);
333
334         val &= _HPAGE_CHG_MASK;
335         val |= massage_pgprot(newprot) & ~_HPAGE_CHG_MASK;
336
337         return __pmd(val);
338 }
339 #endif
340
341 /* mprotect needs to preserve PAT bits when updating vm_page_prot */
342 #define pgprot_modify pgprot_modify
343 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
344 {
345         pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
346         pgprotval_t addbits = pgprot_val(newprot);
347         return __pgprot(preservebits | addbits);
348 }
349
350 #define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK)
351
352 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
353
354 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
355                                          unsigned long flags,
356                                          unsigned long new_flags)
357 {
358         /*
359          * PAT type is always WB for untracked ranges, so no need to check.
360          */
361         if (x86_platform.is_untracked_pat_range(paddr, paddr + size))
362                 return 1;
363
364         /*
365          * Certain new memtypes are not allowed with certain
366          * requested memtype:
367          * - request is uncached, return cannot be write-back
368          * - request is write-combine, return cannot be write-back
369          */
370         if ((flags == _PAGE_CACHE_UC_MINUS &&
371              new_flags == _PAGE_CACHE_WB) ||
372             (flags == _PAGE_CACHE_WC &&
373              new_flags == _PAGE_CACHE_WB)) {
374                 return 0;
375         }
376
377         return 1;
378 }
379
380 pmd_t *populate_extra_pmd(unsigned long vaddr);
381 pte_t *populate_extra_pte(unsigned long vaddr);
382 #endif  /* __ASSEMBLY__ */
383
384 #ifdef CONFIG_X86_32
385 # include "pgtable_32.h"
386 #else
387 # include "pgtable_64.h"
388 #endif
389
390 #ifndef __ASSEMBLY__
391 #include <linux/mm_types.h>
392
393 static inline int pte_none(pte_t pte)
394 {
395         return !pte.pte;
396 }
397
398 #define __HAVE_ARCH_PTE_SAME
399 static inline int pte_same(pte_t a, pte_t b)
400 {
401         return a.pte == b.pte;
402 }
403
404 static inline int pte_present(pte_t a)
405 {
406         return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
407 }
408
409 static inline int pte_hidden(pte_t pte)
410 {
411         return pte_flags(pte) & _PAGE_HIDDEN;
412 }
413
414 static inline int pmd_present(pmd_t pmd)
415 {
416 #if CONFIG_XEN_COMPAT <= 0x030002
417 /* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
418    can temporarily clear it. */
419         return __pmd_val(pmd) != 0;
420 #else
421         return pmd_flags(pmd) & _PAGE_PRESENT;
422 #endif
423 }
424
425 static inline int pmd_none(pmd_t pmd)
426 {
427         /* Only check low word on 32-bit platforms, since it might be
428            out of sync with upper half. */
429         return (unsigned long)__pmd_val(pmd) == 0;
430 }
431
432 static inline unsigned long pmd_page_vaddr(pmd_t pmd)
433 {
434         return (unsigned long)__va(pmd_val(pmd) & PTE_PFN_MASK);
435 }
436
437 /*
438  * Currently stuck as a macro due to indirect forward reference to
439  * linux/mmzone.h's __section_mem_map_addr() definition:
440  */
441 #define pmd_page(pmd)   pfn_to_page((pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT)
442
443 /*
444  * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
445  *
446  * this macro returns the index of the entry in the pmd page which would
447  * control the given virtual address
448  */
449 static inline unsigned long pmd_index(unsigned long address)
450 {
451         return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
452 }
453
454 /*
455  * Conversion functions: convert a page and protection to a page entry,
456  * and a page entry and page directory to the page they refer to.
457  *
458  * (Currently stuck as a macro because of indirect forward reference
459  * to linux/mm.h:page_to_nid())
460  */
461 #define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
462
463 /*
464  * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
465  *
466  * this function returns the index of the entry in the pte page which would
467  * control the given virtual address
468  */
469 static inline unsigned long pte_index(unsigned long address)
470 {
471         return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
472 }
473
474 static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
475 {
476         return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
477 }
478
479 static inline int pmd_bad(pmd_t pmd)
480 {
481 #if CONFIG_XEN_COMPAT <= 0x030002
482         return (pmd_flags(pmd) & ~_PAGE_USER & ~_PAGE_PRESENT)
483                != (_KERNPG_TABLE & ~_PAGE_PRESENT);
484 #else
485         return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
486 #endif
487 }
488
489 static inline unsigned long pages_to_mb(unsigned long npg)
490 {
491         return npg >> (20 - PAGE_SHIFT);
492 }
493
494 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
495         direct_remap_pfn_range(vma, vaddr, pfn, size, prot, DOMID_IO)
496
497 #if PAGETABLE_LEVELS > 2
498 static inline int pud_none(pud_t pud)
499 {
500         return __pud_val(pud) == 0;
501 }
502
503 static inline int pud_present(pud_t pud)
504 {
505         return pud_flags(pud) & _PAGE_PRESENT;
506 }
507
508 static inline unsigned long pud_page_vaddr(pud_t pud)
509 {
510         return (unsigned long)__va((unsigned long)pud_val(pud) & PTE_PFN_MASK);
511 }
512
513 /*
514  * Currently stuck as a macro due to indirect forward reference to
515  * linux/mmzone.h's __section_mem_map_addr() definition:
516  */
517 #define pud_page(pud)           pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
518
519 /* Find an entry in the second-level page table.. */
520 static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
521 {
522         return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
523 }
524
525 static inline int pud_large(pud_t pud)
526 {
527         return (__pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
528                 (_PAGE_PSE | _PAGE_PRESENT);
529 }
530
531 static inline int pud_bad(pud_t pud)
532 {
533         return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
534 }
535 #else
536 static inline int pud_large(pud_t pud)
537 {
538         return 0;
539 }
540 #endif  /* PAGETABLE_LEVELS > 2 */
541
542 #if PAGETABLE_LEVELS > 3
543 static inline int pgd_present(pgd_t pgd)
544 {
545         return pgd_flags(pgd) & _PAGE_PRESENT;
546 }
547
548 static inline unsigned long pgd_page_vaddr(pgd_t pgd)
549 {
550         return (unsigned long)__va((unsigned long)pgd_val(pgd) & PTE_PFN_MASK);
551 }
552
553 /*
554  * Currently stuck as a macro due to indirect forward reference to
555  * linux/mmzone.h's __section_mem_map_addr() definition:
556  */
557 #define pgd_page(pgd)           pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
558
559 /* to find an entry in a page-table-directory. */
560 static inline unsigned long pud_index(unsigned long address)
561 {
562         return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
563 }
564
565 static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
566 {
567         return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
568 }
569
570 static inline int pgd_bad(pgd_t pgd)
571 {
572         return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
573 }
574
575 static inline int pgd_none(pgd_t pgd)
576 {
577         return !__pgd_val(pgd);
578 }
579 #endif  /* PAGETABLE_LEVELS > 3 */
580
581 #endif  /* __ASSEMBLY__ */
582
583 /*
584  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
585  *
586  * this macro returns the index of the entry in the pgd page which would
587  * control the given virtual address
588  */
589 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
590
591 /*
592  * pgd_offset() returns a (pgd_t *)
593  * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
594  */
595 #define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
596 /*
597  * a shortcut which implies the use of the kernel's pgd, instead
598  * of a process's
599  */
600 #define pgd_offset_k(address) pgd_offset(&init_mm, (address))
601
602
603 #define KERNEL_PGD_BOUNDARY     pgd_index(PAGE_OFFSET)
604 #define KERNEL_PGD_PTRS         (PTRS_PER_PGD - KERNEL_PGD_BOUNDARY)
605
606 #ifndef __ASSEMBLY__
607
608 #define direct_gbpages 0
609
610 /* local pte updates need not use xchg for locking */
611 static inline pte_t xen_local_ptep_get_and_clear(pte_t *ptep, pte_t res)
612 {
613         xen_set_pte(ptep, __pte(0));
614         return res;
615 }
616
617 static inline pmd_t xen_local_pmdp_get_and_clear(pmd_t *pmdp)
618 {
619         pmd_t res = *pmdp;
620
621         xen_set_pmd(pmdp, __pmd(0));
622         return res;
623 }
624
625 static inline void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
626                                   pte_t *ptep , pte_t pte)
627 {
628         if ((mm != current->mm && mm != &init_mm) ||
629             HYPERVISOR_update_va_mapping(addr, pte, 0))
630                 xen_set_pte(ptep, pte);
631 }
632
633 static inline void xen_set_pmd_at(struct mm_struct *mm, unsigned long addr,
634                                   pmd_t *pmdp , pmd_t pmd)
635 {
636         xen_set_pmd(pmdp, pmd);
637 }
638
639 static inline void xen_pte_clear(struct mm_struct *mm, unsigned long addr,
640                                  pte_t *ptep)
641 {
642         if ((mm != current->mm && mm != &init_mm)
643             || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
644                 __xen_pte_clear(ptep);
645 }
646
647 #ifndef CONFIG_PARAVIRT
648 /*
649  * Rules for using pte_update - it must be called after any PTE update which
650  * has not been done using the set_pte / clear_pte interfaces.  It is used by
651  * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
652  * updates should either be sets, clears, or set_pte_atomic for P->P
653  * transitions, which means this hook should only be called for user PTEs.
654  * This hook implies a P->P protection or access change has taken place, which
655  * requires a subsequent TLB flush.  The notification can optionally be delayed
656  * until the TLB flush event by using the pte_update_defer form of the
657  * interface, but care must be taken to assure that the flush happens while
658  * still holding the same page table lock so that the shadow and primary pages
659  * do not become out of sync on SMP.
660  */
661 #define pte_update(mm, addr, ptep)              do { } while (0)
662 #define pte_update_defer(mm, addr, ptep)        do { } while (0)
663 #endif
664
665 /*
666  * We only update the dirty/accessed state if we set
667  * the dirty bit by hand in the kernel, since the hardware
668  * will do the accessed bit for us, and we don't want to
669  * race with other CPU's that might be updating the dirty
670  * bit at the same time.
671  */
672 struct vm_area_struct;
673
674 #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
675 extern int ptep_set_access_flags(struct vm_area_struct *vma,
676                                  unsigned long address, pte_t *ptep,
677                                  pte_t entry, int dirty);
678
679 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
680 extern int ptep_test_and_clear_young(struct vm_area_struct *vma,
681                                      unsigned long addr, pte_t *ptep);
682
683 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
684 extern int ptep_clear_flush_young(struct vm_area_struct *vma,
685                                   unsigned long address, pte_t *ptep);
686
687 #define __HAVE_ARCH_PTEP_CLEAR_FLUSH
688 #define ptep_clear_flush(vma, addr, ptep)                       \
689 ({                                                              \
690         pte_t *__ptep = (ptep);                                 \
691         pte_t __res = *__ptep;                                  \
692         if (!pte_none(__res) &&                                 \
693             ((vma)->vm_mm != current->mm ||                     \
694              HYPERVISOR_update_va_mapping(addr, __pte(0),       \
695                         uvm_multi(mm_cpumask((vma)->vm_mm)) |   \
696                                 UVMF_INVLPG))) {                \
697                 __xen_pte_clear(__ptep);                        \
698                 flush_tlb_page(vma, addr);                      \
699         }                                                       \
700         __res;                                                  \
701 })
702
703 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
704 static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
705                                        pte_t *ptep)
706 {
707         pte_t pte = *ptep;
708         if (!pte_none(pte)
709             && (mm != &init_mm
710                 || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))) {
711                 pte = xen_ptep_get_and_clear(ptep, pte);
712                 pte_update(mm, addr, ptep);
713         }
714         return pte;
715 }
716
717 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
718 #define ptep_get_and_clear_full(mm, addr, ptep, full)           \
719         ((full) ? ({                                            \
720                 pte_t *__ptep = (ptep);                         \
721                 pte_t __res = *__ptep;                          \
722                 if (!PagePinned(virt_to_page((mm)->pgd)))       \
723                         __xen_pte_clear(__ptep);                \
724                 else if (!pte_none(__res))                      \
725                         xen_l1_entry_update(__ptep, __pte(0));  \
726                 __res;                                          \
727          }) :                                                   \
728          ptep_get_and_clear(mm, addr, ptep))
729
730 pte_t xen_ptep_get_and_clear_full(struct vm_area_struct *, unsigned long, pte_t *, int);
731
732 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
733 static inline void ptep_set_wrprotect(struct mm_struct *mm,
734                                       unsigned long addr, pte_t *ptep)
735 {
736         pte_t pte = *ptep;
737         if (pte_write(pte))
738                 set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
739 }
740
741 #define flush_tlb_fix_spurious_fault(vma, address) do { } while (0)
742
743 #define mk_pmd(page, pgprot)   pfn_pmd(page_to_pfn(page), (pgprot))
744
745 #define  __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
746 extern int pmdp_set_access_flags(struct vm_area_struct *vma,
747                                  unsigned long address, pmd_t *pmdp,
748                                  pmd_t entry, int dirty);
749
750 #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
751 extern int pmdp_test_and_clear_young(struct vm_area_struct *vma,
752                                      unsigned long addr, pmd_t *pmdp);
753
754 #define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
755 extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
756                                   unsigned long address, pmd_t *pmdp);
757
758
759 #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
760 extern void pmdp_splitting_flush(struct vm_area_struct *vma,
761                                  unsigned long addr, pmd_t *pmdp);
762
763 #define __HAVE_ARCH_PMD_WRITE
764 static inline int pmd_write(pmd_t pmd)
765 {
766         return pmd_flags(pmd) & _PAGE_RW;
767 }
768
769 #define __HAVE_ARCH_PMDP_GET_AND_CLEAR
770 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
771 static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, unsigned long addr,
772                                        pmd_t *pmdp)
773 {
774         pmd_t pmd = xen_pmdp_get_and_clear(pmdp);
775         pmd_update(mm, addr, pmdp);
776         return pmd;
777 }
778 #endif
779
780 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
781 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
782 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
783                                       unsigned long addr, pmd_t *pmdp)
784 {
785         clear_bit(_PAGE_BIT_RW, (unsigned long *)pmdp);
786         pmd_update(mm, addr, pmdp);
787 }
788 #endif
789
790 /*
791  * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
792  *
793  *  dst - pointer to pgd range anwhere on a pgd page
794  *  src - ""
795  *  count - the number of pgds to copy.
796  *
797  * dst and src can be on the same page, but the range must not overlap,
798  * and must not cross a page boundary.
799  */
800 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
801 {
802        memcpy(dst, src, count * sizeof(pgd_t));
803 }
804
805 #define arbitrary_virt_to_mfn(va)                                       \
806 ({                                                                      \
807         unsigned int __lvl;                                             \
808         pte_t *__ptep = lookup_address((unsigned long)(va), &__lvl);    \
809         BUG_ON(!__ptep || __lvl != PG_LEVEL_4K || !pte_present(*__ptep));\
810         pte_mfn(*__ptep);                                               \
811 })
812
813 #define arbitrary_virt_to_machine(va)                                   \
814         (((maddr_t)arbitrary_virt_to_mfn(va) << PAGE_SHIFT)             \
815          | ((unsigned long)(va) & (PAGE_SIZE - 1)))
816
817 #ifdef CONFIG_HIGHPTE
818 #include <asm/io.h>
819 struct page *kmap_atomic_to_page(void *);
820 #define ptep_to_machine(ptep)                                           \
821 ({                                                                      \
822         pte_t *__ptep = (ptep);                                         \
823         page_to_phys(kmap_atomic_to_page(__ptep))                       \
824                 | ((unsigned long)__ptep & (PAGE_SIZE - 1));            \
825 })
826 #else
827 #define ptep_to_machine(ptep)   virt_to_machine(ptep)
828 #endif
829
830 #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
831 static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr,
832                                            pte_t *ptep)
833 {
834 #if CONFIG_XEN_COMPAT < 0x030300
835         if (unlikely(!xen_feature(XENFEAT_mmu_pt_update_preserve_ad)))
836                 return ptep_get_and_clear(mm, addr, ptep);
837 #endif
838         return *ptep;
839 }
840
841 static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
842                                            pte_t *ptep, pte_t pte)
843 {
844         mmu_update_t u;
845
846 #if CONFIG_XEN_COMPAT < 0x030300
847         if (unlikely(!xen_feature(XENFEAT_mmu_pt_update_preserve_ad))) {
848                 set_pte_at(mm, addr, ptep, pte);
849                 return;
850         }
851 #endif
852         u.ptr = ptep_to_machine(ptep) | MMU_PT_UPDATE_PRESERVE_AD;
853         u.val = __pte_val(pte);
854         if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF))
855                 BUG();
856 }
857
858 #include <asm-generic/pgtable.h>
859
860 #include <xen/features.h>
861 void make_page_readonly(void *va, unsigned int feature);
862 void make_page_writable(void *va, unsigned int feature);
863 void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
864 void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
865
866 struct vm_area_struct;
867
868 int direct_remap_pfn_range(struct vm_area_struct *vma,
869                            unsigned long address,
870                            phys_addr_t mfn,
871                            unsigned long size,
872                            pgprot_t prot,
873                            domid_t  domid);
874 int direct_kernel_remap_pfn_range(unsigned long address,
875                                   unsigned long mfn,
876                                   unsigned long size,
877                                   pgprot_t prot,
878                                   domid_t  domid);
879 int create_lookup_pte_addr(struct mm_struct *mm,
880                            unsigned long address,
881                            uint64_t *ptep);
882
883 #endif  /* __ASSEMBLY__ */
884
885 #endif /* _ASM_X86_PGTABLE_H */