diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-05-02 13:27:13 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:13 -0400 |
commit | 3dc494e86d1c93afd4c66385f270899dbfae483d (patch) | |
tree | 6583b57492dc91ef7cc6c23a233f7d5bb95bb5f6 /include/asm-i386/paravirt.h | |
parent | 45876233605c268e929a7875081e129debe34bdc (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 'include/asm-i386/paravirt.h')
-rw-r--r-- | include/asm-i386/paravirt.h | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index f0bdaea6235d..0aacb13bb929 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define __ASM_PARAVIRT_H | 2 | #define __ASM_PARAVIRT_H |
3 | /* Various instructions on x86 need to be replaced for | 3 | /* Various instructions on x86 need to be replaced for |
4 | * para-virtualization: those hooks are defined here. */ | 4 | * para-virtualization: those hooks are defined here. */ |
5 | #include <linux/linkage.h> | ||
6 | #include <linux/stringify.h> | 5 | #include <linux/stringify.h> |
7 | #include <asm/page.h> | 6 | #include <asm/page.h> |
8 | 7 | ||
@@ -25,6 +24,8 @@ | |||
25 | #define CLBR_ANY 0x7 | 24 | #define CLBR_ANY 0x7 |
26 | 25 | ||
27 | #ifndef __ASSEMBLY__ | 26 | #ifndef __ASSEMBLY__ |
27 | #include <linux/types.h> | ||
28 | |||
28 | struct thread_struct; | 29 | struct thread_struct; |
29 | struct Xgt_desc_struct; | 30 | struct Xgt_desc_struct; |
30 | struct tss_struct; | 31 | struct tss_struct; |
@@ -55,11 +56,6 @@ struct paravirt_ops | |||
55 | int (*set_wallclock)(unsigned long); | 56 | int (*set_wallclock)(unsigned long); |
56 | void (*time_init)(void); | 57 | void (*time_init)(void); |
57 | 58 | ||
58 | /* All the function pointers here are declared as "fastcall" | ||
59 | so that we get a specific register-based calling | ||
60 | convention. This makes it easier to implement inline | ||
61 | assembler replacements. */ | ||
62 | |||
63 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, | 59 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, |
64 | unsigned int *ecx, unsigned int *edx); | 60 | unsigned int *ecx, unsigned int *edx); |
65 | 61 | ||
@@ -139,16 +135,33 @@ struct paravirt_ops | |||
139 | void (*release_pd)(u32 pfn); | 135 | void (*release_pd)(u32 pfn); |
140 | 136 | ||
141 | void (*set_pte)(pte_t *ptep, pte_t pteval); | 137 | void (*set_pte)(pte_t *ptep, pte_t pteval); |
142 | void (*set_pte_at)(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval); | 138 | void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); |
143 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); | 139 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); |
144 | void (*pte_update)(struct mm_struct *mm, u32 addr, pte_t *ptep); | 140 | void (*pte_update)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
145 | void (*pte_update_defer)(struct mm_struct *mm, u32 addr, pte_t *ptep); | 141 | void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
142 | |||
143 | pte_t (*ptep_get_and_clear)(pte_t *ptep); | ||
144 | |||
146 | #ifdef CONFIG_X86_PAE | 145 | #ifdef CONFIG_X86_PAE |
147 | void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); | 146 | void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); |
148 | void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); | 147 | void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); |
149 | void (*set_pud)(pud_t *pudp, pud_t pudval); | 148 | void (*set_pud)(pud_t *pudp, pud_t pudval); |
150 | void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); | 149 | void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
151 | void (*pmd_clear)(pmd_t *pmdp); | 150 | void (*pmd_clear)(pmd_t *pmdp); |
151 | |||
152 | unsigned long long (*pte_val)(pte_t); | ||
153 | unsigned long long (*pmd_val)(pmd_t); | ||
154 | unsigned long long (*pgd_val)(pgd_t); | ||
155 | |||
156 | pte_t (*make_pte)(unsigned long long pte); | ||
157 | pmd_t (*make_pmd)(unsigned long long pmd); | ||
158 | pgd_t (*make_pgd)(unsigned long long pgd); | ||
159 | #else | ||
160 | unsigned long (*pte_val)(pte_t); | ||
161 | unsigned long (*pgd_val)(pgd_t); | ||
162 | |||
163 | pte_t (*make_pte)(unsigned long pte); | ||
164 | pgd_t (*make_pgd)(unsigned long pgd); | ||
152 | #endif | 165 | #endif |
153 | 166 | ||
154 | void (*set_lazy_mode)(int mode); | 167 | void (*set_lazy_mode)(int mode); |
@@ -219,6 +232,8 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx, | |||
219 | #define read_cr4_safe(x) paravirt_ops.read_cr4_safe() | 232 | #define read_cr4_safe(x) paravirt_ops.read_cr4_safe() |
220 | #define write_cr4(x) paravirt_ops.write_cr4(x) | 233 | #define write_cr4(x) paravirt_ops.write_cr4(x) |
221 | 234 | ||
235 | #define raw_ptep_get_and_clear(xp) (paravirt_ops.ptep_get_and_clear(xp)) | ||
236 | |||
222 | static inline void raw_safe_halt(void) | 237 | static inline void raw_safe_halt(void) |
223 | { | 238 | { |
224 | paravirt_ops.safe_halt(); | 239 | paravirt_ops.safe_halt(); |
@@ -304,6 +319,17 @@ static inline void halt(void) | |||
304 | (paravirt_ops.write_idt_entry((dt), (entry), (low), (high))) | 319 | (paravirt_ops.write_idt_entry((dt), (entry), (low), (high))) |
305 | #define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask)) | 320 | #define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask)) |
306 | 321 | ||
322 | #define __pte(x) paravirt_ops.make_pte(x) | ||
323 | #define __pgd(x) paravirt_ops.make_pgd(x) | ||
324 | |||
325 | #define pte_val(x) paravirt_ops.pte_val(x) | ||
326 | #define pgd_val(x) paravirt_ops.pgd_val(x) | ||
327 | |||
328 | #ifdef CONFIG_X86_PAE | ||
329 | #define __pmd(x) paravirt_ops.make_pmd(x) | ||
330 | #define pmd_val(x) paravirt_ops.pmd_val(x) | ||
331 | #endif | ||
332 | |||
307 | /* The paravirtualized I/O functions */ | 333 | /* The paravirtualized I/O functions */ |
308 | static inline void slow_down_io(void) { | 334 | static inline void slow_down_io(void) { |
309 | paravirt_ops.io_delay(); | 335 | paravirt_ops.io_delay(); |
@@ -344,6 +370,7 @@ static inline void setup_secondary_clock(void) | |||
344 | } | 370 | } |
345 | #endif | 371 | #endif |
346 | 372 | ||
373 | |||
347 | #ifdef CONFIG_SMP | 374 | #ifdef CONFIG_SMP |
348 | static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, | 375 | static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, |
349 | unsigned long start_esp) | 376 | unsigned long start_esp) |
@@ -371,7 +398,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
371 | paravirt_ops.set_pte(ptep, pteval); | 398 | paravirt_ops.set_pte(ptep, pteval); |
372 | } | 399 | } |
373 | 400 | ||
374 | static inline void set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) | 401 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
402 | pte_t *ptep, pte_t pteval) | ||
375 | { | 403 | { |
376 | paravirt_ops.set_pte_at(mm, addr, ptep, pteval); | 404 | paravirt_ops.set_pte_at(mm, addr, ptep, pteval); |
377 | } | 405 | } |