lkml.org 
[lkml]   [2006]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 13/14] remap_file_pages protection support: uml, i386, x64 bits
From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>, Ingo Molnar <mingo@elte.hu>

Various boilerplate stuff.

Update pte encoding macros for UML, i386 and x86-64.

*) remap_file_pages protection support: improvement for UML bits

Recover one bit by additionally using _PAGE_NEWPROT. Since I wasn't sure this
would work, I've split this out, but it has worked well. We rely on the fact
that pte_newprot always checks first if the PTE is marked present. This is
joined because it worked well during the unit testing I performed, beyond
making sense.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Index: linux-2.6.git/include/asm-i386/pgtable-2level.h
===================================================================
--- linux-2.6.git.orig/include/asm-i386/pgtable-2level.h
+++ linux-2.6.git/include/asm-i386/pgtable-2level.h
@@ -43,16 +43,21 @@ static inline int pte_exec_kernel(pte_t
}

/*
- * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
+ * Bits 0, 1, 6 and 7 are taken, split up the 28 bits of offset
* into this range:
*/
-#define PTE_FILE_MAX_BITS 29
+#define PTE_FILE_MAX_BITS 28

#define pte_to_pgoff(pte) \
- ((((pte).pte_low >> 1) & 0x1f ) + (((pte).pte_low >> 8) << 5 ))
-
-#define pgoff_to_pte(off) \
- ((pte_t) { (((off) & 0x1f) << 1) + (((off) >> 5) << 8) + _PAGE_FILE })
+ ((((pte).pte_low >> 2) & 0xf ) + (((pte).pte_low >> 8) << 4 ))
+#define pte_to_pgprot(pte) \
+ __pgprot(((pte).pte_low & (_PAGE_RW | _PAGE_PROTNONE)) \
+ | (((pte).pte_low & _PAGE_PROTNONE) ? 0 : \
+ (_PAGE_USER | _PAGE_PRESENT)) | _PAGE_ACCESSED)
+
+#define pgoff_prot_to_pte(off, prot) \
+ ((pte_t) { (((off) & 0xf) << 2) + (((off) >> 4) << 8) + \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) + _PAGE_FILE })

/* Encode and de-code a swap entry */
#define __swp_type(x) (((x).val >> 1) & 0x1f)
Index: linux-2.6.git/include/asm-i386/pgtable-3level.h
===================================================================
--- linux-2.6.git.orig/include/asm-i386/pgtable-3level.h
+++ linux-2.6.git/include/asm-i386/pgtable-3level.h
@@ -140,7 +140,16 @@ static inline pmd_t pfn_pmd(unsigned lon
* put the 32 bits of offset into the high part.
*/
#define pte_to_pgoff(pte) ((pte).pte_high)
-#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+
+#define pte_to_pgprot(pte) \
+ __pgprot(((pte).pte_low & (_PAGE_RW | _PAGE_PROTNONE)) \
+ | (((pte).pte_low & _PAGE_PROTNONE) ? 0 : \
+ (_PAGE_USER | _PAGE_PRESENT)) | _PAGE_ACCESSED)
+
+#define pgoff_prot_to_pte(off, prot) \
+ ((pte_t) { _PAGE_FILE + \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) , (off) })
+
#define PTE_FILE_MAX_BITS 32

/* Encode and de-code a swap entry */
Index: linux-2.6.git/include/asm-um/pgtable-2level.h
===================================================================
--- linux-2.6.git.orig/include/asm-um/pgtable-2level.h
+++ linux-2.6.git/include/asm-um/pgtable-2level.h
@@ -45,12 +45,19 @@ static inline void pgd_mkuptodate(pgd_t
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))

/*
- * Bits 0 through 3 are taken
+ * Bits 0, 1, 3 to 5 are taken, split up the 27 bits of offset
+ * into this range:
*/
-#define PTE_FILE_MAX_BITS 28
+#define PTE_FILE_MAX_BITS 27

-#define pte_to_pgoff(pte) (pte_val(pte) >> 4)
+#define pte_to_pgoff(pte) (((pte_val(pte) >> 6) << 1) | ((pte_val(pte) >> 2) & 0x1))
+#define pte_to_pgprot(pte) \
+ __pgprot((pte_val(pte) & (_PAGE_RW | _PAGE_PROTNONE)) \
+ | ((pte_val(pte) & _PAGE_PROTNONE) ? 0 : \
+ (_PAGE_USER | _PAGE_PRESENT)) | _PAGE_ACCESSED)

