summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-05-27 00:31:06 +0200
committerThomas Gleixner <tglx@linutronix.de>2008-05-27 10:11:36 +0200
commita15af1c9ea2750a9ff01e51615c45950bad8221b (patch)
treeb4167c16c23365d016180b20248c724902e0c954
parentxen: don't worry about preempt during xen_irq_enable() (diff)
downloadlinux-a15af1c9ea2750a9ff01e51615c45950bad8221b.tar.xz
linux-a15af1c9ea2750a9ff01e51615c45950bad8221b.zip
x86/paravirt: add pte_flags to just get pte flags
Add pte_flags() to extract the flags from a pte. This is a special case of pte_val() which is only guaranteed to return the pte's flags correctly; the page number may be corrupted or missing. The intent is to allow paravirt implementations to return pte flags without having to do any translation of the page number (most notably, Xen). Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/kernel/paravirt.c1
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--drivers/lguest/lg.h1
-rw-r--r--include/asm-x86/page.h1
-rw-r--r--include/asm-x86/paravirt.h15
-rw-r--r--include/asm-x86/pgtable.h16
6 files changed, 26 insertions, 9 deletions
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 74f0c5ea2a03..c98d54688180 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -403,6 +403,7 @@ struct pv_mmu_ops pv_mmu_ops = {
#endif /* PAGETABLE_LEVELS >= 3 */
.pte_val = native_pte_val,
+ .pte_flags = native_pte_val,
.pgd_val = native_pgd_val,
.make_pte = native_make_pte,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 4a372b71239d..1b4b5fa498b3 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1101,6 +1101,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
.set_pmd = xen_set_pmd,
.pte_val = xen_pte_val,
+ .pte_flags = native_pte_val,
.pgd_val = xen_pgd_val,
.make_pte = xen_make_pte,
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 005bd045d2eb..5faefeaf6790 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -136,7 +136,6 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
* first step in the migration to the kernel types. pte_pfn is already defined
* in the kernel. */
#define pgd_flags(x) (pgd_val(x) & ~PAGE_MASK)
-#define pte_flags(x) (pte_val(x) & ~PAGE_MASK)
#define pgd_pfn(x) (pgd_val(x) >> PAGE_SHIFT)
/* interrupts_and_traps.c: */
diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h
index dc936dddf161..a1e2b9470f25 100644
--- a/include/asm-x86/page.h
+++ b/include/asm-x86/page.h
@@ -160,6 +160,7 @@ static inline pteval_t native_pte_val(pte_t pte)
#endif
#define pte_val(x) native_pte_val(x)
+#define pte_flags(x) native_pte_val(x)
#define __pte(x) native_make_pte(x)
#endif /* CONFIG_PARAVIRT */
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 0f13b945e240..5ea37a48eecb 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -239,6 +239,7 @@ struct pv_mmu_ops {
unsigned long addr, pte_t *ptep);
pteval_t (*pte_val)(pte_t);
+ pteval_t (*pte_flags)(pte_t);
pte_t (*make_pte)(pteval_t pte);
pgdval_t (*pgd_val)(pgd_t);
@@ -996,6 +997,20 @@ static inline pteval_t pte_val(pte_t pte)
return ret;
}
+static inline pteval_t pte_flags(pte_t pte)
+{
+ pteval_t ret;
+
+ if (sizeof(pteval_t) > sizeof(long))
+ ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_flags,
+ pte.pte, (u64)pte.pte >> 32);
+ else
+ ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_flags,
+ pte.pte);
+
+ return ret;
+}
+
static inline pgd_t __pgd(pgdval_t val)
{
pgdval_t ret;
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 97c271b2910b..47a852cb8c92 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -164,37 +164,37 @@ extern struct list_head pgd_list;
*/
static inline int pte_dirty(pte_t pte)
{
- return pte_val(pte) & _PAGE_DIRTY;
+ return pte_flags(pte) & _PAGE_DIRTY;
}
static inline int pte_young(pte_t pte)
{
- return pte_val(pte) & _PAGE_ACCESSED;
+ return pte_flags(pte) & _PAGE_ACCESSED;
}
static inline int pte_write(pte_t pte)
{
- return pte_val(pte) & _PAGE_RW;
+ return pte_flags(pte) & _PAGE_RW;
}
static inline int pte_file(pte_t pte)
{
- return pte_val(pte) & _PAGE_FILE;
+ return pte_flags(pte) & _PAGE_FILE;
}
static inline int pte_huge(pte_t pte)
{
- return pte_val(pte) & _PAGE_PSE;
+ return pte_flags(pte) & _PAGE_PSE;
}
static inline int pte_global(pte_t pte)
{
- return pte_val(pte) & _PAGE_GLOBAL;
+ return pte_flags(pte) & _PAGE_GLOBAL;
}
static inline int pte_exec(pte_t pte)
{
- return !(pte_val(pte) & _PAGE_NX);
+ return !(pte_flags(pte) & _PAGE_NX);
}
static inline int pte_special(pte_t pte)
@@ -305,7 +305,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
return __pgprot(preservebits | addbits);
}
-#define pte_pgprot(x) __pgprot(pte_val(x) & ~PTE_MASK)
+#define pte_pgprot(x) __pgprot(pte_flags(x) & ~PTE_MASK)
#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)