aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/paravirt.h
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2007-05-02 19:27:13 +0200
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 19:27:13 +0200
commit3dc494e86d1c93afd4c66385f270899dbfae483d (patch)
tree6583b57492dc91ef7cc6c23a233f7d5bb95bb5f6 /include/asm-i386/paravirt.h
parent[PATCH] i386: PARAVIRT: use paravirt_nop to consistently mark no-op operations (diff)
downloadlinux-dev-3dc494e86d1c93afd4c66385f270899dbfae483d.tar.xz
linux-dev-3dc494e86d1c93afd4c66385f270899dbfae483d.zip
[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.h52
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 @@
#define __ASM_PARAVIRT_H
/* Various instructions on x86 need to be replaced for
* para-virtualization: those hooks are defined here. */
-#include <linux/linkage.h>
#include <linux/stringify.h>
#include <asm/page.h>
@@ -25,6 +24,8 @@
#define CLBR_ANY 0x7
#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
struct thread_struct;
struct Xgt_desc_struct;
struct tss_struct;
@@ -55,11 +56,6 @@ struct paravirt_ops
int (*set_wallclock)(unsigned long);
void (*time_init)(void);
- /* All the function pointers here are declared as "fastcall"
- so that we get a specific register-based calling
- convention. This makes it easier to implement inline
- assembler replacements. */
-
void (*cpuid)(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx);
@@ -139,16 +135,33 @@ struct paravirt_ops
void (*release_pd)(u32 pfn);
void (*set_pte)(pte_t *ptep, pte_t pteval);
- void (*set_pte_at)(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval);
+ void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval);
void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
- void (*pte_update)(struct mm_struct *mm, u32 addr, pte_t *ptep);
- void (*pte_update_defer)(struct mm_struct *mm, u32 addr, pte_t *ptep);
+ void (*pte_update)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+ void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+
+ pte_t (*ptep_get_and_clear)(pte_t *ptep);
+
#ifdef CONFIG_X86_PAE
void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
- void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
+ void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
void (*set_pud)(pud_t *pudp, pud_t pudval);
- void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+ void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
void (*pmd_clear)(pmd_t *pmdp);
+
+ unsigned long long (*pte_val)(pte_t);
+ unsigned long long (*pmd_val)(pmd_t);
+ unsigned long long (*pgd_val)(pgd_t);
+
+ pte_t (*make_pte)(unsigned long long pte);
+ pmd_t (*make_pmd)(unsigned long long pmd);
+ pgd_t (*make_pgd)(unsigned long long pgd);
+#else
+ unsigned long (*pte_val)(pte_t);
+ unsigned long (*pgd_val)(pgd_t);
+
+ pte_t (*make_pte)(unsigned long pte);
+ pgd_t (*make_pgd)(unsigned long pgd);
#endif
void (*set_lazy_mode)(int mode);
@@ -219,6 +232,8 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
#define read_cr4_safe(x) paravirt_ops.read_cr4_safe()
#define write_cr4(x) paravirt_ops.write_cr4(x)
+#define raw_ptep_get_and_clear(xp) (paravirt_ops.ptep_get_and_clear(xp))
+
static inline void raw_safe_halt(void)
{
paravirt_ops.safe_halt();
@@ -304,6 +319,17 @@ static inline void halt(void)
(paravirt_ops.write_idt_entry((dt), (entry), (low), (high)))
#define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask))
+#define __pte(x) paravirt_ops.make_pte(x)
+#define __pgd(x) paravirt_ops.make_pgd(x)
+
+#define pte_val(x) paravirt_ops.pte_val(x)
+#define pgd_val(x) paravirt_ops.pgd_val(x)
+
+#ifdef CONFIG_X86_PAE
+#define __pmd(x) paravirt_ops.make_pmd(x)
+#define pmd_val(x) paravirt_ops.pmd_val(x)
+#endif
+
/* The paravirtualized I/O functions */
static inline void slow_down_io(void) {
paravirt_ops.io_delay();
@@ -344,6 +370,7 @@ static inline void setup_secondary_clock(void)
}
#endif
+
#ifdef CONFIG_SMP
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
unsigned long start_esp)
@@ -371,7 +398,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
paravirt_ops.set_pte(ptep, pteval);
}
-static inline void set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval)
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pteval)
{
paravirt_ops.set_pte_at(mm, addr, ptep, pteval);
}