ia64/xen-unstable

changeset 13560:765e08679f2b

linux/i386: relax highpte pinning/write-protecting
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Mon Jan 22 15:42:13 2007 +0000 (2007-01-22)
parents de6c4f72b65b
children cc819d81be2a
files linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h linux-2.6-xen-sparse/include/linux/page-flags.h linux-2.6-xen-sparse/include/xen/foreign_page.h linux-2.6-xen-sparse/mm/page_alloc.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Mon Jan 22 15:31:27 2007 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Mon Jan 22 15:42:13 2007 +0000
     1.3 @@ -55,7 +55,9 @@ void *kmap_atomic(struct page *page, enu
     1.4  /* Same as kmap_atomic but with PAGE_KERNEL_RO page protection. */
     1.5  void *kmap_atomic_pte(struct page *page, enum km_type type)
     1.6  {
     1.7 -	return __kmap_atomic(page, type, PAGE_KERNEL_RO);
     1.8 +	return __kmap_atomic(page, type,
     1.9 +	                     test_bit(PG_pinned, &page->flags)
    1.10 +	                     ? PAGE_KERNEL_RO : kmap_prot);
    1.11  }
    1.12  
    1.13  void kunmap_atomic(void *kvaddr, enum km_type type)
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Jan 22 15:31:27 2007 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Jan 22 15:42:13 2007 +0000
     2.3 @@ -25,7 +25,6 @@
     2.4  #include <asm/mmu_context.h>
     2.5  
     2.6  #include <xen/features.h>
     2.7 -#include <xen/foreign_page.h>
     2.8  #include <asm/hypervisor.h>
     2.9  
    2.10  static void pgd_test_and_unpin(pgd_t *pgd);
    2.11 @@ -239,14 +238,6 @@ struct page *pte_alloc_one(struct mm_str
    2.12  
    2.13  #ifdef CONFIG_HIGHPTE
    2.14  	pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
    2.15 -	if (pte && PageHighMem(pte)) {
    2.16 -		struct mmuext_op op;
    2.17 -
    2.18 -		kmap_flush_unused();
    2.19 -		op.cmd = MMUEXT_PIN_L1_TABLE;
    2.20 -		op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte));
    2.21 -		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
    2.22 -	}
    2.23  #else
    2.24  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
    2.25  #endif
    2.26 @@ -267,13 +258,8 @@ void pte_free(struct page *pte)
    2.27  		if (!pte_write(*virt_to_ptep(va)))
    2.28  			BUG_ON(HYPERVISOR_update_va_mapping(
    2.29  			       va, pfn_pte(pfn, PAGE_KERNEL), 0));
    2.30 -	} else {
    2.31 -		struct mmuext_op op;
    2.32 -
    2.33 -		op.cmd = MMUEXT_UNPIN_TABLE;
    2.34 -		op.arg1.mfn = pfn_to_mfn(pfn);
    2.35 -		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
    2.36 -	}
    2.37 +	} else
    2.38 +		clear_bit(PG_pinned, &pte->flags);
    2.39  
    2.40  	ClearPageForeign(pte);
    2.41  	init_page_count(pte);
    2.42 @@ -587,46 +573,48 @@ void make_pages_writable(void *va, unsig
    2.43  	}
    2.44  }
    2.45  
    2.46 -static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
    2.47 +static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags)
    2.48  {
    2.49 -	struct page *page = virt_to_page(pt);
    2.50  	unsigned long pfn = page_to_pfn(page);
    2.51  
    2.52  	if (PageHighMem(page))
    2.53 -		return;
    2.54 +		return pgprot_val(flags) & _PAGE_RW
    2.55 +		       ? test_and_clear_bit(PG_pinned, &page->flags)
    2.56 +		       : !test_and_set_bit(PG_pinned, &page->flags);
    2.57 +
    2.58  	BUG_ON(HYPERVISOR_update_va_mapping(
    2.59  		(unsigned long)__va(pfn << PAGE_SHIFT),
    2.60  		pfn_pte(pfn, flags), 0));
    2.61 +
    2.62 +	return 0;
    2.63  }
    2.64  
    2.65 -static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
    2.66 +static int pgd_walk(pgd_t *pgd_base, pgprot_t flags)
    2.67  {
    2.68  	pgd_t *pgd = pgd_base;
    2.69  	pud_t *pud;
    2.70  	pmd_t *pmd;
    2.71 -	pte_t *pte;
    2.72 -	int    g, u, m;
    2.73 +	int    g, u, m, flush;
    2.74  
    2.75  	if (xen_feature(XENFEAT_auto_translated_physmap))
    2.76 -		return;
    2.77 +		return 0;
    2.78  
    2.79 -	for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    2.80 +	for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    2.81  		if (pgd_none(*pgd))
    2.82  			continue;
    2.83  		pud = pud_offset(pgd, 0);
    2.84  		if (PTRS_PER_PUD > 1) /* not folded */
    2.85 -			pgd_walk_set_prot(pud,flags);
    2.86 +			flush |= pgd_walk_set_prot(virt_to_page(pud),flags);
    2.87  		for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
    2.88  			if (pud_none(*pud))
    2.89  				continue;
    2.90  			pmd = pmd_offset(pud, 0);
    2.91  			if (PTRS_PER_PMD > 1) /* not folded */
    2.92 -				pgd_walk_set_prot(pmd,flags);
    2.93 +				flush |= pgd_walk_set_prot(virt_to_page(pmd),flags);
    2.94  			for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
    2.95  				if (pmd_none(*pmd))
    2.96  					continue;
    2.97 -				pte = pte_offset_kernel(pmd,0);
    2.98 -				pgd_walk_set_prot(pte,flags);
    2.99 +				flush |= pgd_walk_set_prot(pmd_page(*pmd),flags);
   2.100  			}
   2.101  		}
   2.102  	}
   2.103 @@ -635,11 +623,14 @@ static void pgd_walk(pgd_t *pgd_base, pg
   2.104  		(unsigned long)pgd_base,
   2.105  		pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
   2.106  		UVMF_TLB_FLUSH));
   2.107 +
   2.108 +	return flush;
   2.109  }
   2.110  
   2.111  static void __pgd_pin(pgd_t *pgd)
   2.112  {
   2.113 -	pgd_walk(pgd, PAGE_KERNEL_RO);
   2.114 +	if (pgd_walk(pgd, PAGE_KERNEL_RO))
   2.115 +		kmap_flush_unused();
   2.116  	xen_pgd_pin(__pa(pgd));
   2.117  	set_bit(PG_pinned, &virt_to_page(pgd)->flags);
   2.118  }
   2.119 @@ -647,7 +638,8 @@ static void __pgd_pin(pgd_t *pgd)
   2.120  static void __pgd_unpin(pgd_t *pgd)
   2.121  {
   2.122  	xen_pgd_unpin(__pa(pgd));
   2.123 -	pgd_walk(pgd, PAGE_KERNEL);
   2.124 +	if (pgd_walk(pgd, PAGE_KERNEL))
   2.125 +		kmap_flush_unused();
   2.126  	clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
   2.127  }
   2.128  
     3.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Mon Jan 22 15:31:27 2007 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Mon Jan 22 15:42:13 2007 +0000
     3.3 @@ -28,13 +28,12 @@
     3.4  #include <asm/bug.h>
     3.5  #include <xen/interface/xen.h>
     3.6  #include <xen/features.h>
     3.7 -#include <xen/foreign_page.h>
     3.8  
     3.9 -#define arch_free_page(_page,_order)			\
    3.10 -({	int foreign = PageForeign(_page);		\
    3.11 -	if (foreign)					\
    3.12 -		(PageForeignDestructor(_page))(_page);	\
    3.13 -	foreign;					\
    3.14 +#define arch_free_page(_page,_order)		\
    3.15 +({	int foreign = PageForeign(_page);	\
    3.16 +	if (foreign)				\
    3.17 +		PageForeignDestructor(_page);	\
    3.18 +	foreign;				\
    3.19  })
    3.20  #define HAVE_ARCH_FREE_PAGE
    3.21  
     4.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Mon Jan 22 15:31:27 2007 +0000
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Mon Jan 22 15:42:13 2007 +0000
     4.3 @@ -6,27 +6,23 @@
     4.4  #include <linux/mm.h>		/* for struct page */
     4.5  #include <asm/io.h>		/* for phys_to_virt and page_to_pseudophys */
     4.6  
     4.7 -/* Is this pagetable pinned? */
     4.8 -#define PG_pinned	PG_arch_1
     4.9 -
    4.10  #define pmd_populate_kernel(mm, pmd, pte) \
    4.11  		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
    4.12  
    4.13  #define pmd_populate(mm, pmd, pte) 					\
    4.14  do {									\
    4.15 +	unsigned long pfn = page_to_pfn(pte);				\
    4.16  	if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) {	\
    4.17  		if (!PageHighMem(pte))					\
    4.18  			BUG_ON(HYPERVISOR_update_va_mapping(		\
    4.19 -			  (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\
    4.20 -			  pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));\
    4.21 -		set_pmd(pmd, __pmd(_PAGE_TABLE +			\
    4.22 -			((unsigned long long)page_to_pfn(pte) <<	\
    4.23 -				(unsigned long long) PAGE_SHIFT)));	\
    4.24 -	} else {							\
    4.25 -		*(pmd) = __pmd(_PAGE_TABLE +				\
    4.26 -			((unsigned long long)page_to_pfn(pte) <<	\
    4.27 -				(unsigned long long) PAGE_SHIFT));	\
    4.28 -	}								\
    4.29 +			  (unsigned long)__va(pfn << PAGE_SHIFT),	\
    4.30 +			  pfn_pte(pfn, PAGE_KERNEL_RO), 0));		\
    4.31 +		else if (!test_and_set_bit(PG_pinned, &pte->flags))	\
    4.32 +			kmap_flush_unused();				\
    4.33 +		set_pmd(pmd,						\
    4.34 +		        __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT))); \
    4.35 +	} else							\
    4.36 +		*(pmd) = __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT)); \
    4.37  } while (0)
    4.38  
    4.39  /*
     5.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Mon Jan 22 15:31:27 2007 +0000
     5.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Mon Jan 22 15:42:13 2007 +0000
     5.3 @@ -25,6 +25,9 @@
     5.4  #include <linux/list.h>
     5.5  #include <linux/spinlock.h>
     5.6  
     5.7 +/* Is this pagetable pinned? */
     5.8 +#define PG_pinned	PG_arch_1
     5.9 +
    5.10  struct mm_struct;
    5.11  struct vm_area_struct;
    5.12  
     6.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Mon Jan 22 15:31:27 2007 +0000
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Mon Jan 22 15:42:13 2007 +0000
     6.3 @@ -8,13 +8,12 @@
     6.4  #include <asm/bug.h>
     6.5  #endif
     6.6  #include <xen/interface/xen.h> 
     6.7 -#include <xen/foreign_page.h>
     6.8  
     6.9 -#define arch_free_page(_page,_order)			\
    6.10 -({	int foreign = PageForeign(_page);		\
    6.11 -	if (foreign)					\
    6.12 -		(PageForeignDestructor(_page))(_page);	\
    6.13 -	foreign;					\
    6.14 +#define arch_free_page(_page,_order)		\
    6.15 +({	int foreign = PageForeign(_page);	\
    6.16 +	if (foreign)				\
    6.17 +		PageForeignDestructor(_page);	\
    6.18 +	foreign;				\
    6.19  })
    6.20  #define HAVE_ARCH_FREE_PAGE
    6.21  
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/linux-2.6-xen-sparse/include/linux/page-flags.h	Mon Jan 22 15:42:13 2007 +0000
     7.3 @@ -0,0 +1,280 @@
     7.4 +/*
     7.5 + * Macros for manipulating and testing page->flags
     7.6 + */
     7.7 +
     7.8 +#ifndef PAGE_FLAGS_H
     7.9 +#define PAGE_FLAGS_H
    7.10 +
    7.11 +#include <linux/types.h>
    7.12 +
    7.13 +/*
    7.14 + * Various page->flags bits:
    7.15 + *
    7.16 + * PG_reserved is set for special pages, which can never be swapped out. Some
    7.17 + * of them might not even exist (eg empty_bad_page)...
    7.18 + *
    7.19 + * The PG_private bitflag is set if page->private contains a valid value.
    7.20 + *
    7.21 + * During disk I/O, PG_locked is used. This bit is set before I/O and
    7.22 + * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks
    7.23 + * waiting for the I/O on this page to complete.
    7.24 + *
    7.25 + * PG_uptodate tells whether the page's contents is valid.  When a read
    7.26 + * completes, the page becomes uptodate, unless a disk I/O error happened.
    7.27 + *
    7.28 + * For choosing which pages to swap out, inode pages carry a PG_referenced bit,
    7.29 + * which is set any time the system accesses that page through the (mapping,
    7.30 + * index) hash table.  This referenced bit, together with the referenced bit
    7.31 + * in the page tables, is used to manipulate page->age and move the page across
    7.32 + * the active, inactive_dirty and inactive_clean lists.
    7.33 + *
    7.34 + * Note that the referenced bit, the page->lru list_head and the active,
    7.35 + * inactive_dirty and inactive_clean lists are protected by the
    7.36 + * zone->lru_lock, and *NOT* by the usual PG_locked bit!
    7.37 + *
    7.38 + * PG_error is set to indicate that an I/O error occurred on this page.
    7.39 + *
    7.40 + * PG_arch_1 is an architecture specific page state bit.  The generic code
    7.41 + * guarantees that this bit is cleared for a page when it first is entered into
    7.42 + * the page cache.
    7.43 + *
    7.44 + * PG_highmem pages are not permanently mapped into the kernel virtual address
    7.45 + * space, they need to be kmapped separately for doing IO on the pages.  The
    7.46 + * struct page (these bits with information) are always mapped into kernel
    7.47 + * address space...
    7.48 + */
    7.49 +
    7.50 +/*
    7.51 + * Don't use the *_dontuse flags.  Use the macros.  Otherwise you'll break
    7.52 + * locked- and dirty-page accounting.
    7.53 + *
    7.54 + * The page flags field is split into two parts, the main flags area
    7.55 + * which extends from the low bits upwards, and the fields area which
    7.56 + * extends from the high bits downwards.
    7.57 + *
    7.58 + *  | FIELD | ... | FLAGS |
    7.59 + *  N-1     ^             0
    7.60 + *          (N-FLAGS_RESERVED)
    7.61 + *
    7.62 + * The fields area is reserved for fields mapping zone, node and SPARSEMEM
    7.63 + * section.  The boundry between these two areas is defined by
    7.64 + * FLAGS_RESERVED which defines the width of the fields section
    7.65 + * (see linux/mmzone.h).  New flags must _not_ overlap with this area.
    7.66 + */
    7.67 +#define PG_locked	 	 0	/* Page is locked. Don't touch. */
    7.68 +#define PG_error		 1
    7.69 +#define PG_referenced		 2
    7.70 +#define PG_uptodate		 3
    7.71 +
    7.72 +#define PG_dirty	 	 4
    7.73 +#define PG_lru			 5
    7.74 +#define PG_active		 6
    7.75 +#define PG_slab			 7	/* slab debug (Suparna wants this) */
    7.76 +
    7.77 +#define PG_checked		 8	/* kill me in 2.5.<early>. */
    7.78 +#define PG_arch_1		 9
    7.79 +#define PG_reserved		10
    7.80 +#define PG_private		11	/* Has something at ->private */
    7.81 +
    7.82 +#define PG_writeback		12	/* Page is under writeback */
    7.83 +#define PG_nosave		13	/* Used for system suspend/resume */
    7.84 +#define PG_compound		14	/* Part of a compound page */
    7.85 +#define PG_swapcache		15	/* Swap page: swp_entry_t in private */
    7.86 +
    7.87 +#define PG_mappedtodisk		16	/* Has blocks allocated on-disk */
    7.88 +#define PG_reclaim		17	/* To be reclaimed asap */
    7.89 +#define PG_nosave_free		18	/* Free, should not be written */
    7.90 +#define PG_buddy		19	/* Page is free, on buddy lists */
    7.91 +
    7.92 +
    7.93 +#if (BITS_PER_LONG > 32)
    7.94 +/*
    7.95 + * 64-bit-only flags build down from bit 31
    7.96 + *
    7.97 + * 32 bit  -------------------------------| FIELDS |       FLAGS         |
    7.98 + * 64 bit  |           FIELDS             | ??????         FLAGS         |
    7.99 + *         63                            32                              0
   7.100 + */
   7.101 +#define PG_uncached		31	/* Page has been mapped as uncached */
   7.102 +#endif
   7.103 +
   7.104 +#define PG_foreign		20	/* Page is owned by foreign allocator. */
   7.105 +
   7.106 +/*
   7.107 + * Manipulation of page state flags
   7.108 + */
   7.109 +#define PageLocked(page)		\
   7.110 +		test_bit(PG_locked, &(page)->flags)
   7.111 +#define SetPageLocked(page)		\
   7.112 +		set_bit(PG_locked, &(page)->flags)
   7.113 +#define TestSetPageLocked(page)		\
   7.114 +		test_and_set_bit(PG_locked, &(page)->flags)
   7.115 +#define ClearPageLocked(page)		\
   7.116 +		clear_bit(PG_locked, &(page)->flags)
   7.117 +#define TestClearPageLocked(page)	\
   7.118 +		test_and_clear_bit(PG_locked, &(page)->flags)
   7.119 +
   7.120 +#define PageError(page)		test_bit(PG_error, &(page)->flags)
   7.121 +#define SetPageError(page)	set_bit(PG_error, &(page)->flags)
   7.122 +#define ClearPageError(page)	clear_bit(PG_error, &(page)->flags)
   7.123 +
   7.124 +#define PageReferenced(page)	test_bit(PG_referenced, &(page)->flags)
   7.125 +#define SetPageReferenced(page)	set_bit(PG_referenced, &(page)->flags)
   7.126 +#define ClearPageReferenced(page)	clear_bit(PG_referenced, &(page)->flags)
   7.127 +#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
   7.128 +
   7.129 +#define PageUptodate(page)	test_bit(PG_uptodate, &(page)->flags)
   7.130 +#ifdef CONFIG_S390
   7.131 +#define SetPageUptodate(_page) \
   7.132 +	do {								      \
   7.133 +		struct page *__page = (_page);				      \
   7.134 +		if (!test_and_set_bit(PG_uptodate, &__page->flags))	      \
   7.135 +			page_test_and_clear_dirty(_page);		      \
   7.136 +	} while (0)
   7.137 +#else
   7.138 +#define SetPageUptodate(page)	set_bit(PG_uptodate, &(page)->flags)
   7.139 +#endif
   7.140 +#define ClearPageUptodate(page)	clear_bit(PG_uptodate, &(page)->flags)
   7.141 +
   7.142 +#define PageDirty(page)		test_bit(PG_dirty, &(page)->flags)
   7.143 +#define SetPageDirty(page)	set_bit(PG_dirty, &(page)->flags)
   7.144 +#define TestSetPageDirty(page)	test_and_set_bit(PG_dirty, &(page)->flags)
   7.145 +#define ClearPageDirty(page)	clear_bit(PG_dirty, &(page)->flags)
   7.146 +#define __ClearPageDirty(page)	__clear_bit(PG_dirty, &(page)->flags)
   7.147 +#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags)
   7.148 +
   7.149 +#define PageLRU(page)		test_bit(PG_lru, &(page)->flags)
   7.150 +#define SetPageLRU(page)	set_bit(PG_lru, &(page)->flags)
   7.151 +#define ClearPageLRU(page)	clear_bit(PG_lru, &(page)->flags)
   7.152 +#define __ClearPageLRU(page)	__clear_bit(PG_lru, &(page)->flags)
   7.153 +
   7.154 +#define PageActive(page)	test_bit(PG_active, &(page)->flags)
   7.155 +#define SetPageActive(page)	set_bit(PG_active, &(page)->flags)
   7.156 +#define ClearPageActive(page)	clear_bit(PG_active, &(page)->flags)
   7.157 +#define __ClearPageActive(page)	__clear_bit(PG_active, &(page)->flags)
   7.158 +
   7.159 +#define PageSlab(page)		test_bit(PG_slab, &(page)->flags)
   7.160 +#define __SetPageSlab(page)	__set_bit(PG_slab, &(page)->flags)
   7.161 +#define __ClearPageSlab(page)	__clear_bit(PG_slab, &(page)->flags)
   7.162 +
   7.163 +#ifdef CONFIG_HIGHMEM
   7.164 +#define PageHighMem(page)	is_highmem(page_zone(page))
   7.165 +#else
   7.166 +#define PageHighMem(page)	0 /* needed to optimize away at compile time */
   7.167 +#endif
   7.168 +
   7.169 +#define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
   7.170 +#define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
   7.171 +#define ClearPageChecked(page)	clear_bit(PG_checked, &(page)->flags)
   7.172 +
   7.173 +#define PageReserved(page)	test_bit(PG_reserved, &(page)->flags)
   7.174 +#define SetPageReserved(page)	set_bit(PG_reserved, &(page)->flags)
   7.175 +#define ClearPageReserved(page)	clear_bit(PG_reserved, &(page)->flags)
   7.176 +#define __ClearPageReserved(page)	__clear_bit(PG_reserved, &(page)->flags)
   7.177 +
   7.178 +#define SetPagePrivate(page)	set_bit(PG_private, &(page)->flags)
   7.179 +#define ClearPagePrivate(page)	clear_bit(PG_private, &(page)->flags)
   7.180 +#define PagePrivate(page)	test_bit(PG_private, &(page)->flags)
   7.181 +#define __SetPagePrivate(page)  __set_bit(PG_private, &(page)->flags)
   7.182 +#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
   7.183 +
   7.184 +#define PageWriteback(page)	test_bit(PG_writeback, &(page)->flags)
   7.185 +#define SetPageWriteback(page)						\
   7.186 +	do {								\
   7.187 +		if (!test_and_set_bit(PG_writeback,			\
   7.188 +				&(page)->flags))			\
   7.189 +			inc_zone_page_state(page, NR_WRITEBACK);	\
   7.190 +	} while (0)
   7.191 +#define TestSetPageWriteback(page)					\
   7.192 +	({								\
   7.193 +		int ret;						\
   7.194 +		ret = test_and_set_bit(PG_writeback,			\
   7.195 +					&(page)->flags);		\
   7.196 +		if (!ret)						\
   7.197 +			inc_zone_page_state(page, NR_WRITEBACK);	\
   7.198 +		ret;							\
   7.199 +	})
   7.200 +#define ClearPageWriteback(page)					\
   7.201 +	do {								\
   7.202 +		if (test_and_clear_bit(PG_writeback,			\
   7.203 +				&(page)->flags))			\
   7.204 +			dec_zone_page_state(page, NR_WRITEBACK);	\
   7.205 +	} while (0)
   7.206 +#define TestClearPageWriteback(page)					\
   7.207 +	({								\
   7.208 +		int ret;						\
   7.209 +		ret = test_and_clear_bit(PG_writeback,			\
   7.210 +				&(page)->flags);			\
   7.211 +		if (ret)						\
   7.212 +			dec_zone_page_state(page, NR_WRITEBACK);	\
   7.213 +		ret;							\
   7.214 +	})
   7.215 +
   7.216 +#define PageNosave(page)	test_bit(PG_nosave, &(page)->flags)
   7.217 +#define SetPageNosave(page)	set_bit(PG_nosave, &(page)->flags)
   7.218 +#define TestSetPageNosave(page)	test_and_set_bit(PG_nosave, &(page)->flags)
   7.219 +#define ClearPageNosave(page)		clear_bit(PG_nosave, &(page)->flags)
   7.220 +#define TestClearPageNosave(page)	test_and_clear_bit(PG_nosave, &(page)->flags)
   7.221 +
   7.222 +#define PageNosaveFree(page)	test_bit(PG_nosave_free, &(page)->flags)
   7.223 +#define SetPageNosaveFree(page)	set_bit(PG_nosave_free, &(page)->flags)
   7.224 +#define ClearPageNosaveFree(page)		clear_bit(PG_nosave_free, &(page)->flags)
   7.225 +
   7.226 +#define PageBuddy(page)		test_bit(PG_buddy, &(page)->flags)
   7.227 +#define __SetPageBuddy(page)	__set_bit(PG_buddy, &(page)->flags)
   7.228 +#define __ClearPageBuddy(page)	__clear_bit(PG_buddy, &(page)->flags)
   7.229 +
   7.230 +#define PageMappedToDisk(page)	test_bit(PG_mappedtodisk, &(page)->flags)
   7.231 +#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
   7.232 +#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
   7.233 +
   7.234 +#define PageReclaim(page)	test_bit(PG_reclaim, &(page)->flags)
   7.235 +#define SetPageReclaim(page)	set_bit(PG_reclaim, &(page)->flags)
   7.236 +#define ClearPageReclaim(page)	clear_bit(PG_reclaim, &(page)->flags)
   7.237 +#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags)
   7.238 +
   7.239 +#define PageCompound(page)	test_bit(PG_compound, &(page)->flags)
   7.240 +#define __SetPageCompound(page)	__set_bit(PG_compound, &(page)->flags)
   7.241 +#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags)
   7.242 +
   7.243 +#ifdef CONFIG_SWAP
   7.244 +#define PageSwapCache(page)	test_bit(PG_swapcache, &(page)->flags)
   7.245 +#define SetPageSwapCache(page)	set_bit(PG_swapcache, &(page)->flags)
   7.246 +#define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags)
   7.247 +#else
   7.248 +#define PageSwapCache(page)	0
   7.249 +#endif
   7.250 +
   7.251 +#define PageUncached(page)	test_bit(PG_uncached, &(page)->flags)
   7.252 +#define SetPageUncached(page)	set_bit(PG_uncached, &(page)->flags)
   7.253 +#define ClearPageUncached(page)	clear_bit(PG_uncached, &(page)->flags)
   7.254 +
   7.255 +#define PageForeign(page)	test_bit(PG_foreign, &(page)->flags)
   7.256 +#define SetPageForeign(page, dtor) do {		\
   7.257 +	set_bit(PG_foreign, &(page)->flags);	\
   7.258 +	(page)->mapping = (void *)dtor;		\
   7.259 +} while (0)
   7.260 +#define ClearPageForeign(page) do {		\
   7.261 +	clear_bit(PG_foreign, &(page)->flags);	\
   7.262 +	(page)->mapping = NULL;			\
   7.263 +} while (0)
   7.264 +#define PageForeignDestructor(page)		\
   7.265 +	( (void (*) (struct page *)) (page)->mapping )(page)
   7.266 +
   7.267 +struct page;	/* forward declaration */
   7.268 +
   7.269 +int test_clear_page_dirty(struct page *page);
   7.270 +int test_clear_page_writeback(struct page *page);
   7.271 +int test_set_page_writeback(struct page *page);
   7.272 +
   7.273 +static inline void clear_page_dirty(struct page *page)
   7.274 +{
   7.275 +	test_clear_page_dirty(page);
   7.276 +}
   7.277 +
   7.278 +static inline void set_page_writeback(struct page *page)
   7.279 +{
   7.280 +	test_set_page_writeback(page);
   7.281 +}
   7.282 +
   7.283 +#endif	/* PAGE_FLAGS_H */
     8.1 --- a/linux-2.6-xen-sparse/include/xen/foreign_page.h	Mon Jan 22 15:31:27 2007 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,30 +0,0 @@
     8.4 -/******************************************************************************
     8.5 - * foreign_page.h
     8.6 - * 
     8.7 - * Provide a "foreign" page type, that is owned by a foreign allocator and 
     8.8 - * not the normal buddy allocator in page_alloc.c
     8.9 - * 
    8.10 - * Copyright (c) 2004, K A Fraser
    8.11 - */
    8.12 -
    8.13 -#ifndef __ASM_XEN_FOREIGN_PAGE_H__
    8.14 -#define __ASM_XEN_FOREIGN_PAGE_H__
    8.15 -
    8.16 -#define PG_foreign		PG_arch_1
    8.17 -
    8.18 -#define PageForeign(page)	test_bit(PG_foreign, &(page)->flags)
    8.19 -
    8.20 -#define SetPageForeign(page, dtor) do {		\
    8.21 -	set_bit(PG_foreign, &(page)->flags);	\
    8.22 -	(page)->mapping = (void *)dtor;		\
    8.23 -} while (0)
    8.24 -
    8.25 -#define ClearPageForeign(page) do {		\
    8.26 -	clear_bit(PG_foreign, &(page)->flags);	\
    8.27 -	(page)->mapping = NULL;			\
    8.28 -} while (0)
    8.29 -
    8.30 -#define PageForeignDestructor(page)	\
    8.31 -	( (void (*) (struct page *)) (page)->mapping )
    8.32 -
    8.33 -#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
     9.1 --- a/linux-2.6-xen-sparse/mm/page_alloc.c	Mon Jan 22 15:31:27 2007 +0000
     9.2 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c	Mon Jan 22 15:42:13 2007 +0000
     9.3 @@ -154,7 +154,11 @@ static void bad_page(struct page *page)
     9.4  			1 << PG_slab    |
     9.5  			1 << PG_swapcache |
     9.6  			1 << PG_writeback |
     9.7 -			1 << PG_buddy );
     9.8 +			1 << PG_buddy	|
     9.9 +#ifdef CONFIG_X86_XEN
    9.10 +			1 << PG_pinned	|
    9.11 +#endif
    9.12 +			1 << PG_foreign );
    9.13  	set_page_count(page, 0);
    9.14  	reset_page_mapcount(page);
    9.15  	page->mapping = NULL;
    9.16 @@ -389,7 +393,11 @@ static inline int free_pages_check(struc
    9.17  			1 << PG_swapcache |
    9.18  			1 << PG_writeback |
    9.19  			1 << PG_reserved |
    9.20 -			1 << PG_buddy ))))
    9.21 +			1 << PG_buddy	|
    9.22 +#ifdef CONFIG_X86_XEN
    9.23 +			1 << PG_pinned	|
    9.24 +#endif
    9.25 +			1 << PG_foreign ))))
    9.26  		bad_page(page);
    9.27  	if (PageDirty(page))
    9.28  		__ClearPageDirty(page);
    9.29 @@ -539,7 +547,11 @@ static int prep_new_page(struct page *pa
    9.30  			1 << PG_swapcache |
    9.31  			1 << PG_writeback |
    9.32  			1 << PG_reserved |
    9.33 -			1 << PG_buddy ))))
    9.34 +			1 << PG_buddy	|
    9.35 +#ifdef CONFIG_X86_XEN
    9.36 +			1 << PG_pinned	|
    9.37 +#endif
    9.38 +			1 << PG_foreign ))))
    9.39  		bad_page(page);
    9.40  
    9.41  	/*