# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206012925 0
# Node ID de57c3f218fb5c23bb767d2192e9beb1b4d09681
# Parent 9a5af85d3238ba03f3ced1295019ef65ba5489a3
xen, x86: Track foreign and I/O mappings with a new pte flag, and do
not subject such ptes to conversions to/from pseudophysical addresses.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
arch/i386/mm/ioremap-xen.c | 2 +-
include/asm-i386/mach-xen/asm/page.h | 21 +++++++++++++--------
include/asm-i386/mach-xen/asm/pgtable-2level.h | 6 ++++--
include/asm-i386/mach-xen/asm/pgtable-3level.h | 6 ++++--
include/asm-i386/mach-xen/asm/pgtable.h | 5 ++++-
include/asm-x86_64/mach-xen/asm/page.h | 11 +++++++----
include/asm-x86_64/mach-xen/asm/pgtable.h | 11 ++++++++---
7 files changed, 41 insertions(+), 21 deletions(-)
diff -r 9a5af85d3238 -r de57c3f218fb arch/i386/mm/ioremap-xen.c
--- a/arch/i386/mm/ioremap-xen.c Wed Mar 19 10:23:31 2008 +0000
+++ b/arch/i386/mm/ioremap-xen.c Thu Mar 20 11:35:25 2008 +0000
@@ -76,7 +76,7 @@ static int __direct_remap_pfn_range(stru
* Fill in the machine address: PTE ptr is done later by
* apply_to_page_range().
*/
- v->val = __pte_val(pfn_pte_ma(mfn, prot));
+ v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
mfn++;
address += PAGE_SIZE;
diff -r 9a5af85d3238 -r de57c3f218fb include/asm-i386/mach-xen/asm/page.h
--- a/include/asm-i386/mach-xen/asm/page.h Wed Mar 19 10:23:31 2008 +0000
+++ b/include/asm-i386/mach-xen/asm/page.h Thu Mar 20 11:35:25 2008 +0000
@@ -27,6 +27,7 @@
* below. The preprocessor will warn if the two definitions aren't identical.
*/
#define _PAGE_PRESENT 0x001
+#define _PAGE_IO 0x200
#ifndef __ASSEMBLY__
@@ -74,8 +75,9 @@ typedef struct { unsigned long long pgpr
typedef struct { unsigned long long pgprot; } pgprot_t;
#define pgprot_val(x) ((x).pgprot)
#include <asm/maddr.h>
-#define __pte(x) ({ unsigned long long _x = (x); \
- if (_x & _PAGE_PRESENT) _x = pte_phys_to_machine(_x); \
+#define __pte(x) ({ unsigned long long _x = (x); \
+ if ((_x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT) \
+ _x = pte_phys_to_machine(_x); \
((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
#define __pgd(x) ({ unsigned long long _x = (x); \
(pgd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
@@ -88,7 +90,8 @@ static inline unsigned long long pte_val
static inline unsigned long long pte_val(pte_t x)
{
unsigned long long ret = __pte_val(x);
- if (x.pte_low & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+ if ((x.pte_low & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
+ ret = pte_machine_to_phys(ret);
return ret;
}
#define __pmd_val(x) ((x).pmd)
@@ -119,11 +122,13 @@ typedef struct { unsigned long pgprot; }
#include <asm/maddr.h>
#define boot_pte_t pte_t /* or would you rather have a typedef */
#define __pte_val(x) ((x).pte_low)
-#define pte_val(x) (__pte_val(x) & _PAGE_PRESENT ? \
- machine_to_phys(__pte_val(x)) : \
- __pte_val(x))
-#define __pte(x) ({ unsigned long _x = (x); \
- (pte_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
+#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO)) \
+ == _PAGE_PRESENT ? \
+ machine_to_phys(__pte_val(x)) : \
+ __pte_val(x))
+#define __pte(x) ({ unsigned long _x = (x); \
+ (pte_t)(((_x) & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT ? \
+ phys_to_machine(_x) : (_x)); })
#define __pmd_val(x) __pud_val((x).pud)
#define __pud_val(x) __pgd_val((x).pgd)
#define __pgd(x) ({ unsigned long _x = (x); \
diff -r 9a5af85d3238 -r de57c3f218fb
include/asm-i386/mach-xen/asm/pgtable-2level.h
--- a/include/asm-i386/mach-xen/asm/pgtable-2level.h Wed Mar 19 10:23:31
2008 +0000
+++ b/include/asm-i386/mach-xen/asm/pgtable-2level.h Thu Mar 20 11:35:25
2008 +0000
@@ -71,8 +71,10 @@ static inline pte_t ptep_get_and_clear(s
#define __pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
-#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
- mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_IO ? max_mapnr : \
+ (_pte).pte_low & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : \
+ __pte_mfn(_pte))
#define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
diff -r 9a5af85d3238 -r de57c3f218fb
include/asm-i386/mach-xen/asm/pgtable-3level.h
--- a/include/asm-i386/mach-xen/asm/pgtable-3level.h Wed Mar 19 10:23:31
2008 +0000
+++ b/include/asm-i386/mach-xen/asm/pgtable-3level.h Thu Mar 20 11:35:25
2008 +0000
@@ -170,8 +170,10 @@ static inline int pte_same(pte_t a, pte_
((_pte).pte_high << (32-PAGE_SHIFT)))
#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
-#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
- mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_IO ? max_mapnr : \
+ (_pte).pte_low & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : \
+ __pte_mfn(_pte))
extern unsigned long long __supported_pte_mask;
diff -r 9a5af85d3238 -r de57c3f218fb include/asm-i386/mach-xen/asm/pgtable.h
--- a/include/asm-i386/mach-xen/asm/pgtable.h Wed Mar 19 10:23:31 2008 +0000
+++ b/include/asm-i386/mach-xen/asm/pgtable.h Thu Mar 20 11:35:25 2008 +0000
@@ -133,9 +133,12 @@ void paging_init(void);
#define _PAGE_NX 0
#endif
+/* Mapped page is I/O or foreign and has no associated page struct. */
+#define _PAGE_IO 0x200
+
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED
| _PAGE_DIRTY)
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |
_PAGE_DIRTY)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
#define PAGE_NONE \
__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
diff -r 9a5af85d3238 -r de57c3f218fb include/asm-x86_64/mach-xen/asm/page.h
--- a/include/asm-x86_64/mach-xen/asm/page.h Wed Mar 19 10:23:31 2008 +0000
+++ b/include/asm-x86_64/mach-xen/asm/page.h Thu Mar 20 11:35:25 2008 +0000
@@ -15,6 +15,7 @@
* below. The preprocessor will warn if the two definitions aren't identical.
*/
#define _PAGE_PRESENT 0x001
+#define _PAGE_IO 0x200
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
@@ -89,9 +90,10 @@ typedef struct { unsigned long pgprot; }
typedef struct { unsigned long pgprot; } pgprot_t;
#define __pte_val(x) ((x).pte)
-#define pte_val(x) ((__pte_val(x) & _PAGE_PRESENT) ? \
- pte_machine_to_phys(__pte_val(x)) : \
- __pte_val(x))
+#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO)) \
+ == _PAGE_PRESENT ? \
+ pte_machine_to_phys(__pte_val(x)) : \
+ __pte_val(x))
#define __pmd_val(x) ((x).pmd)
static inline unsigned long pmd_val(pmd_t x)
@@ -125,7 +127,8 @@ static inline unsigned long pgd_val(pgd_
static inline pte_t __pte(unsigned long x)
{
- if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
+ if ((x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
+ x = pte_phys_to_machine(x);
return ((pte_t) { (x) });
}
diff -r 9a5af85d3238 -r de57c3f218fb include/asm-x86_64/mach-xen/asm/pgtable.h
--- a/include/asm-x86_64/mach-xen/asm/pgtable.h Wed Mar 19 10:23:31 2008 +0000
+++ b/include/asm-x86_64/mach-xen/asm/pgtable.h Thu Mar 20 11:35:25 2008 +0000
@@ -168,6 +168,9 @@ static inline void pgd_clear (pgd_t * pg
#define _PAGE_PROTNONE 0x080 /* If not present */
#define _PAGE_NX (1UL<<_PAGE_BIT_NX)
+/* Mapped page is I/O or foreign and has no associated page struct. */
+#define _PAGE_IO 0x200
+
#if CONFIG_XEN_COMPAT <= 0x030002
extern unsigned int __kernel_page_user;
#else
@@ -177,7 +180,7 @@ extern unsigned int __kernel_page_user;
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED
| _PAGE_DIRTY)
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |
_PAGE_DIRTY | __kernel_page_user)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
_PAGE_ACCESSED | _PAGE_NX)
@@ -268,8 +271,10 @@ static inline unsigned long pud_bad(pud_
#define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
#define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
-#define pte_pfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
- mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
+#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? end_pfn : \
+ (_pte).pte & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : \
+ __pte_mfn(_pte))
#define pte_page(x) pfn_to_page(pte_pfn(x))
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|