ia64/linux-2.6.18-xen.hg

changeset 488:de57c3f218fb

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@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Mar 20 11:35:25 2008 +0000 (2008-03-20)
parents 9a5af85d3238
children 17807457215a 14b987774233
files arch/i386/mm/ioremap-xen.c include/asm-i386/mach-xen/asm/page.h include/asm-i386/mach-xen/asm/pgtable-2level.h include/asm-i386/mach-xen/asm/pgtable-3level.h include/asm-i386/mach-xen/asm/pgtable.h include/asm-x86_64/mach-xen/asm/page.h include/asm-x86_64/mach-xen/asm/pgtable.h
line diff
     1.1 --- a/arch/i386/mm/ioremap-xen.c	Wed Mar 19 10:23:31 2008 +0000
     1.2 +++ b/arch/i386/mm/ioremap-xen.c	Thu Mar 20 11:35:25 2008 +0000
     1.3 @@ -76,7 +76,7 @@ static int __direct_remap_pfn_range(stru
     1.4  		 * Fill in the machine address: PTE ptr is done later by
     1.5  		 * apply_to_page_range(). 
     1.6  		 */
     1.7 -		v->val = __pte_val(pfn_pte_ma(mfn, prot));
     1.8 +		v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
     1.9  
    1.10  		mfn++;
    1.11  		address += PAGE_SIZE; 
     2.1 --- a/include/asm-i386/mach-xen/asm/page.h	Wed Mar 19 10:23:31 2008 +0000
     2.2 +++ b/include/asm-i386/mach-xen/asm/page.h	Thu Mar 20 11:35:25 2008 +0000
     2.3 @@ -27,6 +27,7 @@
     2.4   * below. The preprocessor will warn if the two definitions aren't identical.
     2.5   */
     2.6  #define _PAGE_PRESENT	0x001
     2.7 +#define _PAGE_IO	0x200
     2.8  
     2.9  #ifndef __ASSEMBLY__
    2.10  
    2.11 @@ -74,8 +75,9 @@ typedef struct { unsigned long long pgd;
    2.12  typedef struct { unsigned long long pgprot; } pgprot_t;
    2.13  #define pgprot_val(x)	((x).pgprot)
    2.14  #include <asm/maddr.h>
    2.15 -#define __pte(x) ({ unsigned long long _x = (x);        \
    2.16 -    if (_x & _PAGE_PRESENT) _x = pte_phys_to_machine(_x);   \
    2.17 +#define __pte(x) ({ unsigned long long _x = (x);			\
    2.18 +    if ((_x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)		\
    2.19 +        _x = pte_phys_to_machine(_x);					\
    2.20      ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
    2.21  #define __pgd(x) ({ unsigned long long _x = (x); \
    2.22      (pgd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
    2.23 @@ -88,7 +90,8 @@ static inline unsigned long long __pte_v
    2.24  static inline unsigned long long pte_val(pte_t x)
    2.25  {
    2.26  	unsigned long long ret = __pte_val(x);
    2.27 -	if (x.pte_low & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
    2.28 +	if ((x.pte_low & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
    2.29 +		ret = pte_machine_to_phys(ret);
    2.30  	return ret;
    2.31  }
    2.32  #define __pmd_val(x) ((x).pmd)
    2.33 @@ -119,11 +122,13 @@ typedef struct { unsigned long pgprot; }
    2.34  #include <asm/maddr.h>
    2.35  #define boot_pte_t pte_t /* or would you rather have a typedef */
    2.36  #define __pte_val(x) ((x).pte_low)
    2.37 -#define pte_val(x) (__pte_val(x) & _PAGE_PRESENT ? \
    2.38 -                    machine_to_phys(__pte_val(x)) : \
    2.39 -                    __pte_val(x))
    2.40 -#define __pte(x) ({ unsigned long _x = (x); \
    2.41 -    (pte_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
    2.42 +#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO))	\
    2.43 +		    == _PAGE_PRESENT ?				\
    2.44 +		    machine_to_phys(__pte_val(x)) :		\
    2.45 +		    __pte_val(x))
    2.46 +#define __pte(x) ({ unsigned long _x = (x);				\
    2.47 +    (pte_t)(((_x) & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT ?	\
    2.48 +    phys_to_machine(_x) : (_x)); })
    2.49  #define __pmd_val(x) __pud_val((x).pud)
    2.50  #define __pud_val(x) __pgd_val((x).pgd)
    2.51  #define __pgd(x) ({ unsigned long _x = (x); \
     3.1 --- a/include/asm-i386/mach-xen/asm/pgtable-2level.h	Wed Mar 19 10:23:31 2008 +0000
     3.2 +++ b/include/asm-i386/mach-xen/asm/pgtable-2level.h	Thu Mar 20 11:35:25 2008 +0000
     3.3 @@ -71,8 +71,10 @@ static inline pte_t ptep_get_and_clear(s
     3.4  #define __pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
     3.5  #define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
     3.6  	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
     3.7 -#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
     3.8 -	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
     3.9 +#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_IO ? max_mapnr :	\
    3.10 +		       (_pte).pte_low & _PAGE_PRESENT ?		\
    3.11 +		       mfn_to_local_pfn(__pte_mfn(_pte)) :	\
    3.12 +		       __pte_mfn(_pte))
    3.13  
    3.14  #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
    3.15  
     4.1 --- a/include/asm-i386/mach-xen/asm/pgtable-3level.h	Wed Mar 19 10:23:31 2008 +0000
     4.2 +++ b/include/asm-i386/mach-xen/asm/pgtable-3level.h	Thu Mar 20 11:35:25 2008 +0000
     4.3 @@ -170,8 +170,10 @@ static inline int pte_same(pte_t a, pte_
     4.4  			 ((_pte).pte_high << (32-PAGE_SHIFT)))
     4.5  #define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
     4.6  	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
     4.7 -#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
     4.8 -	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
     4.9 +#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_IO ? max_mapnr :	\
    4.10 +		       (_pte).pte_low & _PAGE_PRESENT ?		\
    4.11 +		       mfn_to_local_pfn(__pte_mfn(_pte)) :	\
    4.12 +		       __pte_mfn(_pte))
    4.13  
    4.14  extern unsigned long long __supported_pte_mask;
    4.15  
     5.1 --- a/include/asm-i386/mach-xen/asm/pgtable.h	Wed Mar 19 10:23:31 2008 +0000
     5.2 +++ b/include/asm-i386/mach-xen/asm/pgtable.h	Thu Mar 20 11:35:25 2008 +0000
     5.3 @@ -133,9 +133,12 @@ void paging_init(void);
     5.4  #define _PAGE_NX	0
     5.5  #endif
     5.6  
     5.7 +/* Mapped page is I/O or foreign and has no associated page struct. */
     5.8 +#define _PAGE_IO	0x200
     5.9 +
    5.10  #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
    5.11  #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
    5.12 -#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
    5.13 +#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
    5.14  
    5.15  #define PAGE_NONE \
    5.16  	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
     6.1 --- a/include/asm-x86_64/mach-xen/asm/page.h	Wed Mar 19 10:23:31 2008 +0000
     6.2 +++ b/include/asm-x86_64/mach-xen/asm/page.h	Thu Mar 20 11:35:25 2008 +0000
     6.3 @@ -15,6 +15,7 @@
     6.4   * below. The preprocessor will warn if the two definitions aren't identical.
     6.5   */
     6.6  #define _PAGE_PRESENT	0x001
     6.7 +#define _PAGE_IO	0x200
     6.8  
     6.9  /* PAGE_SHIFT determines the page size */
    6.10  #define PAGE_SHIFT	12
    6.11 @@ -89,9 +90,10 @@ typedef struct { unsigned long pgd; } pg
    6.12  typedef struct { unsigned long pgprot; } pgprot_t;
    6.13  
    6.14  #define __pte_val(x) ((x).pte)
    6.15 -#define pte_val(x) ((__pte_val(x) & _PAGE_PRESENT) ? \
    6.16 -                    pte_machine_to_phys(__pte_val(x)) : \
    6.17 -                    __pte_val(x))
    6.18 +#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO))	\
    6.19 +		    == _PAGE_PRESENT ?				\
    6.20 +		    pte_machine_to_phys(__pte_val(x)) :		\
    6.21 +		    __pte_val(x))
    6.22  
    6.23  #define __pmd_val(x) ((x).pmd)
    6.24  static inline unsigned long pmd_val(pmd_t x)
    6.25 @@ -125,7 +127,8 @@ static inline unsigned long pgd_val(pgd_
    6.26  
    6.27  static inline pte_t __pte(unsigned long x)
    6.28  {
    6.29 -	if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
    6.30 +	if ((x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
    6.31 +		x = pte_phys_to_machine(x);
    6.32  	return ((pte_t) { (x) });
    6.33  }
    6.34  
     7.1 --- a/include/asm-x86_64/mach-xen/asm/pgtable.h	Wed Mar 19 10:23:31 2008 +0000
     7.2 +++ b/include/asm-x86_64/mach-xen/asm/pgtable.h	Thu Mar 20 11:35:25 2008 +0000
     7.3 @@ -168,6 +168,9 @@ static inline void pgd_clear (pgd_t * pg
     7.4  #define _PAGE_PROTNONE	0x080	/* If not present */
     7.5  #define _PAGE_NX        (1UL<<_PAGE_BIT_NX)
     7.6  
     7.7 +/* Mapped page is I/O or foreign and has no associated page struct. */
     7.8 +#define _PAGE_IO	0x200
     7.9 +
    7.10  #if CONFIG_XEN_COMPAT <= 0x030002
    7.11  extern unsigned int __kernel_page_user;
    7.12  #else
    7.13 @@ -177,7 +180,7 @@ extern unsigned int __kernel_page_user;
    7.14  #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
    7.15  #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
    7.16  
    7.17 -#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
    7.18 +#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
    7.19  
    7.20  #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
    7.21  #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
    7.22 @@ -268,8 +271,10 @@ static inline unsigned long pud_bad(pud_
    7.23  #define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
    7.24  #define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
    7.25  	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
    7.26 -#define pte_pfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
    7.27 -	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
    7.28 +#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? end_pfn :	\
    7.29 +		       (_pte).pte & _PAGE_PRESENT ?		\
    7.30 +		       mfn_to_local_pfn(__pte_mfn(_pte)) :	\
    7.31 +		       __pte_mfn(_pte))
    7.32  
    7.33  #define pte_page(x)	pfn_to_page(pte_pfn(x))
    7.34