blob: 6b87bc6d50189263691c10819618bc97deb8c086 [file] [log] [blame]
H. Peter Anvin1965aae2008-10-22 22:26:29 -07001#ifndef _ASM_X86_PGTABLE_64_H
2#define _ASM_X86_PGTABLE_64_H
Linus Torvalds1da177e2005-04-16 15:20:36 -07003
Randy Dunlap6df95fd2007-05-08 00:31:11 -07004#include <linux/const.h>
Jeremy Fitzhardingefb355142009-02-08 18:50:52 -08005#include <asm/pgtable_64_types.h>
6
Vivek Goyal9d291e72007-05-02 19:27:06 +02007#ifndef __ASSEMBLY__
8
Linus Torvalds1da177e2005-04-16 15:20:36 -07009/*
10 * This file contains the functions and defines necessary to modify and use
11 * the x86-64 page table tree.
12 */
13#include <asm/processor.h>
Jiri Slaby1977f032007-10-18 23:40:25 -070014#include <linux/bitops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/threads.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17extern pud_t level3_kernel_pgt[512];
Linus Torvalds1da177e2005-04-16 15:20:36 -070018extern pud_t level3_ident_pgt[512];
19extern pmd_t level2_kernel_pgt[512];
Jeremy Fitzhardinge084a2a42008-07-08 15:06:50 -070020extern pmd_t level2_fixmap_pgt[512];
21extern pmd_t level2_ident_pgt[512];
Linus Torvalds1da177e2005-04-16 15:20:36 -070022extern pgd_t init_level4_pgt[];
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
Linus Torvaldse3ebadd2007-05-07 08:44:24 -070024#define swapper_pg_dir init_level4_pgt
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
Linus Torvalds1da177e2005-04-16 15:20:36 -070026extern void paging_init(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Vivek Goyal9d291e72007-05-02 19:27:06 +020028#endif /* !__ASSEMBLY__ */
29
Vivek Goyal9d291e72007-05-02 19:27:06 +020030#ifndef __ASSEMBLY__
31
Joe Perches7f944012008-03-23 01:03:11 -070032#define pte_ERROR(e) \
33 printk("%s:%d: bad pte %p(%016lx).\n", \
34 __FILE__, __LINE__, &(e), pte_val(e))
35#define pmd_ERROR(e) \
36 printk("%s:%d: bad pmd %p(%016lx).\n", \
37 __FILE__, __LINE__, &(e), pmd_val(e))
38#define pud_ERROR(e) \
39 printk("%s:%d: bad pud %p(%016lx).\n", \
40 __FILE__, __LINE__, &(e), pud_val(e))
41#define pgd_ERROR(e) \
42 printk("%s:%d: bad pgd %p(%016lx).\n", \
43 __FILE__, __LINE__, &(e), pgd_val(e))
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
Tim Schmielau8c65b4a2005-11-07 00:59:43 -080045struct mm_struct;
46
Eduardo Habkost0814e0b2008-06-25 00:19:22 -040047void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
48
49
Jeremy Fitzhardinge48916452008-01-30 13:32:58 +010050static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
51 pte_t *ptep)
Zachary Amsden61e06032005-09-03 15:55:06 -070052{
Jeremy Fitzhardinge48916452008-01-30 13:32:58 +010053 *ptep = native_make_pte(0);
54}
55
56static inline void native_set_pte(pte_t *ptep, pte_t pte)
57{
58 *ptep = pte;
59}
60
Ingo Molnarb65e6392008-01-30 13:34:01 +010061static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
62{
63 native_set_pte(ptep, pte);
64}
65
Jeremy Fitzhardinge48916452008-01-30 13:32:58 +010066static inline pte_t native_ptep_get_and_clear(pte_t *xp)
67{
68#ifdef CONFIG_SMP
69 return native_make_pte(xchg(&xp->pte, 0));
70#else
Joe Perches7f944012008-03-23 01:03:11 -070071 /* native_local_ptep_get_and_clear,
72 but duplicated because of cyclic dependency */
Jeremy Fitzhardinge48916452008-01-30 13:32:58 +010073 pte_t ret = *xp;
74 native_pte_clear(NULL, 0, xp);
75 return ret;
76#endif
77}
78
79static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
80{
81 *pmdp = pmd;
82}
83
84static inline void native_pmd_clear(pmd_t *pmd)
85{
86 native_set_pmd(pmd, native_make_pmd(0));
87}
88
89static inline void native_set_pud(pud_t *pudp, pud_t pud)
90{
91 *pudp = pud;
92}
93
94static inline void native_pud_clear(pud_t *pud)
95{
96 native_set_pud(pud, native_make_pud(0));
97}
98
99static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
100{
101 *pgdp = pgd;
102}
103
Joe Perches7f944012008-03-23 01:03:11 -0700104static inline void native_pgd_clear(pgd_t *pgd)
Jeremy Fitzhardinge48916452008-01-30 13:32:58 +0100105{
106 native_set_pgd(pgd, native_make_pgd(0));
Zachary Amsden61e06032005-09-03 15:55:06 -0700107}
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 * Conversion functions: convert a page and protection to a page entry,
111 * and a page entry and page directory to the page they refer to.
112 */
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114/*
115 * Level 4 access.
116 */
H. Peter Anvine00fc5422008-02-19 16:18:32 +0100117static inline int pgd_large(pgd_t pgd) { return 0; }
Eduardo Habkoste7a9b0b2008-06-25 00:19:05 -0400118#define mk_kernel_pgd(address) __pgd((address) | _KERNPG_TABLE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
120/* PUD - Level3 access */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122/* PMD - Level 2 access */
Joe Perches7f944012008-03-23 01:03:11 -0700123#define pte_to_pgoff(pte) ((pte_val((pte)) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
124#define pgoff_to_pte(off) ((pte_t) { .pte = ((off) << PAGE_SHIFT) | \
125 _PAGE_FILE })
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126#define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT
127
128/* PTE - Level 1 access. */
129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130/* x86-64 always has all page tables mapped. */
Joe Perches7f944012008-03-23 01:03:11 -0700131#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address))
132#define pte_offset_map_nested(dir, address) pte_offset_kernel((dir), (address))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133#define pte_unmap(pte) /* NOP */
Joe Perches7f944012008-03-23 01:03:11 -0700134#define pte_unmap_nested(pte) /* NOP */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Joe Perches7f944012008-03-23 01:03:11 -0700136#define update_mmu_cache(vma, address, pte) do { } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
Ingo Molnar00d1c5e2008-04-17 17:40:45 +0200138extern int direct_gbpages;
139
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140/* Encode and de-code a swap entry */
Jan Beulich17963162008-12-16 11:35:24 +0000141#if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
142#define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1)
143#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1)
144#else
145#define SWP_TYPE_BITS (_PAGE_BIT_PROTNONE - _PAGE_BIT_PRESENT - 1)
146#define SWP_OFFSET_SHIFT (_PAGE_BIT_FILE + 1)
147#endif
148
149#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
150
151#define __swp_type(x) (((x).val >> (_PAGE_BIT_PRESENT + 1)) \
152 & ((1U << SWP_TYPE_BITS) - 1))
153#define __swp_offset(x) ((x).val >> SWP_OFFSET_SHIFT)
154#define __swp_entry(type, offset) ((swp_entry_t) { \
155 ((type) << (_PAGE_BIT_PRESENT + 1)) \
156 | ((offset) << SWP_OFFSET_SHIFT) })
Joe Perches7f944012008-03-23 01:03:11 -0700157#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
Jeremy Fitzhardingec8e53932008-01-30 13:32:57 +0100158#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
Joe Perches7f944012008-03-23 01:03:11 -0700160extern int kern_addr_valid(unsigned long addr);
Thomas Gleixner31eedd82008-02-15 17:29:12 +0100161extern void cleanup_highmap(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163#define HAVE_ARCH_UNMAPPED_AREA
Jiri Kosinacc503c12008-01-30 13:31:07 +0100164#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166#define pgtable_cache_init() do { } while (0)
Linus Torvaldsda8f1532007-09-21 12:09:41 -0700167#define check_pgt_cache() do { } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
169#define PAGE_AGP PAGE_KERNEL_NOCACHE
170#define HAVE_PAGE_AGP 1
171
172/* fs/proc/kcore.c */
173#define kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK)
Joe Perches7f944012008-03-23 01:03:11 -0700174#define kc_offset_to_vaddr(o) \
175 (((o) & (1UL << (__VIRTUAL_MASK_SHIFT - 1))) \
176 ? ((o) | ~__VIRTUAL_MASK) \
177 : (o))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179#define __HAVE_ARCH_PTE_SAME
Vivek Goyal9d291e72007-05-02 19:27:06 +0200180#endif /* !__ASSEMBLY__ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
H. Peter Anvin1965aae2008-10-22 22:26:29 -0700182#endif /* _ASM_X86_PGTABLE_64_H */