-#define pgoff_to_pte(off) ((pte_t) { ((off) << 4) + _PAGE_FILE })
+#define pgoff_prot_to_pte(off, prot) \
+ __pte((((off) >> 1) << 6) + (((off) & 0x1) << 2) + \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) + _PAGE_FILE)

#endif
Index: linux-2.6.git/include/asm-um/pgtable-3level.h
===================================================================
--- linux-2.6.git.orig/include/asm-um/pgtable-3level.h
+++ linux-2.6.git/include/asm-um/pgtable-3level.h
@@ -101,25 +101,35 @@ static inline pmd_t pfn_pmd(pfn_t page_n
}

/*
- * Bits 0 through 3 are taken in the low part of the pte,
+ * Bits 0 through 5 are taken in the low part of the pte,
* put the 32 bits of offset into the high part.
*/
#define PTE_FILE_MAX_BITS 32

+
#ifdef CONFIG_64BIT

#define pte_to_pgoff(p) ((p).pte >> 32)
-
-#define pgoff_to_pte(off) ((pte_t) { ((off) << 32) | _PAGE_FILE })
+#define pgoff_prot_to_pte(off, prot) ((pte_t) { ((off) << 32) | _PAGE_FILE | \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) })
+#define __pte_flags(pte) pte_val(pte)

#else

#define pte_to_pgoff(pte) ((pte).pte_high)
-
-#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+#define pgoff_prot_to_pte(off, prot) ((pte_t) { \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) | _PAGE_FILE, \
+ (off) })
+/* Don't use pte_val below, useless to join the two halves */
+#define __pte_flags(pte) ((pte).pte_low)

#endif

+#define pte_to_pgprot(pte) \
+ __pgprot((__pte_flags(pte) & (_PAGE_RW | _PAGE_PROTNONE)) \
+ | ((__pte_flags(pte) & _PAGE_PROTNONE) ? 0 : \
+ (_PAGE_USER | _PAGE_PRESENT)) | _PAGE_ACCESSED)
+
#endif

/*
Index: linux-2.6.git/include/asm-x86_64/pgtable.h
===================================================================
--- linux-2.6.git.orig/include/asm-x86_64/pgtable.h
+++ linux-2.6.git/include/asm-x86_64/pgtable.h
@@ -360,9 +360,19 @@ static inline pud_t *__pud_offset_k(pud_
#define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)

#define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
-#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
#define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT

+#define pte_to_pgprot(pte) \
+ __pgprot((pte_val(pte) & (_PAGE_RW | _PAGE_PROTNONE)) \
+ | ((pte_val(pte) & _PAGE_PROTNONE) ? 0 : \
+ (_PAGE_USER | _PAGE_PRESENT)) | _PAGE_ACCESSED)
+
+#define pgoff_prot_to_pte(off, prot) \
+ ((pte_t) { _PAGE_FILE + \
+ (pgprot_val(prot) & (_PAGE_RW | _PAGE_PROTNONE)) + \
+ ((off) << PAGE_SHIFT) })
+
+
/* PTE - Level 1 access. */

/* page, protection -> pte */
@@ -454,6 +464,7 @@ extern int kern_addr_valid(unsigned long
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTE_SAME
+#define __HAVE_ARCH_PTE_TO_PGPROT
#include <asm-generic/pgtable.h>

#endif /* _X86_64_PGTABLE_H */
Index: linux-2.6.git/include/asm-i386/pgtable.h
===================================================================
--- linux-2.6.git.orig/include/asm-i386/pgtable.h
+++ linux-2.6.git/include/asm-i386/pgtable.h
@@ -452,6 +452,7 @@ extern void noexec_setup(const char *str
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTE_SAME
+#define __HAVE_ARCH_PTE_TO_PGPROT
#include <asm-generic/pgtable.h>

#endif /* _I386_PGTABLE_H */
Index: linux-2.6.git/include/asm-um/pgtable.h
===================================================================
--- linux-2.6.git.orig/include/asm-um/pgtable.h
+++ linux-2.6.git/include/asm-um/pgtable.h
@@ -410,6 +410,7 @@ static inline pte_t pte_modify(pte_t pte

#define kern_addr_valid(addr) (1)

+#define __HAVE_ARCH_PTE_TO_PGPROT
#include <asm-generic/pgtable.h>

#include <asm-generic/pgtable-nopud.h>
--
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894)
http://www.user-mode-linux.org/~blaisorblade
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-04-30 19:36    [W:1.339 / U:0.528 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site