ia64/xen-unstable

changeset 8688:990c009015e8

Merge up and generally make shadow mode be nice.

Signed-off-by: Steven Smith, sos22@cam.ac.uk
author sos22@douglas.cl.cam.ac.uk
date Fri Jan 27 21:23:06 2006 +0100 (2006-01-27)
parents 05a1340bc1e7 60beade30a0c
children e9770d41e5bd
files linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/xen/i386/mm/init.c linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6-xen-sparse/arch/xen/kernel/Makefile linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6-xen-sparse/include/asm-xen/gnttab.h linux-2.6-xen-sparse/mm/memory.c xen/arch/x86/mm.c xen/arch/x86/shadow32.c xen/common/kernel.c xen/common/memory.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Thu Jan 26 19:52:18 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Fri Jan 27 21:23:06 2006 +0100
     1.3 @@ -572,7 +572,7 @@ void __cpuinit cpu_gdt_init(struct Xgt_d
     1.4  	     va < gdt_descr->address + gdt_descr->size;
     1.5  	     va += PAGE_SIZE, f++) {
     1.6  		frames[f] = virt_to_mfn(va);
     1.7 -		make_lowmem_page_readonly((void *)va);
     1.8 +		make_lowmem_mmu_page_readonly((void *)va);
     1.9  	}
    1.10  	if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
    1.11  		BUG();
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Thu Jan 26 19:52:18 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Fri Jan 27 21:23:06 2006 +0100
     2.3 @@ -119,7 +119,7 @@ void destroy_context(struct mm_struct *m
     2.4  	if (mm->context.size) {
     2.5  		if (mm == current->active_mm)
     2.6  			clear_LDT();
     2.7 -		make_pages_writable(mm->context.ldt, 
     2.8 +		make_pages_writable(mm->context.ldt,
     2.9  				    (mm->context.size * LDT_ENTRY_SIZE) /
    2.10  				    PAGE_SIZE);
    2.11  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Thu Jan 26 19:52:18 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Fri Jan 27 21:23:06 2006 +0100
     3.3 @@ -56,6 +56,7 @@
     3.4  #include <asm/hypervisor.h>
     3.5  #include <asm-xen/xen-public/physdev.h>
     3.6  #include <asm-xen/xen-public/memory.h>
     3.7 +#include <asm-xen/features.h>
     3.8  #include "setup_arch_pre.h"
     3.9  #include <bios_ebda.h>
    3.10  
    3.11 @@ -1591,6 +1592,9 @@ void __init setup_arch(char **cmdline_p)
    3.12  	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
    3.13  	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
    3.14  #endif
    3.15 +
    3.16 +	setup_xen_features();
    3.17 +
    3.18  	ARCH_SETUP
    3.19  	if (efi_enabled)
    3.20  		efi_init();
    3.21 @@ -1601,6 +1605,7 @@ void __init setup_arch(char **cmdline_p)
    3.22  
    3.23  	copy_edd();
    3.24  
    3.25 +	/* Make the PFNs in the Xen hole reserved. */
    3.26  	if (!MOUNT_ROOT_RDONLY)
    3.27  		root_mountflags &= ~MS_RDONLY;
    3.28  	init_mm.start_code = (unsigned long) _text;
    3.29 @@ -1763,6 +1768,8 @@ void __init setup_arch(char **cmdline_p)
    3.30  		console_use_vt = 0;
    3.31  #endif
    3.32  	}
    3.33 +
    3.34 +
    3.35  }
    3.36  
    3.37  static int
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Thu Jan 26 19:52:18 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Fri Jan 27 21:23:06 2006 +0100
     4.3 @@ -113,6 +113,20 @@ void xen_pt_switch(unsigned long ptr)
     4.4  	BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
     4.5  }
     4.6  
     4.7 +unsigned long xen_pfn_hole_start(void)
     4.8 +{
     4.9 +	struct mmuext_op op;
    4.10 +	op.cmd = MMUEXT_PFN_HOLE_BASE;
    4.11 +	return HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF);
    4.12 +}
    4.13 +
    4.14 +unsigned long xen_pfn_hole_size(void)
    4.15 +{
    4.16 +	struct mmuext_op op;
    4.17 +	op.cmd = MMUEXT_PFN_HOLE_SIZE;
    4.18 +	return HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF);
    4.19 +}
    4.20 +
    4.21  void xen_new_user_pt(unsigned long ptr)
    4.22  {
    4.23  	struct mmuext_op op;
    4.24 @@ -265,6 +279,7 @@ void xen_set_ldt(unsigned long ptr, unsi
    4.25   */
    4.26  unsigned long *contiguous_bitmap;
    4.27  
    4.28 +#ifndef CONFIG_XEN_SHADOW_MODE
    4.29  static void contiguous_bitmap_set(
    4.30  	unsigned long first_page, unsigned long nr_pages)
    4.31  {
    4.32 @@ -315,9 +330,9 @@ int xen_create_contiguous_region(
    4.33  	pud_t         *pud; 
    4.34  	pmd_t         *pmd;
    4.35  	pte_t         *pte;
    4.36 -	unsigned long  mfn, i, flags;
    4.37 +	unsigned long  frame, i, flags;
    4.38  	struct xen_memory_reservation reservation = {
    4.39 -		.extent_start = &mfn,
    4.40 +		.extent_start = &frame,
    4.41  		.nr_extents   = 1,
    4.42  		.extent_order = 0,
    4.43  		.domid        = DOMID_SELF
    4.44 @@ -333,7 +348,7 @@ int xen_create_contiguous_region(
    4.45  		pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
    4.46  		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
    4.47  		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
    4.48 -		mfn = pte_mfn(*pte);
    4.49 +		frame = pte_mfn(*pte);
    4.50  		BUG_ON(HYPERVISOR_update_va_mapping(
    4.51  			vstart + (i*PAGE_SIZE), __pte_ma(0), 0));
    4.52  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
    4.53 @@ -345,7 +360,8 @@ int xen_create_contiguous_region(
    4.54  	/* 2. Get a new contiguous memory extent. */
    4.55  	reservation.extent_order = order;
    4.56  	reservation.address_bits = address_bits;
    4.57 -	if (HYPERVISOR_memory_op(XENMEM_increase_reservation,
    4.58 +	frame = __pa(vstart) >> PAGE_SHIFT;
    4.59 +	if (HYPERVISOR_memory_op(XENMEM_populate_physmap,
    4.60  				 &reservation) != 1)
    4.61  		goto fail;
    4.62  
    4.63 @@ -353,9 +369,8 @@ int xen_create_contiguous_region(
    4.64  	for (i = 0; i < (1<<order); i++) {
    4.65  		BUG_ON(HYPERVISOR_update_va_mapping(
    4.66  			vstart + (i*PAGE_SIZE),
    4.67 -			pfn_pte_ma(mfn+i, PAGE_KERNEL), 0));
    4.68 -		xen_machphys_update(mfn+i, (__pa(vstart)>>PAGE_SHIFT)+i);
    4.69 -		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn+i);
    4.70 +			pfn_pte_ma(frame+i, PAGE_KERNEL), 0));
    4.71 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame+i);
    4.72  	}
    4.73  
    4.74  	flush_tlb_all();
    4.75 @@ -371,13 +386,13 @@ int xen_create_contiguous_region(
    4.76  	reservation.address_bits = 0;
    4.77  
    4.78  	for (i = 0; i < (1<<order); i++) {
    4.79 +		frame = (__pa(vstart) >> PAGE_SHIFT) + i;
    4.80  		BUG_ON(HYPERVISOR_memory_op(
    4.81 -			XENMEM_increase_reservation, &reservation) != 1);
    4.82 +			XENMEM_populate_physmap, &reservation) != 1);
    4.83  		BUG_ON(HYPERVISOR_update_va_mapping(
    4.84  			vstart + (i*PAGE_SIZE),
    4.85 -			pfn_pte_ma(mfn, PAGE_KERNEL), 0));
    4.86 -		xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
    4.87 -		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn);
    4.88 +			pfn_pte_ma(frame, PAGE_KERNEL), 0));
    4.89 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
    4.90  	}
    4.91  
    4.92  	flush_tlb_all();
    4.93 @@ -393,9 +408,9 @@ void xen_destroy_contiguous_region(unsig
    4.94  	pud_t         *pud; 
    4.95  	pmd_t         *pmd;
    4.96  	pte_t         *pte;
    4.97 -	unsigned long  mfn, i, flags;
    4.98 +	unsigned long  frame, i, flags;
    4.99  	struct xen_memory_reservation reservation = {
   4.100 -		.extent_start = &mfn,
   4.101 +		.extent_start = &frame,
   4.102  		.nr_extents   = 1,
   4.103  		.extent_order = 0,
   4.104  		.domid        = DOMID_SELF
   4.105 @@ -413,7 +428,7 @@ void xen_destroy_contiguous_region(unsig
   4.106  		pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
   4.107  		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
   4.108  		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
   4.109 -		mfn = pte_mfn(*pte);
   4.110 +		frame = pte_mfn(*pte);
   4.111  		BUG_ON(HYPERVISOR_update_va_mapping(
   4.112  			vstart + (i*PAGE_SIZE), __pte_ma(0), 0));
   4.113  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
   4.114 @@ -424,19 +439,32 @@ void xen_destroy_contiguous_region(unsig
   4.115  
   4.116  	/* 2. Map new pages in place of old pages. */
   4.117  	for (i = 0; i < (1<<order); i++) {
   4.118 +		frame = (__pa(vstart) >> PAGE_SHIFT) + i;
   4.119  		BUG_ON(HYPERVISOR_memory_op(
   4.120 -			XENMEM_increase_reservation, &reservation) != 1);
   4.121 +			XENMEM_populate_physmap, &reservation) != 1);
   4.122  		BUG_ON(HYPERVISOR_update_va_mapping(
   4.123  			vstart + (i*PAGE_SIZE),
   4.124 -			pfn_pte_ma(mfn, PAGE_KERNEL), 0));
   4.125 -		xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
   4.126 -		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn);
   4.127 +			pfn_pte_ma(frame, PAGE_KERNEL), 0));
   4.128 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
   4.129  	}
   4.130  
   4.131  	flush_tlb_all();
   4.132  
   4.133  	balloon_unlock(flags);
   4.134  }
   4.135 +#else
   4.136 +int xen_create_contiguous_region(
   4.137 +       unsigned long vstat, unsigned int order, unsigned int address_bits)
   4.138 +{
   4.139 +       if (order >= 1)
   4.140 +               BUG();
   4.141 +       return 0;
   4.142 +}
   4.143 +
   4.144 +void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
   4.145 +{
   4.146 +}
   4.147 +#endif
   4.148  
   4.149  #ifdef __i386__
   4.150  int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Thu Jan 26 19:52:18 2006 +0100
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Fri Jan 27 21:23:06 2006 +0100
     5.3 @@ -68,7 +68,7 @@ static pmd_t * __init one_md_table_init(
     5.4  		
     5.5  #ifdef CONFIG_X86_PAE
     5.6  	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
     5.7 -	make_lowmem_page_readonly(pmd_table);
     5.8 +	make_lowmem_mmu_page_readonly(pmd_table);
     5.9  	set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
    5.10  	pud = pud_offset(pgd, 0);
    5.11  	if (pmd_table != pmd_offset(pud, 0)) 
    5.12 @@ -89,7 +89,7 @@ static pte_t * __init one_page_table_ini
    5.13  {
    5.14  	if (pmd_none(*pmd)) {
    5.15  		pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
    5.16 -		make_lowmem_page_readonly(page_table);
    5.17 +		make_lowmem_mmu_page_readonly(page_table);
    5.18  		set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
    5.19  		if (page_table != pte_offset_kernel(pmd, 0))
    5.20  			BUG();	
    5.21 @@ -644,6 +644,17 @@ void __init mem_init(void)
    5.22  		totalram_pages++;
    5.23  	}
    5.24  
    5.25 +        /* Make the Xen hole reserved. */
    5.26 +        unsigned long hole_start, hole_size;
    5.27 +        hole_size = xen_pfn_hole_size();
    5.28 +        hole_start = xen_pfn_hole_start();
    5.29 +        for (pfn = hole_start; pfn < hole_start + hole_size; pfn++) {
    5.30 +                printk("<0>Reserve %lx for hole.\n",
    5.31 +                       pfn);
    5.32 +                SetPageReserved(pfn_to_page(pfn));
    5.33 +                BUG_ON(!PageReserved(pfn_to_page(pfn)));
    5.34 +        }
    5.35 +
    5.36  	reservedpages = 0;
    5.37  	for (tmp = 0; tmp < max_low_pfn; tmp++)
    5.38  		/*
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Thu Jan 26 19:52:18 2006 +0100
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Jan 27 21:23:06 2006 +0100
     6.3 @@ -24,6 +24,7 @@
     6.4  #include <asm/io.h>
     6.5  #include <asm/mmu_context.h>
     6.6  
     6.7 +#include <asm-xen/features.h>
     6.8  #include <asm-xen/foreign_page.h>
     6.9  #include <asm/hypervisor.h>
    6.10  
    6.11 @@ -198,7 +199,7 @@ pte_t *pte_alloc_one_kernel(struct mm_st
    6.12  {
    6.13  	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
    6.14  	if (pte)
    6.15 -		make_lowmem_page_readonly(pte);
    6.16 +		make_lowmem_mmu_page_readonly(pte);
    6.17  	return pte;
    6.18  }
    6.19  
    6.20 @@ -316,6 +317,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
    6.21  
    6.22  	pgd_test_and_unpin(pgd);
    6.23  
    6.24 +	memset(pgd, 0, 10);
    6.25  	if (PTRS_PER_PMD == 1 || !pgd)
    6.26  		return pgd;
    6.27  
    6.28 @@ -344,7 +346,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
    6.29  			pmd_t *kpmd = pmd_offset(kpud, v);
    6.30  			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
    6.31  			memcpy(pmd, kpmd, PAGE_SIZE);
    6.32 -			make_lowmem_page_readonly(pmd);
    6.33 +			make_lowmem_mmu_page_readonly(pmd);
    6.34  		}
    6.35  		pgd_list_add(pgd);
    6.36  		spin_unlock_irqrestore(&pgd_lock, flags);
    6.37 @@ -378,7 +380,7 @@ void pgd_free(pgd_t *pgd)
    6.38  			spin_unlock_irqrestore(&pgd_lock, flags);
    6.39  			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
    6.40  				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
    6.41 -				make_lowmem_page_writable(pmd);
    6.42 +				make_lowmem_mmu_page_writable(pmd);
    6.43  				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
    6.44  				kmem_cache_free(pmd_cache, pmd);
    6.45  			}
    6.46 @@ -388,27 +390,37 @@ void pgd_free(pgd_t *pgd)
    6.47  	kmem_cache_free(pgd_cache, pgd);
    6.48  }
    6.49  
    6.50 -#ifndef CONFIG_XEN_SHADOW_MODE
    6.51 +
    6.52  void make_lowmem_page_readonly(void *va)
    6.53  {
    6.54 -	pte_t *pte = virt_to_ptep(va);
    6.55 -	int rc = HYPERVISOR_update_va_mapping(
    6.56 +	pte_t *pte;
    6.57 +	int rc;
    6.58 +
    6.59 +	pte = virt_to_ptep(va);
    6.60 +	rc = HYPERVISOR_update_va_mapping(
    6.61  		(unsigned long)va, pte_wrprotect(*pte), 0);
    6.62  	BUG_ON(rc);
    6.63  }
    6.64  
    6.65  void make_lowmem_page_writable(void *va)
    6.66  {
    6.67 -	pte_t *pte = virt_to_ptep(va);
    6.68 -	int rc = HYPERVISOR_update_va_mapping(
    6.69 +	pte_t *pte;
    6.70 +	int rc;
    6.71 +
    6.72 +	pte = virt_to_ptep(va);
    6.73 +	rc = HYPERVISOR_update_va_mapping(
    6.74  		(unsigned long)va, pte_mkwrite(*pte), 0);
    6.75  	BUG_ON(rc);
    6.76  }
    6.77  
    6.78 +
    6.79  void make_page_readonly(void *va)
    6.80  {
    6.81 -	pte_t *pte = virt_to_ptep(va);
    6.82 -	int rc = HYPERVISOR_update_va_mapping(
    6.83 +	pte_t *pte;
    6.84 +	int rc;
    6.85 +
    6.86 +	pte = virt_to_ptep(va);
    6.87 +	rc = HYPERVISOR_update_va_mapping(
    6.88  		(unsigned long)va, pte_wrprotect(*pte), 0);
    6.89  	if (rc) /* fallback? */
    6.90  		xen_l1_entry_update(pte, pte_wrprotect(*pte));
    6.91 @@ -426,8 +438,11 @@ void make_page_readonly(void *va)
    6.92  
    6.93  void make_page_writable(void *va)
    6.94  {
    6.95 -	pte_t *pte = virt_to_ptep(va);
    6.96 -	int rc = HYPERVISOR_update_va_mapping(
    6.97 +	pte_t *pte;
    6.98 +	int rc;
    6.99 +
   6.100 +	pte = virt_to_ptep(va);
   6.101 +	rc = HYPERVISOR_update_va_mapping(
   6.102  		(unsigned long)va, pte_mkwrite(*pte), 0);
   6.103  	if (rc) /* fallback? */
   6.104  		xen_l1_entry_update(pte, pte_mkwrite(*pte));
   6.105 @@ -441,7 +456,7 @@ void make_page_writable(void *va)
   6.106  	}
   6.107  }
   6.108  
   6.109 -void make_pages_readonly(void *va, unsigned int nr)
   6.110 +void make_pages_readonly(void *va, unsigned nr)
   6.111  {
   6.112  	while (nr-- != 0) {
   6.113  		make_page_readonly(va);
   6.114 @@ -449,14 +464,57 @@ void make_pages_readonly(void *va, unsig
   6.115  	}
   6.116  }
   6.117  
   6.118 -void make_pages_writable(void *va, unsigned int nr)
   6.119 +void make_pages_writable(void *va, unsigned nr)
   6.120  {
   6.121  	while (nr-- != 0) {
   6.122  		make_page_writable(va);
   6.123  		va = (void *)((unsigned long)va + PAGE_SIZE);
   6.124  	}
   6.125  }
   6.126 -#endif /* CONFIG_XEN_SHADOW_MODE */
   6.127 +
   6.128 +#ifndef CONFIG_XEN_SHADOW_MODE
   6.129 +void make_lowmem_mmu_page_readonly(void *va)
   6.130 +{
   6.131 +	if (xen_feature(writable_mmu_structures))
   6.132 +		return;
   6.133 +	make_lowmem_page_readonly(va);
   6.134 +}
   6.135 +
   6.136 +void make_lowmem_mmu_page_writable(void *va)
   6.137 +{
   6.138 +	if (xen_feature(writable_mmu_structures))
   6.139 +		return;
   6.140 +	make_lowmem_page_writable(va);
   6.141 +}
   6.142 +
   6.143 +void make_mmu_page_readonly(void *va)
   6.144 +{
   6.145 +	if (xen_feature(writable_mmu_structures))
   6.146 +		return;
   6.147 +	make_page_readonly(va);
   6.148 +}
   6.149 +
   6.150 +void make_mmu_page_writable(void *va)
   6.151 +{
   6.152 +	if (xen_feature(writable_mmu_structures))
   6.153 +		return;
   6.154 +	make_page_writable(va);
   6.155 +}
   6.156 +
   6.157 +void make_mmu_pages_readonly(void *va, unsigned int nr)
   6.158 +{
   6.159 +	if (xen_feature(writable_mmu_structures))
   6.160 +		return;
   6.161 +	make_pages_readonly(va, nr);
   6.162 +}
   6.163 +
   6.164 +void make_mmu_pages_writable(void *va, unsigned int nr)
   6.165 +{
   6.166 +	if (xen_feature(writable_mmu_structures))
   6.167 +		return;
   6.168 +	make_pages_writable(va, nr);
   6.169 +}
   6.170 +#endif
   6.171  
   6.172  static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
   6.173  {
   6.174 @@ -507,7 +565,8 @@ static void pgd_walk(pgd_t *pgd_base, pg
   6.175  
   6.176  static void __pgd_pin(pgd_t *pgd)
   6.177  {
   6.178 -	pgd_walk(pgd, PAGE_KERNEL_RO);
   6.179 +	if (!xen_feature(writable_mmu_structures))
   6.180 +		pgd_walk(pgd, PAGE_KERNEL_RO);
   6.181  	xen_pgd_pin(__pa(pgd));
   6.182  	set_bit(PG_pinned, &virt_to_page(pgd)->flags);
   6.183  }
   6.184 @@ -515,7 +574,8 @@ static void __pgd_pin(pgd_t *pgd)
   6.185  static void __pgd_unpin(pgd_t *pgd)
   6.186  {
   6.187  	xen_pgd_unpin(__pa(pgd));
   6.188 -	pgd_walk(pgd, PAGE_KERNEL);
   6.189 +	if (!xen_feature(writable_mmu_structures))
   6.190 +		pgd_walk(pgd, PAGE_KERNEL);
   6.191  	clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
   6.192  }
   6.193  
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile	Thu Jan 26 19:52:18 2006 +0100
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile	Fri Jan 27 21:23:06 2006 +0100
     7.3 @@ -11,7 +11,7 @@ CPPFLAGS_vmlinux.lds += -U$(XENARCH)
     7.4  
     7.5  extra-y += vmlinux.lds
     7.6  
     7.7 -obj-y   := evtchn.o reboot.o gnttab.o
     7.8 +obj-y   := evtchn.o reboot.o gnttab.o features.o
     7.9  
    7.10  obj-$(CONFIG_PROC_FS) += xen_proc.o
    7.11  obj-$(CONFIG_NET)     += skbuff.o
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/features.c	Fri Jan 27 21:23:06 2006 +0100
     8.3 @@ -0,0 +1,29 @@
     8.4 +/******************************************************************************
     8.5 + * features.c
     8.6 + *
     8.7 + * Xen feature flags.
     8.8 + *
     8.9 + * Copyright (c) 2006, Ian Campbell
    8.10 + */
    8.11 +#include <linux/types.h>
    8.12 +#include <linux/cache.h>
    8.13 +#include <asm/hypervisor.h>
    8.14 +#include <asm-xen/features.h>
    8.15 +
    8.16 +/* When we rebase to a more recent version of Linux we can use __read_mostly here. */
    8.17 +unsigned long xen_features[XENFEAT_NR_SUBMAPS] __cacheline_aligned;
    8.18 +
    8.19 +void setup_xen_features(void)
    8.20 +{
    8.21 +     uint32_t *flags = (uint32_t *)&xen_features[0];
    8.22 +     xen_feature_info_t fi;
    8.23 +     int i;
    8.24 +
    8.25 +     for (i=0; i<XENFEAT_NR_SUBMAPS; i++) {
    8.26 +	  fi.submap_idx = i;
    8.27 +	  if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
    8.28 +	       break;
    8.29 +	  flags[i] = fi.submap;
    8.30 +     }
    8.31 +}
    8.32 +
     9.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Thu Jan 26 19:52:18 2006 +0100
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Fri Jan 27 21:23:06 2006 +0100
     9.3 @@ -201,25 +201,22 @@ gnttab_end_foreign_access(grant_ref_t re
     9.4  }
     9.5  
     9.6  int
     9.7 -gnttab_grant_foreign_transfer(domid_t domid)
     9.8 +gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
     9.9  {
    9.10  	int ref;
    9.11  
    9.12  	if (unlikely((ref = get_free_entry()) == -1))
    9.13  		return -ENOSPC;
    9.14 -
    9.15 -	shared[ref].frame = 0;
    9.16 -	shared[ref].domid = domid;
    9.17 -	wmb();
    9.18 -	shared[ref].flags = GTF_accept_transfer;
    9.19 +	gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
    9.20  
    9.21  	return ref;
    9.22  }
    9.23  
    9.24  void
    9.25 -gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
    9.26 +gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
    9.27 +				  unsigned long pfn)
    9.28  {
    9.29 -	shared[ref].frame = 0;
    9.30 +	shared[ref].frame = pfn;
    9.31  	shared[ref].domid = domid;
    9.32  	wmb();
    9.33  	shared[ref].flags = GTF_accept_transfer;
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Thu Jan 26 19:52:18 2006 +0100
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Jan 27 21:23:06 2006 +0100
    10.3 @@ -74,6 +74,7 @@ static DECLARE_WORK(shutdown_work, __shu
    10.4  #endif
    10.5  
    10.6  
    10.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    10.8  static int __do_suspend(void *ignore)
    10.9  {
   10.10  	int i, j, k, fpp;
   10.11 @@ -216,6 +217,13 @@ static int __do_suspend(void *ignore)
   10.12  
   10.13  	return err;
   10.14  }
   10.15 +#else
   10.16 +static int __do_suspend(void *ignore)
   10.17 +{
   10.18 +	printk(KERN_WARNING "Don't do suspend in shadow mode\n");
   10.19 +	return -EOPNOTSUPP;
   10.20 +}
   10.21 +#endif
   10.22  
   10.23  static int shutdown_process(void *__unused)
   10.24  {
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c	Thu Jan 26 19:52:18 2006 +0100
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c	Fri Jan 27 21:23:06 2006 +0100
    12.3 @@ -65,8 +65,8 @@ static int alloc_ldt(mm_context_t *pc, u
    12.4  
    12.5  		preempt_disable();
    12.6  #endif
    12.7 -		make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
    12.8 -				    PAGE_SIZE);
    12.9 +		make_mmu_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
   12.10 +					PAGE_SIZE);
   12.11  		load_LDT(pc);
   12.12  #ifdef CONFIG_SMP
   12.13  		mask = cpumask_of_cpu(smp_processor_id());
   12.14 @@ -76,7 +76,7 @@ static int alloc_ldt(mm_context_t *pc, u
   12.15  #endif
   12.16  	}
   12.17  	if (oldsize) {
   12.18 -		make_pages_writable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
   12.19 +		make_mmu_pages_writable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
   12.20  			PAGE_SIZE);
   12.21  		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
   12.22  			vfree(oldldt);
   12.23 @@ -92,8 +92,8 @@ static inline int copy_ldt(mm_context_t 
   12.24  	if (err < 0)
   12.25  		return err;
   12.26  	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
   12.27 -	make_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
   12.28 -			    PAGE_SIZE);
   12.29 +	make_mmu_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
   12.30 +				PAGE_SIZE);
   12.31  	return 0;
   12.32  }
   12.33  
   12.34 @@ -131,9 +131,9 @@ void destroy_context(struct mm_struct *m
   12.35  	if (mm->context.size) {
   12.36  		if (mm == current->active_mm)
   12.37  			clear_LDT();
   12.38 -		make_pages_writable(mm->context.ldt, 
   12.39 -				    (mm->context.size * LDT_ENTRY_SIZE) /
   12.40 -				    PAGE_SIZE);
   12.41 +		make_mmu_pages_writable(mm->context.ldt,
   12.42 +					(mm->context.size * LDT_ENTRY_SIZE) /
   12.43 +					PAGE_SIZE);
   12.44  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
   12.45  			vfree(mm->context.ldt);
   12.46  		else
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Thu Jan 26 19:52:18 2006 +0100
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Fri Jan 27 21:23:06 2006 +0100
    13.3 @@ -63,6 +63,7 @@
    13.4  #include "setup_arch_pre.h"
    13.5  #include <asm/hypervisor.h>
    13.6  #include <asm-xen/xen-public/nmi.h>
    13.7 +#include <asm-xen/features.h>
    13.8  #define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
    13.9  #define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
   13.10  #define end_pfn_map end_pfn
   13.11 @@ -587,6 +588,8 @@ void __init setup_arch(char **cmdline_p)
   13.12  
   13.13  #endif
   13.14  
   13.15 +	setup_xen_features();
   13.16 +
   13.17  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
   13.18  			     VMASST_TYPE_writable_pagetables);
   13.19  
    14.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c	Thu Jan 26 19:52:18 2006 +0100
    14.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c	Fri Jan 27 21:23:06 2006 +0100
    14.3 @@ -141,7 +141,7 @@ void __cpuinit cpu_gdt_init(struct desc_
    14.4  	     va < gdt_descr->address + gdt_descr->size;
    14.5  	     va += PAGE_SIZE, f++) {
    14.6  		frames[f] = virt_to_mfn(va);
    14.7 -		make_page_readonly((void *)va);
    14.8 +		make_mmu_page_readonly((void *)va);
    14.9  	}
   14.10  	if (HYPERVISOR_set_gdt(frames, gdt_descr->size /
   14.11                                 sizeof (struct desc_struct)))
    15.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Thu Jan 26 19:52:18 2006 +0100
    15.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Fri Jan 27 21:23:06 2006 +0100
    15.3 @@ -40,6 +40,8 @@
    15.4  #include <asm/proto.h>
    15.5  #include <asm/smp.h>
    15.6  
    15.7 +#include <asm-xen/features.h>
    15.8 +
    15.9  #ifndef Dprintk
   15.10  #define Dprintk(x...)
   15.11  #endif
   15.12 @@ -66,12 +68,15 @@ extern unsigned long start_pfn;
   15.13  	(((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +	\
   15.14  	__START_KERNEL_map)))
   15.15  
   15.16 -static void early_make_page_readonly(void *va)
   15.17 +static void early_make_mmu_page_readonly(void *va)
   15.18  {
   15.19  	unsigned long addr, _va = (unsigned long)va;
   15.20  	pte_t pte, *ptep;
   15.21  	unsigned long *page = (unsigned long *) init_level4_pgt;
   15.22  
   15.23 +	if (xen_feature(writable_mmu_structures))
   15.24 +		return;
   15.25 +
   15.26  	addr = (unsigned long) page[pgd_index(_va)];
   15.27  	addr_to_page(addr, page);
   15.28  
   15.29 @@ -88,11 +93,14 @@ static void early_make_page_readonly(voi
   15.30  		BUG();
   15.31  }
   15.32  
   15.33 -void make_page_readonly(void *va)
   15.34 +void make_mmu_page_readonly(void *va)
   15.35  {
   15.36  	pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
   15.37  	unsigned long addr = (unsigned long) va;
   15.38  
   15.39 +	if (xen_feature(writable_mmu_structures))
   15.40 +		return;
   15.41 +
   15.42  	pgd = pgd_offset_k(addr);
   15.43  	pud = pud_offset(pgd, addr);
   15.44  	pmd = pmd_offset(pud, addr);
   15.45 @@ -103,14 +111,17 @@ void make_page_readonly(void *va)
   15.46  		xen_l1_entry_update(ptep, pte); /* fallback */
   15.47  
   15.48  	if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
   15.49 -		make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT));
   15.50 +		make_mmu_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT));
   15.51  }
   15.52  
   15.53 -void make_page_writable(void *va)
   15.54 +void make_mmu_page_writable(void *va)
   15.55  {
   15.56  	pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
   15.57  	unsigned long addr = (unsigned long) va;
   15.58  
   15.59 +	if (xen_feature(writable_mmu_structures))
   15.60 +		return;
   15.61 +
   15.62  	pgd = pgd_offset_k(addr);
   15.63  	pud = pud_offset(pgd, addr);
   15.64  	pmd = pmd_offset(pud, addr);
   15.65 @@ -121,21 +132,26 @@ void make_page_writable(void *va)
   15.66  		xen_l1_entry_update(ptep, pte); /* fallback */
   15.67  
   15.68  	if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
   15.69 -		make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT));
   15.70 +		make_mmu_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT));
   15.71  }
   15.72  
   15.73 -void make_pages_readonly(void *va, unsigned nr)
   15.74 +void make_mmu_pages_readonly(void *va, unsigned nr)
   15.75  {
   15.76 +	if (xen_feature(writable_mmu_structures))
   15.77 +		return;
   15.78 +
   15.79  	while (nr-- != 0) {
   15.80 -		make_page_readonly(va);
   15.81 +		make_mmu_page_readonly(va);
   15.82  		va = (void*)((unsigned long)va + PAGE_SIZE);
   15.83  	}
   15.84  }
   15.85  
   15.86 -void make_pages_writable(void *va, unsigned nr)
   15.87 +void make_mmu_pages_writable(void *va, unsigned nr)
   15.88  {
   15.89 +	if (xen_feature(writable_mmu_structures))
   15.90 +		return;
   15.91  	while (nr-- != 0) {
   15.92 -		make_page_writable(va);
   15.93 +		make_mmu_page_writable(va);
   15.94  		va = (void*)((unsigned long)va + PAGE_SIZE);
   15.95  	}
   15.96  }
   15.97 @@ -223,7 +239,7 @@ static void set_pte_phys(unsigned long v
   15.98  	pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
   15.99  	if (pud_none(*pud)) {
  15.100  		pmd = (pmd_t *) spp_getpage(); 
  15.101 -		make_page_readonly(pmd);
  15.102 +		make_mmu_page_readonly(pmd);
  15.103  		xen_pmd_pin(__pa(pmd));
  15.104  		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
  15.105  		if (pmd != pmd_offset(pud, 0)) {
  15.106 @@ -234,7 +250,7 @@ static void set_pte_phys(unsigned long v
  15.107  	pmd = pmd_offset(pud, vaddr);
  15.108  	if (pmd_none(*pmd)) {
  15.109  		pte = (pte_t *) spp_getpage();
  15.110 -		make_page_readonly(pte);
  15.111 +		make_mmu_page_readonly(pte);
  15.112  		xen_pte_pin(__pa(pte));
  15.113  		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
  15.114  		if (pte != pte_offset_kernel(pmd, 0)) {
  15.115 @@ -276,7 +292,7 @@ static void set_pte_phys_ma(unsigned lon
  15.116  	if (pud_none(*pud)) {
  15.117  
  15.118  		pmd = (pmd_t *) spp_getpage(); 
  15.119 -		make_page_readonly(pmd);
  15.120 +		make_mmu_page_readonly(pmd);
  15.121  		xen_pmd_pin(__pa(pmd));
  15.122  
  15.123  		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
  15.124 @@ -290,7 +306,7 @@ static void set_pte_phys_ma(unsigned lon
  15.125  
  15.126  	if (pmd_none(*pmd)) {
  15.127  		pte = (pte_t *) spp_getpage();
  15.128 -		make_page_readonly(pte);  
  15.129 +		make_mmu_page_readonly(pte);
  15.130  		xen_pte_pin(__pa(pte));
  15.131  
  15.132  		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
  15.133 @@ -385,6 +401,9 @@ static inline int make_readonly(unsigned
  15.134  {
  15.135  	int readonly = 0;
  15.136  
  15.137 +	if (xen_feature(writable_mmu_structures))
  15.138 +		return 0;
  15.139 +
  15.140  	/* Make old and new page tables read-only. */
  15.141  	if ((paddr >= (xen_start_info->pt_base - __START_KERNEL_map))
  15.142  	    && (paddr < ((table_start << PAGE_SHIFT) + tables_space)))
  15.143 @@ -419,7 +438,7 @@ static void __init phys_pud_init(pud_t *
  15.144  		} 
  15.145  
  15.146  		pmd = alloc_static_page(&pmd_phys);
  15.147 -		early_make_page_readonly(pmd);
  15.148 +		early_make_mmu_page_readonly(pmd);
  15.149  		xen_pmd_pin(pmd_phys);
  15.150  		set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
  15.151        		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
  15.152 @@ -448,7 +467,7 @@ static void __init phys_pud_init(pud_t *
  15.153  				__set_pte(pte, __pte(paddr | _KERNPG_TABLE));
  15.154  			}
  15.155  			pte = pte_save;
  15.156 -			early_make_page_readonly(pte);  
  15.157 +			early_make_mmu_page_readonly(pte);
  15.158  			xen_pte_pin(pte_phys);
  15.159  			set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
  15.160  		}
  15.161 @@ -497,11 +516,11 @@ void __init xen_init_pt(void)
  15.162  		      _KERNPG_TABLE | _PAGE_USER);
  15.163  	memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
  15.164  
  15.165 -	early_make_page_readonly(init_level4_pgt);
  15.166 -	early_make_page_readonly(init_level4_user_pgt);
  15.167 -	early_make_page_readonly(level3_kernel_pgt);
  15.168 -	early_make_page_readonly(level3_user_pgt);
  15.169 -	early_make_page_readonly(level2_kernel_pgt);
  15.170 +	early_make_mmu_page_readonly(init_level4_pgt);
  15.171 +	early_make_mmu_page_readonly(init_level4_user_pgt);
  15.172 +	early_make_mmu_page_readonly(level3_kernel_pgt);
  15.173 +	early_make_mmu_page_readonly(level3_user_pgt);
  15.174 +	early_make_mmu_page_readonly(level2_kernel_pgt);
  15.175  
  15.176  	xen_pgd_pin(__pa_symbol(init_level4_pgt));
  15.177  	xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
  15.178 @@ -539,7 +558,7 @@ void __init extend_init_mapping(void)
  15.179  		pmd = (pmd_t *)&page[pmd_index(va)];
  15.180  		if (pmd_none(*pmd)) {
  15.181  			pte_page = alloc_static_page(&phys);
  15.182 -			early_make_page_readonly(pte_page);
  15.183 +			early_make_mmu_page_readonly(pte_page);
  15.184  			xen_pte_pin(phys);
  15.185  			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
  15.186  		} else {
  15.187 @@ -586,7 +605,7 @@ void __init init_memory_mapping(unsigned
  15.188  	for (; start < end; start = next) {
  15.189  		unsigned long pud_phys; 
  15.190  		pud_t *pud = alloc_static_page(&pud_phys);
  15.191 -		early_make_page_readonly(pud);
  15.192 +		early_make_mmu_page_readonly(pud);
  15.193  		xen_pud_pin(pud_phys);
  15.194  		next = start + PGDIR_SIZE;
  15.195  		if (next > end) 
  15.196 @@ -791,11 +810,11 @@ void free_initmem(void)
  15.197  		set_page_count(virt_to_page(addr), 1);
  15.198  		memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
  15.199  		xen_pte_unpin(__pa(addr));
  15.200 -		make_page_writable(__va(__pa(addr)));
  15.201 +		make_mmu_page_writable(__va(__pa(addr)));
  15.202  		/*
  15.203  		 * Make pages from __PAGE_OFFSET address as well
  15.204  		 */
  15.205 -		make_page_writable((void *)addr);
  15.206 +		make_mmu_page_writable((void *)addr);
  15.207  		free_page(addr);
  15.208  		totalram_pages++;
  15.209  	}
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Thu Jan 26 19:52:18 2006 +0100
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Jan 27 21:23:06 2006 +0100
    16.3 @@ -107,9 +107,27 @@ static struct timer_list balloon_timer;
    16.4  #define WPRINTK(fmt, args...) \
    16.5  	printk(KERN_WARNING "xen_mem: " fmt, ##args)
    16.6  
    16.7 +static int page_is_xen_hole(unsigned long pfn)
    16.8 +{
    16.9 +	static unsigned long hole_start, hole_len = -1;
   16.10 +	if (hole_len == -1) {
   16.11 +		hole_start = xen_pfn_hole_start();
   16.12 +		hole_len = xen_pfn_hole_size();
   16.13 +		printk("<0>Xen hole at [%lx,%lx).\n", hole_start,
   16.14 +		       hole_start + hole_len);
   16.15 +	}
   16.16 +	return pfn >= hole_start && pfn < hole_start + hole_len;
   16.17 +}
   16.18 +
   16.19  /* balloon_append: add the given page to the balloon. */
   16.20  static void balloon_append(struct page *page)
   16.21  {
   16.22 +	BUG_ON(PageReserved(page));
   16.23 +	if (page_is_xen_hole(page_to_pfn(page))) {
   16.24 +		printk("<0>Attempt to add reserved pfn %lx to balloon.\n",
   16.25 +		       page_to_pfn(page));
   16.26 +		BUG();
   16.27 +	}
   16.28  	/* Lowmem is re-populated first, so highmem pages go at list tail. */
   16.29  	if (PageHighMem(page)) {
   16.30  		list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
   16.31 @@ -139,6 +157,21 @@ static struct page *balloon_retrieve(voi
   16.32  	return page;
   16.33  }
   16.34  
   16.35 +static struct page *balloon_first_page(void)
   16.36 +{
   16.37 +	if (list_empty(&ballooned_pages))
   16.38 +		return NULL;
   16.39 +	return LIST_TO_PAGE(ballooned_pages.next);
   16.40 +}
   16.41 +
   16.42 +static struct page *balloon_next_page(struct page *page)
   16.43 +{
   16.44 +	struct list_head *next = PAGE_TO_LIST(page)->next;
   16.45 +	if (next == &ballooned_pages)
   16.46 +		return NULL;
   16.47 +	return LIST_TO_PAGE(next);
   16.48 +}
   16.49 +
   16.50  static void balloon_alarm(unsigned long unused)
   16.51  {
   16.52  	schedule_work(&balloon_worker);
   16.53 @@ -154,7 +187,7 @@ static unsigned long current_target(void
   16.54  
   16.55  static int increase_reservation(unsigned long nr_pages)
   16.56  {
   16.57 -	unsigned long *mfn_list, pfn, i, flags;
   16.58 +	unsigned long *frame_list, pfn, i, flags;
   16.59  	struct page   *page;
   16.60  	long           rc;
   16.61  	struct xen_memory_reservation reservation = {
   16.62 @@ -166,20 +199,28 @@ static int increase_reservation(unsigned
   16.63  	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
   16.64  		nr_pages = PAGE_SIZE / sizeof(unsigned long);
   16.65  
   16.66 -	mfn_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   16.67 -	if (mfn_list == NULL)
   16.68 +	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   16.69 +	if (frame_list == NULL)
   16.70  		return -ENOMEM;
   16.71  
   16.72  	balloon_lock(flags);
   16.73  
   16.74 -	reservation.extent_start = mfn_list;
   16.75 +	page = balloon_first_page();
   16.76 +	for (i = 0; i < nr_pages; i++) {
   16.77 +		BUG_ON(page == NULL);
   16.78 +		frame_list[i] = page_to_pfn(page);;
   16.79 +		BUG_ON(page_is_xen_hole(frame_list[i]));
   16.80 +		page = balloon_next_page(page);
   16.81 +	}
   16.82 +
   16.83 +	reservation.extent_start = frame_list;
   16.84  	reservation.nr_extents   = nr_pages;
   16.85  	rc = HYPERVISOR_memory_op(
   16.86 -		XENMEM_increase_reservation, &reservation);
   16.87 +		XENMEM_populate_physmap, &reservation);
   16.88  	if (rc < nr_pages) {
   16.89  		int ret;
   16.90  		/* We hit the Xen hard limit: reprobe. */
   16.91 -		reservation.extent_start = mfn_list;
   16.92 +		reservation.extent_start = frame_list;
   16.93  		reservation.nr_extents   = rc;
   16.94  		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
   16.95  				&reservation);
   16.96 @@ -193,20 +234,34 @@ static int increase_reservation(unsigned
   16.97  		BUG_ON(page == NULL);
   16.98  
   16.99  		pfn = page_to_pfn(page);
  16.100 +#ifndef CONFIG_XEN_SHADOW_MODE
  16.101 +		/* In shadow mode, Xen handles this part for us. */
  16.102  		BUG_ON(phys_to_machine_mapping_valid(pfn));
  16.103  
  16.104  		/* Update P->M and M->P tables. */
  16.105 -		set_phys_to_machine(pfn, mfn_list[i]);
  16.106 -		xen_machphys_update(mfn_list[i], pfn);
  16.107 -            
  16.108 +		set_phys_to_machine(pfn, frame_list[i]);
  16.109 +		xen_machphys_update(frame_list[i], pfn);
  16.110 +#endif
  16.111 +
  16.112 +		printk("<0>Balloon allocated %lx.\n", pfn);
  16.113  		/* Link back into the page tables if not highmem. */
  16.114  		if (pfn < max_low_pfn) {
  16.115  			int ret;
  16.116 +			pgd_t *pgd = pgd_offset_k((unsigned long)__va(pfn << PAGE_SHIFT));
  16.117 +			printk("pgd is %lx.\n", *(unsigned long *)pgd);
  16.118 +			(void)copy_from_user(&ret,
  16.119 +					     (unsigned long *)__va(pfn << PAGE_SHIFT),
  16.120 +					     4);
  16.121  			ret = HYPERVISOR_update_va_mapping(
  16.122  				(unsigned long)__va(pfn << PAGE_SHIFT),
  16.123 -				pfn_pte_ma(mfn_list[i], PAGE_KERNEL),
  16.124 +				pfn_pte_ma(frame_list[i], PAGE_KERNEL),
  16.125  				0);
  16.126  			BUG_ON(ret);
  16.127 +			printk("<0>Rehooked va; pte now %lx.\n",
  16.128 +			       *(unsigned long *)virt_to_ptep(__va(pfn << PAGE_SHIFT)));
  16.129 +			*(unsigned long *)__va(pfn << PAGE_SHIFT) =
  16.130 +				0xf001;
  16.131 +			printk("<0>Touched va.\n");
  16.132  		}
  16.133  
  16.134  		/* Relinquish the page back to the allocator. */
  16.135 @@ -221,14 +276,14 @@ static int increase_reservation(unsigned
  16.136   out:
  16.137  	balloon_unlock(flags);
  16.138  
  16.139 -	free_page((unsigned long)mfn_list);
  16.140 +	free_page((unsigned long)frame_list);
  16.141  
  16.142  	return 0;
  16.143  }
  16.144  
  16.145  static int decrease_reservation(unsigned long nr_pages)
  16.146  {
  16.147 -	unsigned long *mfn_list, pfn, i, flags;
  16.148 +	unsigned long *frame_list, pfn, i, flags;
  16.149  	struct page   *page;
  16.150  	void          *v;
  16.151  	int            need_sleep = 0;
  16.152 @@ -242,8 +297,8 @@ static int decrease_reservation(unsigned
  16.153  	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
  16.154  		nr_pages = PAGE_SIZE / sizeof(unsigned long);
  16.155  
  16.156 -	mfn_list = (unsigned long *)__get_free_page(GFP_KERNEL);
  16.157 -	if (mfn_list == NULL)
  16.158 +	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
  16.159 +	if (frame_list == NULL)
  16.160  		return -ENOMEM;
  16.161  
  16.162  	for (i = 0; i < nr_pages; i++) {
  16.163 @@ -254,7 +309,7 @@ static int decrease_reservation(unsigned
  16.164  		}
  16.165  
  16.166  		pfn = page_to_pfn(page);
  16.167 -		mfn_list[i] = pfn_to_mfn(pfn);
  16.168 +		frame_list[i] = pfn_to_mfn(pfn);
  16.169  
  16.170  		if (!PageHighMem(page)) {
  16.171  			v = phys_to_virt(pfn << PAGE_SHIFT);
  16.172 @@ -280,12 +335,12 @@ static int decrease_reservation(unsigned
  16.173  
  16.174  	/* No more mappings: invalidate P2M and add to balloon. */
  16.175  	for (i = 0; i < nr_pages; i++) {
  16.176 -		pfn = mfn_to_pfn(mfn_list[i]);
  16.177 +		pfn = mfn_to_pfn(frame_list[i]);
  16.178  		set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
  16.179  		balloon_append(pfn_to_page(pfn));
  16.180  	}
  16.181  
  16.182 -	reservation.extent_start = mfn_list;
  16.183 +	reservation.extent_start = frame_list;
  16.184  	reservation.nr_extents   = nr_pages;
  16.185  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
  16.186  	BUG_ON(ret != nr_pages);
  16.187 @@ -295,7 +350,7 @@ static int decrease_reservation(unsigned
  16.188  
  16.189  	balloon_unlock(flags);
  16.190  
  16.191 -	free_page((unsigned long)mfn_list);
  16.192 +	free_page((unsigned long)frame_list);
  16.193  
  16.194  	return need_sleep;
  16.195  }
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Thu Jan 26 19:52:18 2006 +0100
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Jan 27 21:23:06 2006 +0100
    17.3 @@ -586,7 +586,8 @@ static void network_alloc_rx_buffers(str
    17.4  		BUG_ON((signed short)ref < 0);
    17.5  		np->grant_rx_ref[id] = ref;
    17.6  		gnttab_grant_foreign_transfer_ref(ref,
    17.7 -						  np->xbdev->otherend_id);
    17.8 +						  np->xbdev->otherend_id,
    17.9 +						  __pa(skb->head) >> PAGE_SHIFT);
   17.10  		RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
   17.11  		rx_pfn_array[i] = virt_to_mfn(skb->head);
   17.12  
   17.13 @@ -613,7 +614,7 @@ static void network_alloc_rx_buffers(str
   17.14  	reservation.domid        = DOMID_SELF;
   17.15  
   17.16  	/* Tell the ballon driver what is going on. */
   17.17 -	balloon_update_driver_allowance(i);
   17.18 +//SOS22	balloon_update_driver_allowance(i);
   17.19  
   17.20  	/* Zap PTEs and give away pages in one big multicall. */
   17.21  	(void)HYPERVISOR_multicall(rx_mcl, i+1);
   17.22 @@ -802,9 +803,11 @@ static int netif_poll(struct net_device 
   17.23  		np->stats.rx_bytes += rx->status;
   17.24  
   17.25  		/* Remap the page. */
   17.26 +#ifndef CONFIG_XEN_SHADOW_MODE
   17.27  		mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
   17.28  		mmu->val  = __pa(skb->head) >> PAGE_SHIFT;
   17.29  		mmu++;
   17.30 +#endif
   17.31  		MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
   17.32  					pfn_pte_ma(mfn, PAGE_KERNEL), 0);
   17.33  		mcl++;
   17.34 @@ -815,7 +818,7 @@ static int netif_poll(struct net_device 
   17.35  	}
   17.36  
   17.37  	/* Some pages are no longer absent... */
   17.38 -	balloon_update_driver_allowance(-work_done);
   17.39 +//SOS22	balloon_update_driver_allowance(-work_done);
   17.40  
   17.41  	/* Do all the remapping work, and M2P updates, in one big hypercall. */
   17.42  	if (likely((mcl - rx_mcl) != 0)) {
   17.43 @@ -999,7 +1002,8 @@ static void network_connect(struct net_d
   17.44  		if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
   17.45  			continue;
   17.46  		gnttab_grant_foreign_transfer_ref(
   17.47 -			np->grant_rx_ref[i], np->xbdev->otherend_id);
   17.48 +			np->grant_rx_ref[i], np->xbdev->otherend_id,
   17.49 +			__pa(np->rx_skbs[i]->data) >> PAGE_SHIFT);
   17.50  		RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
   17.51  			np->grant_rx_ref[i];
   17.52  		RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/util.c	Thu Jan 26 19:52:18 2006 +0100
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/util.c	Fri Jan 27 21:23:06 2006 +0100
    18.3 @@ -1,5 +1,6 @@
    18.4  #include <linux/config.h>
    18.5  #include <linux/mm.h>
    18.6 +#include <linux/module.h>
    18.7  #include <linux/slab.h>
    18.8  #include <linux/vmalloc.h>
    18.9  #include <asm/uaccess.h>
   18.10 @@ -31,7 +32,7 @@ struct vm_struct *alloc_vm_area(unsigned
   18.11  
   18.12  	return area;
   18.13  }
   18.14 -EXPORT_SYMBOL(alloc_vm_area);
   18.15 +EXPORT_SYMBOL_GPL(alloc_vm_area);
   18.16  
   18.17  void free_vm_area(struct vm_struct *area)
   18.18  {
   18.19 @@ -40,7 +41,7 @@ void free_vm_area(struct vm_struct *area
   18.20  	BUG_ON(ret != area);
   18.21  	kfree(area);
   18.22  }
   18.23 -EXPORT_SYMBOL(free_vm_area);
   18.24 +EXPORT_SYMBOL_GPL(free_vm_area);
   18.25  
   18.26  void lock_vm_area(struct vm_struct *area)
   18.27  {
   18.28 @@ -60,13 +61,13 @@ void lock_vm_area(struct vm_struct *area
   18.29  	for (i = 0; i < area->size; i += PAGE_SIZE)
   18.30  		(void)__get_user(c, (char __user *)area->addr + i);
   18.31  }
   18.32 -EXPORT_SYMBOL(lock_vm_area);
   18.33 +EXPORT_SYMBOL_GPL(lock_vm_area);
   18.34  
   18.35  void unlock_vm_area(struct vm_struct *area)
   18.36  {
   18.37  	preempt_enable();
   18.38  }
   18.39 -EXPORT_SYMBOL(unlock_vm_area);
   18.40 +EXPORT_SYMBOL_GPL(unlock_vm_area);
   18.41  
   18.42  /*
   18.43   * Local variables:
    19.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h	Thu Jan 26 19:52:18 2006 +0100
    19.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h	Fri Jan 27 21:23:06 2006 +0100
    19.3 @@ -101,6 +101,9 @@ void xen_pte_unpin(unsigned long ptr);
    19.4  void xen_set_ldt(unsigned long ptr, unsigned long bytes);
    19.5  void xen_machphys_update(unsigned long mfn, unsigned long pfn);
    19.6  
    19.7 +unsigned long xen_pfn_hole_start(void);
    19.8 +unsigned long xen_pfn_hole_size(void);
    19.9 +
   19.10  #ifdef CONFIG_SMP
   19.11  #include <linux/cpumask.h>
   19.12  void xen_tlb_flush_all(void);
    20.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Thu Jan 26 19:52:18 2006 +0100
    20.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Fri Jan 27 21:23:06 2006 +0100
    20.3 @@ -59,8 +59,18 @@
    20.4  #define clear_user_page(page, vaddr, pg)	clear_page(page)
    20.5  #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
    20.6  
    20.7 +/* Definitions for machine and pseudophysical addresses. */
    20.8 +#ifdef CONFIG_X86_PAE
    20.9 +typedef unsigned long long paddr_t;
   20.10 +typedef unsigned long long maddr_t;
   20.11 +#else
   20.12 +typedef unsigned long paddr_t;
   20.13 +typedef unsigned long maddr_t;
   20.14 +#endif
   20.15 +
   20.16  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
   20.17  #define INVALID_P2M_ENTRY	(~0UL)
   20.18 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.19  #define FOREIGN_FRAME(m)	((m) | (1UL<<31))
   20.20  extern unsigned long *phys_to_machine_mapping;
   20.21  #define pfn_to_mfn(pfn)	\
   20.22 @@ -93,15 +103,6 @@ static inline void set_phys_to_machine(u
   20.23  	phys_to_machine_mapping[pfn] = mfn;
   20.24  }
   20.25  
   20.26 -/* Definitions for machine and pseudophysical addresses. */
   20.27 -#ifdef CONFIG_X86_PAE
   20.28 -typedef unsigned long long paddr_t;
   20.29 -typedef unsigned long long maddr_t;
   20.30 -#else
   20.31 -typedef unsigned long paddr_t;
   20.32 -typedef unsigned long maddr_t;
   20.33 -#endif
   20.34 -
   20.35  static inline maddr_t phys_to_machine(paddr_t phys)
   20.36  {
   20.37  	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
   20.38 @@ -114,7 +115,16 @@ static inline paddr_t machine_to_phys(ma
   20.39  	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
   20.40  	return phys;
   20.41  }
   20.42 -
   20.43 +#else
   20.44 +#define pfn_to_mfn(p) (p)
   20.45 +#define mfn_to_pfn(m) (m)
   20.46 +#define phys_to_machine(p) (p)
   20.47 +#define machine_to_phys(m) (m)
   20.48 +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
   20.49 +{
   20.50 +       BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
   20.51 +}
   20.52 +#endif
   20.53  /*
   20.54   * These are used to make use of C type-checking..
   20.55   */
    21.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Thu Jan 26 19:52:18 2006 +0100
    21.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Fri Jan 27 21:23:06 2006 +0100
    21.3 @@ -42,7 +42,7 @@ extern struct page *pte_alloc_one(struct
    21.4  static inline void pte_free_kernel(pte_t *pte)
    21.5  {
    21.6  	free_page((unsigned long)pte);
    21.7 -	make_page_writable(pte);
    21.8 +	make_mmu_page_writable(pte);
    21.9  }
   21.10  
   21.11  extern void pte_free(struct page *pte);
    22.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Thu Jan 26 19:52:18 2006 +0100
    22.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Fri Jan 27 21:23:06 2006 +0100
    22.3 @@ -64,7 +64,7 @@
    22.4  ({									\
    22.5  	unsigned long mfn = pte_mfn(_pte);				\
    22.6  	unsigned long pfn = mfn_to_pfn(mfn);				\
    22.7 -	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
    22.8 +	if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))             \
    22.9  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
   22.10  	pfn;								\
   22.11  })
    23.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Thu Jan 26 19:52:18 2006 +0100
    23.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Fri Jan 27 21:23:06 2006 +0100
    23.3 @@ -149,7 +149,7 @@ static inline int pte_none(pte_t pte)
    23.4  ({                                                                     \
    23.5         unsigned long mfn = pte_mfn(_pte);                              \
    23.6         unsigned long pfn = mfn_to_pfn(mfn);                            \
    23.7 -       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
    23.8 +       if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))             \
    23.9                 pfn = max_mapnr; /* special: force !pfn_valid() */      \
   23.10         pfn;                                                            \
   23.11  })
    24.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Thu Jan 26 19:52:18 2006 +0100
    24.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Jan 27 21:23:06 2006 +0100
    24.3 @@ -412,20 +412,26 @@ do {				  					\
    24.4  	ptep_set_access_flags(__vma, __address, __ptep, __entry, 1);	\
    24.5  } while (0)
    24.6  
    24.7 -#ifndef CONFIG_XEN_SHADOW_MODE
    24.8  void make_lowmem_page_readonly(void *va);
    24.9  void make_lowmem_page_writable(void *va);
   24.10  void make_page_readonly(void *va);
   24.11  void make_page_writable(void *va);
   24.12  void make_pages_readonly(void *va, unsigned int nr);
   24.13  void make_pages_writable(void *va, unsigned int nr);
   24.14 +#ifndef CONFIG_XEN_SHADOW_MODE
   24.15 +void make_lowmem_mmu_page_readonly(void *va);
   24.16 +void make_lowmem_mmu_page_writable(void *va);
   24.17 +void make_mmu_page_readonly(void *va);
   24.18 +void make_mmu_page_writable(void *va);
   24.19 +void make_mmu_pages_readonly(void *va, unsigned int nr);
   24.20 +void make_mmu_pages_writable(void *va, unsigned int nr);
   24.21  #else
   24.22 -#define make_lowmem_page_readonly(_va) ((void)0)
   24.23 -#define make_lowmem_page_writable(_va) ((void)0)
   24.24 -#define make_page_readonly(_va)        ((void)0)
   24.25 -#define make_page_writable(_va)        ((void)0)
   24.26 -#define make_pages_readonly(_va, _nr)  ((void)0)
   24.27 -#define make_pages_writable(_va, _nr)  ((void)0)
   24.28 +#define make_lowmem_mmu_page_readonly(_va) ((void)0)
   24.29 +#define make_lowmem_mmu_page_writable(_va)     ((void)0)
   24.30 +#define make_mmu_page_readonly(_va)        ((void)0)
   24.31 +#define make_mmu_page_writable(_va)            ((void)0)
   24.32 +#define make_mmu_pages_readonly(_va, _nr)  ((void)0)
   24.33 +#define make_mmu_pages_writable(_va, _nr)      ((void)0)
   24.34  #endif
   24.35  
   24.36  #define virt_to_ptep(__va)						\
    25.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgalloc.h	Thu Jan 26 19:52:18 2006 +0100
    25.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgalloc.h	Fri Jan 27 21:23:06 2006 +0100
    25.3 @@ -7,10 +7,10 @@
    25.4  #include <linux/mm.h>
    25.5  #include <asm/io.h>		/* for phys_to_virt and page_to_pseudophys */
    25.6  
    25.7 -void make_page_readonly(void *va);
    25.8 -void make_page_writable(void *va);
    25.9 -void make_pages_readonly(void *va, unsigned int nr);
   25.10 -void make_pages_writable(void *va, unsigned int nr);
   25.11 +void make_mmu_page_readonly(void *va);
   25.12 +void make_mmu_page_writable(void *va);
   25.13 +void make_mmu_pages_readonly(void *va, unsigned int nr);
   25.14 +void make_mmu_pages_writable(void *va, unsigned int nr);
   25.15  
   25.16  #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
   25.17  
   25.18 @@ -161,7 +161,7 @@ static inline pte_t *pte_alloc_one_kerne
   25.19  {
   25.20          pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   25.21          if (pte)
   25.22 -		make_page_readonly(pte);
   25.23 +		make_mmu_page_readonly(pte);
   25.24  
   25.25  	return pte;
   25.26  }
   25.27 @@ -181,7 +181,7 @@ extern __inline__ void pte_free_kernel(p
   25.28  {
   25.29  	BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
   25.30          xen_pte_unpin(__pa(pte));
   25.31 -        make_page_writable(pte);
   25.32 +        make_mmu_page_writable(pte);
   25.33  	free_page((unsigned long)pte); 
   25.34  }
   25.35  
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/features.h	Fri Jan 27 21:23:06 2006 +0100
    26.3 @@ -0,0 +1,20 @@
    26.4 +/******************************************************************************
    26.5 + * features.h
    26.6 + *
    26.7 + * Query the features reported by Xen.
    26.8 + *
    26.9 + * Copyright (c) 2006, Ian Campbell
   26.10 + */
   26.11 +
   26.12 +#ifndef __ASM_XEN_FEATURES_H__
   26.13 +#define __ASM_XEN_FEATURES_H__
   26.14 +
   26.15 +#include <asm-xen/xen-public/version.h>
   26.16 +
   26.17 +extern void setup_xen_features(void);
   26.18 +
   26.19 +extern unsigned long xen_features[XENFEAT_NR_SUBMAPS];
   26.20 +
   26.21 +#define xen_feature(flag)	(test_bit(_XENFEAT_ ## flag, xen_features))
   26.22 +
   26.23 +#endif
    27.1 --- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h	Thu Jan 26 19:52:18 2006 +0100
    27.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h	Fri Jan 27 21:23:06 2006 +0100
    27.3 @@ -50,7 +50,7 @@ int gnttab_end_foreign_access_ref(grant_
    27.4  void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
    27.5  			       unsigned long page);
    27.6  
    27.7 -int gnttab_grant_foreign_transfer(domid_t domid);
    27.8 +int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
    27.9  
   27.10  unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
   27.11  unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
   27.12 @@ -77,7 +77,8 @@ void gnttab_request_free_callback(struct
   27.13  void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
   27.14  				     unsigned long frame, int readonly);
   27.15  
   27.16 -void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid);
   27.17 +void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
   27.18 +				       unsigned long pfn);
   27.19  
   27.20  #ifdef __ia64__
   27.21  #define gnttab_map_vaddr(map) __va(map.dev_bus_addr)
    28.1 --- a/linux-2.6-xen-sparse/mm/memory.c	Thu Jan 26 19:52:18 2006 +0100
    28.2 +++ b/linux-2.6-xen-sparse/mm/memory.c	Fri Jan 27 21:23:06 2006 +0100
    28.3 @@ -291,6 +291,7 @@ pte_t fastcall *pte_alloc_map(struct mm_
    28.4  		spin_lock(&mm->page_table_lock);
    28.5  		if (!new)
    28.6  			return NULL;
    28.7 +
    28.8  		/*
    28.9  		 * Because we dropped the lock, we should re-check the
   28.10  		 * entry, as somebody else could have populated it..
    29.1 --- a/xen/arch/x86/mm.c	Thu Jan 26 19:52:18 2006 +0100
    29.2 +++ b/xen/arch/x86/mm.c	Fri Jan 27 21:23:06 2006 +0100
    29.3 @@ -1041,7 +1041,7 @@ static inline int update_l1e(l1_pgentry_
    29.4      if ( unlikely(cmpxchg_user(pl1e, o, n) != 0) ||
    29.5           unlikely(o != l1e_get_intpte(ol1e)) )
    29.6      {
    29.7 -        MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
    29.8 +        printf("Failed to update %" PRIpte " -> %" PRIpte
    29.9                  ": saw %" PRIpte,
   29.10                  l1e_get_intpte(ol1e),
   29.11                  l1e_get_intpte(nl1e),
   29.12 @@ -1058,11 +1058,16 @@ static int mod_l1_entry(l1_pgentry_t *pl
   29.13      l1_pgentry_t ol1e;
   29.14      struct domain *d = current->domain;
   29.15  
   29.16 -    if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) )
   29.17 +    shadow_sync_all(d);
   29.18 +    if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) ) {
   29.19 +        printf("copy_from_user1 failed %p, l2 %lx.\n", pl1e,
   29.20 +               *(unsigned long *)&__linear_l2_table[l2_table_offset((unsigned long)pl1e)]);
   29.21          return 0;
   29.22 -
   29.23 -    if ( unlikely(shadow_mode_refcounts(d)) )
   29.24 +    }
   29.25 +
   29.26 +    if ( unlikely(shadow_mode_refcounts(d)) ) {
   29.27          return update_l1e(pl1e, ol1e, nl1e);
   29.28 +    }
   29.29  
   29.30      if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
   29.31      {
   29.32 @@ -2540,8 +2545,10 @@ int do_update_va_mapping(unsigned long v
   29.33  
   29.34      perfc_incrc(calls_to_update_va);
   29.35  
   29.36 -    if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
   29.37 +    if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) ) {
   29.38 +        printf("Bad update_va_mapping.\n");
   29.39          return -EINVAL;
   29.40 +    }
   29.41  
   29.42      LOCK_BIGLOCK(d);
   29.43  
   29.44 @@ -2550,9 +2557,13 @@ int do_update_va_mapping(unsigned long v
   29.45      if ( unlikely(shadow_mode_enabled(d)) )
   29.46          check_pagetable(v, "pre-va"); /* debug */
   29.47  
   29.48 +    shadow_sync_all(d);
   29.49 +
   29.50      if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
   29.51 -                                val)) )
   29.52 +                                val)) ) {
   29.53 +        printf("mod_l1_entry failed.\n");
   29.54          rc = -EINVAL;
   29.55 +    }
   29.56  
   29.57      if ( likely(rc == 0) && unlikely(shadow_mode_enabled(d)) )
   29.58      {
   29.59 @@ -2569,7 +2580,8 @@ int do_update_va_mapping(unsigned long v
   29.60          }
   29.61      
   29.62          rc = shadow_do_update_va_mapping(va, val, v);
   29.63 -
   29.64 +        if (rc)
   29.65 +            printf("shadow_do_update_va_mapping says %d.\n", rc);
   29.66          check_pagetable(v, "post-va"); /* debug */
   29.67      }
   29.68  
    30.1 --- a/xen/arch/x86/shadow32.c	Thu Jan 26 19:52:18 2006 +0100
    30.2 +++ b/xen/arch/x86/shadow32.c	Fri Jan 27 21:23:06 2006 +0100
    30.3 @@ -2494,7 +2494,9 @@ static int resync_all(struct domain *d, 
    30.4              l2_pgentry_t *guest2 = guest;
    30.5              l2_pgentry_t *snapshot2 = snapshot;
    30.6              l1_pgentry_t *shadow2 = shadow;
    30.7 -            
    30.8 +
    30.9 +            printf("Update hl2 shadow.\n");
   30.10 +
   30.11              ASSERT(shadow_mode_write_all(d) || shadow_mode_wr_pt_pte(d));
   30.12              BUG_ON(!shadow_mode_refcounts(d)); // not yet implemented
   30.13  
    31.1 --- a/xen/common/kernel.c	Thu Jan 26 19:52:18 2006 +0100
    31.2 +++ b/xen/common/kernel.c	Fri Jan 27 21:23:06 2006 +0100
    31.3 @@ -13,6 +13,7 @@
    31.4  #include <asm/current.h>
    31.5  #include <public/nmi.h>
    31.6  #include <public/version.h>
    31.7 +#include <asm/shadow.h>
    31.8  
    31.9  void cmdline_parse(char *cmdline)
   31.10  {
   31.11 @@ -144,6 +145,31 @@ long do_xen_version(int cmd, void *arg)
   31.12              return -EFAULT;
   31.13          return 0;
   31.14      }
   31.15 +
   31.16 +    case XENVER_get_features:
   31.17 +    {
   31.18 +        xen_feature_info_t fi;
   31.19 +
   31.20 +        if ( copy_from_user(&fi, arg, sizeof(fi)) )
   31.21 +            return -EFAULT;
   31.22 +
   31.23 +        switch ( fi.submap_idx )
   31.24 +        {
   31.25 +        case 0:
   31.26 +            if (shadow_mode_wr_pt_pte(current->domain))
   31.27 +                fi.submap = XENFEAT_writable_mmu_structures;
   31.28 +            else
   31.29 +                fi.submap = 0;
   31.30 +            break;
   31.31 +        default:
   31.32 +            return -EINVAL;
   31.33 +        }
   31.34 +
   31.35 +        if ( copy_to_user(arg, &fi, sizeof(fi)) )
   31.36 +            return -EFAULT;
   31.37 +        return 0;
   31.38 +    }
   31.39 +
   31.40      }
   31.41  
   31.42      return -ENOSYS;
    32.1 --- a/xen/common/memory.c	Thu Jan 26 19:52:18 2006 +0100
    32.2 +++ b/xen/common/memory.c	Fri Jan 27 21:23:06 2006 +0100
    32.3 @@ -30,7 +30,7 @@ increase_reservation(
    32.4      int           *preempted)
    32.5  {
    32.6      struct pfn_info *page;
    32.7 -    unsigned int     i;
    32.8 +    unsigned long    i;
    32.9  
   32.10      if ( (extent_list != NULL) &&
   32.11           !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
   32.12 @@ -52,7 +52,7 @@ increase_reservation(
   32.13              d, extent_order, flags)) == NULL) )
   32.14          {
   32.15              DPRINTK("Could not allocate order=%d extent: "
   32.16 -                    "id=%d flags=%x (%d of %d)\n",
   32.17 +                    "id=%d flags=%x (%ld of %d)\n",
   32.18                      extent_order, d->domain_id, flags, i, nr_extents);
   32.19              return i;
   32.20          }
   32.21 @@ -65,6 +65,79 @@ increase_reservation(
   32.22  
   32.23      return nr_extents;
   32.24  }
   32.25 +
   32.26 +static long
   32.27 +populate_physmap(
   32.28 +    struct domain *d, 
   32.29 +    unsigned long *extent_list, 
   32.30 +    unsigned int   nr_extents,
   32.31 +    unsigned int   extent_order,
   32.32 +    unsigned int   flags,
   32.33 +    int           *preempted)
   32.34 +{
   32.35 +    struct pfn_info         *page;
   32.36 +    unsigned long            i, j, pfn, mfn;
   32.37 +    struct domain_mmap_cache cache1, cache2;
   32.38 +
   32.39 +    if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
   32.40 +        return 0;
   32.41 +
   32.42 +    if ( (extent_order != 0) &&
   32.43 +         !multipage_allocation_permitted(current->domain) )
   32.44 +        return 0;
   32.45 +
   32.46 +    if (shadow_mode_translate(d)) {
   32.47 +        domain_mmap_cache_init(&cache1);
   32.48 +        domain_mmap_cache_init(&cache2);
   32.49 +        shadow_lock(d);
   32.50 +    }
   32.51 +
   32.52 +    for ( i = 0; i < nr_extents; i++ )
   32.53 +    {
   32.54 +        if ( hypercall_preempt_check() )
   32.55 +        {
   32.56 +            *preempted = 1;
   32.57 +            goto out;
   32.58 +        }
   32.59 +
   32.60 +        if ( unlikely((page = alloc_domheap_pages(
   32.61 +            d, extent_order, flags)) == NULL) )
   32.62 +        {
   32.63 +            DPRINTK("Could not allocate order=%d extent: "
   32.64 +                    "id=%d flags=%x (%ld of %d)\n",
   32.65 +                    extent_order, d->domain_id, flags, i, nr_extents);
   32.66 +            goto out;
   32.67 +        }
   32.68 +
   32.69 +        mfn = page_to_pfn(page);
   32.70 +
   32.71 +        if ( unlikely(__get_user(pfn, &extent_list[i]) != 0) )
   32.72 +            goto out;
   32.73 +
   32.74 +        for ( j = 0; j < (1 << extent_order); j++ ) {
   32.75 +            printf("Populating %lx with %lx.\n",
   32.76 +                   pfn + j, mfn + j);
   32.77 +            if (shadow_mode_translate(d))
   32.78 +                set_p2m_entry(d, pfn + j, mfn + j, &cache1, &cache2);
   32.79 +            set_pfn_from_mfn(mfn + j, pfn + j);
   32.80 +        }
   32.81 +
   32.82 +        if (!shadow_mode_translate(d)) {
   32.83 +            /* Inform the domain of the new page's machine address. */ 
   32.84 +            if ( __put_user(mfn, &extent_list[i]) != 0 )
   32.85 +                goto out;
   32.86 +        }
   32.87 +    }
   32.88 +
   32.89 + out:
   32.90 +    if (shadow_mode_translate(d)) {
   32.91 +        shadow_unlock(d);
   32.92 +        domain_mmap_cache_destroy(&cache1);
   32.93 +        domain_mmap_cache_destroy(&cache2);
   32.94 +    }
   32.95 +
   32.96 +    return i;
   32.97 +}
   32.98      
   32.99  static long
  32.100  decrease_reservation(
  32.101 @@ -76,7 +149,7 @@ decrease_reservation(
  32.102      int           *preempted)
  32.103  {
  32.104      struct pfn_info *page;
  32.105 -    unsigned long    i, j, mpfn, mfn;
  32.106 +    unsigned long    i, j, gpfn, mfn;
  32.107  
  32.108      if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
  32.109          return 0;
  32.110 @@ -89,16 +162,16 @@ decrease_reservation(
  32.111              return i;
  32.112          }
  32.113  
  32.114 -        if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
  32.115 +        if ( unlikely(__get_user(gpfn, &extent_list[i]) != 0) )
  32.116              return i;
  32.117  
  32.118          for ( j = 0; j < (1 << extent_order); j++ )
  32.119          {
  32.120 -            mfn = __gpfn_to_mfn(d, mpfn + j);
  32.121 +            mfn = __gpfn_to_mfn(d, gpfn + j);
  32.122              if ( unlikely(mfn >= max_page) )
  32.123              {
  32.124 -                DPRINTK("Domain %u page number out of range (%lx >= %lx)\n", 
  32.125 -                        d->domain_id, mfn, max_page);
  32.126 +                DPRINTK("Domain %u page number out of range (%lx(%lx) >= %lx)\n", 
  32.127 +                        d->domain_id, mfn, gpfn, max_page);
  32.128                  return i;
  32.129              }
  32.130              
  32.131 @@ -115,8 +188,18 @@ decrease_reservation(
  32.132              if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
  32.133                  put_page(page);
  32.134  
  32.135 -            shadow_sync_and_drop_references(d, page);
  32.136 -
  32.137 +            if (shadow_mode_translate(d)) {
  32.138 +                struct domain_mmap_cache c1, c2;
  32.139 +                domain_mmap_cache_init(&c1);
  32.140 +                domain_mmap_cache_init(&c2);
  32.141 +                shadow_lock(d);
  32.142 +                shadow_sync_and_drop_references(d, page);
  32.143 +                set_p2m_entry(d, gpfn + j, -1, &c1, &c2);
  32.144 +                set_pfn_from_mfn(mfn + j, INVALID_M2P_ENTRY);
  32.145 +                shadow_unlock(d);
  32.146 +                domain_mmap_cache_destroy(&c1);
  32.147 +                domain_mmap_cache_destroy(&c2);
  32.148 +            }
  32.149              put_page(page);
  32.150          }
  32.151      }
  32.152 @@ -144,6 +227,7 @@ long do_memory_op(int cmd, void *arg)
  32.153      {
  32.154      case XENMEM_increase_reservation:
  32.155      case XENMEM_decrease_reservation:
  32.156 +    case XENMEM_populate_physmap:
  32.157          if ( copy_from_user(&reservation, arg, sizeof(reservation)) )
  32.158              return -EFAULT;
  32.159  
  32.160 @@ -171,14 +255,37 @@ long do_memory_op(int cmd, void *arg)
  32.161          else if ( (d = find_domain_by_id(reservation.domid)) == NULL )
  32.162              return -ESRCH;
  32.163  
  32.164 -        rc = ((op == XENMEM_increase_reservation) ?
  32.165 -              increase_reservation : decrease_reservation)(
  32.166 -                  d,
  32.167 -                  reservation.extent_start,
  32.168 -                  reservation.nr_extents,
  32.169 -                  reservation.extent_order,
  32.170 -                  flags,
  32.171 -                  &preempted);
  32.172 +        switch ( op )
  32.173 +        {
  32.174 +        case XENMEM_increase_reservation:
  32.175 +            rc = increase_reservation(
  32.176 +                d,
  32.177 +                reservation.extent_start,
  32.178 +                reservation.nr_extents,
  32.179 +                reservation.extent_order,
  32.180 +                flags,
  32.181 +                &preempted);
  32.182 +            break;
  32.183 +        case XENMEM_decrease_reservation:
  32.184 +            rc = decrease_reservation(
  32.185 +                d,
  32.186 +                reservation.extent_start,
  32.187 +                reservation.nr_extents,
  32.188 +                reservation.extent_order,
  32.189 +                flags,
  32.190 +                &preempted);
  32.191 +            break;
  32.192 +        case XENMEM_populate_physmap:
  32.193 +        default:
  32.194 +            rc = populate_physmap(
  32.195 +                d,
  32.196 +                reservation.extent_start,
  32.197 +                reservation.nr_extents,
  32.198 +                reservation.extent_order,
  32.199 +                flags,
  32.200 +                &preempted);
  32.201 +            break;
  32.202 +        }
  32.203  
  32.204          if ( unlikely(reservation.domid != DOMID_SELF) )
  32.205              put_domain(d);
    33.1 --- a/xen/include/asm-x86/shadow.h	Thu Jan 26 19:52:18 2006 +0100
    33.2 +++ b/xen/include/asm-x86/shadow.h	Fri Jan 27 21:23:06 2006 +0100
    33.3 @@ -326,7 +326,7 @@ struct out_of_sync_entry {
    33.4  #define SHADOW_SNAPSHOT_ELSEWHERE (-1L)
    33.5  
    33.6  /************************************************************************/
    33.7 -#define SHADOW_DEBUG 0
    33.8 +#define SHADOW_DEBUG 1
    33.9  #define SHADOW_VERBOSE_DEBUG 0
   33.10  #define SHADOW_VVERBOSE_DEBUG 0
   33.11  #define SHADOW_VVVERBOSE_DEBUG 0
    34.1 --- a/xen/include/public/memory.h	Thu Jan 26 19:52:18 2006 +0100
    34.2 +++ b/xen/include/public/memory.h	Fri Jan 27 21:23:06 2006 +0100
    34.3 @@ -16,11 +16,18 @@
    34.4   */
    34.5  #define XENMEM_increase_reservation 0
    34.6  #define XENMEM_decrease_reservation 1
    34.7 +#define XENMEM_populate_physmap     6
    34.8  typedef struct xen_memory_reservation {
    34.9  
   34.10      /*
   34.11 -     * MFN bases of extents to free (XENMEM_decrease_reservation).
   34.12 -     * MFN bases of extents that were allocated (XENMEM_increase_reservation).
   34.13 +     * XENMEM_increase_reservation:
   34.14 +     *   OUT: MFN bases of extents that were allocated
   34.15 +     * XENMEM_decrease_reservation:
   34.16 +     *   IN:  MFN bases of extents to free
   34.17 +     * XENMEM_populate_physmap:
   34.18 +     *   IN:  PFN bases of extents to populate with memory
   34.19 +     *   OUT: MFN bases of extents that were allocated
   34.20 +     *   (NB. This command also updates the mach_to_phys translation table)
   34.21       */
   34.22      unsigned long *extent_start;
   34.23  
   34.24 @@ -29,11 +36,10 @@ typedef struct xen_memory_reservation {
   34.25      unsigned int   extent_order;
   34.26  
   34.27      /*
   34.28 -     * XENMEM_increase_reservation: maximum # bits addressable by the user
   34.29 -     * of the allocated region (e.g., I/O devices often have a 32-bit
   34.30 -     * limitation even in 64-bit systems). If zero then the user has no
   34.31 -     * addressing restriction.
   34.32 -     * XENMEM_decrease_reservation: unused.
   34.33 +     * Mmaximum # bits addressable by the user of the allocated region (e.g., 
   34.34 +     * I/O devices often have a 32-bit limitation even in 64-bit systems). If 
   34.35 +     * zero then the user has no addressing restriction.
   34.36 +     * This field is not used by XENMEM_decrease_reservation.
   34.37       */
   34.38      unsigned int   address_bits;
   34.39  
    35.1 --- a/xen/include/public/version.h	Thu Jan 26 19:52:18 2006 +0100
    35.2 +++ b/xen/include/public/version.h	Fri Jan 27 21:23:06 2006 +0100
    35.3 @@ -39,6 +39,17 @@ typedef struct xen_platform_parameters {
    35.4      unsigned long virt_start;
    35.5  } xen_platform_parameters_t;
    35.6  
    35.7 +#define XENVER_get_features 6
    35.8 +typedef struct xen_feature_info {
    35.9 +    unsigned int submap_idx;    /* IN: which 32-bit submap to return */
   35.10 +    uint32_t     submap;        /* OUT: 32-bit submap */
   35.11 +} xen_feature_info_t;
   35.12 +
   35.13 +#define _XENFEAT_writable_mmu_structures 0
   35.14 +#define XENFEAT_writable_mmu_structures (1UL<<_XENFEAT_writable_mmu_structures)
   35.15 +
   35.16 +#define XENFEAT_NR_SUBMAPS 1
   35.17 +
   35.18  #endif /* __XEN_PUBLIC_VERSION_H__ */
   35.19  
   35.20  /*