ia64/xen-unstable

changeset 8732:c84a051d8967

Add new feature XENFEAT_auto_translated_physmap.

This feature causes the guest OS to ignore the P2M and M2P tables and
to assume that P==M.

Signed-off-by: Ian Campbell <Ian.Campbell@XenSource.com>
author Ian.Campbell@xensource.com
date Wed Feb 01 20:12:51 2006 +0000 (2006-02-01)
parents 0e87a5bd6e8b
children a450063e64ab
files linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c linux-2.6-xen-sparse/drivers/xen/core/reboot.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.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/pgtable-2level.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h xen/include/public/version.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Wed Feb 01 20:11:18 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Wed Feb 01 20:12:51 2006 +0000
     1.3 @@ -1310,7 +1310,9 @@ void __init setup_bootmem_allocator(void
     1.4  	}
     1.5  #endif
     1.6  
     1.7 -	phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list;
     1.8 +	if (!xen_feature(XENFEAT_auto_translated_physmap))
     1.9 +		phys_to_machine_mapping =
    1.10 +			(unsigned long *)xen_start_info->mfn_list;
    1.11  }
    1.12  
    1.13  /*
    1.14 @@ -1746,42 +1748,43 @@ void __init setup_arch(char **cmdline_p)
    1.15  #endif
    1.16  
    1.17  	/* Make sure we have a correctly sized P->M table. */
    1.18 -	phys_to_machine_mapping = alloc_bootmem_low_pages(
    1.19 -		max_pfn * sizeof(unsigned long));
    1.20 -	memset(phys_to_machine_mapping, ~0,
    1.21 -		max_pfn * sizeof(unsigned long));
    1.22 -	memcpy(phys_to_machine_mapping,
    1.23 -		(unsigned long *)xen_start_info->mfn_list,
    1.24 -		xen_start_info->nr_pages * sizeof(unsigned long));
    1.25 -	free_bootmem(
    1.26 -		__pa(xen_start_info->mfn_list), 
    1.27 -		PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    1.28 -		sizeof(unsigned long))));
    1.29 +	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    1.30 +		phys_to_machine_mapping = alloc_bootmem_low_pages(
    1.31 +		     max_pfn * sizeof(unsigned long));
    1.32 +		memset(phys_to_machine_mapping, ~0,
    1.33 +		       max_pfn * sizeof(unsigned long));
    1.34 +		memcpy(phys_to_machine_mapping,
    1.35 +		       (unsigned long *)xen_start_info->mfn_list,
    1.36 +		       xen_start_info->nr_pages * sizeof(unsigned long));
    1.37 +		free_bootmem(
    1.38 +		     __pa(xen_start_info->mfn_list),
    1.39 +		     PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    1.40 +				     sizeof(unsigned long))));
    1.41  
    1.42 -	/* 
    1.43 -	 * Initialise the list of the frames that specify the list of 
    1.44 -	 * frames that make up the p2m table. Used by save/restore
    1.45 -	 */
    1.46 -	pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
    1.47 -	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
    1.48 -	  virt_to_mfn(pfn_to_mfn_frame_list_list);
    1.49 -	       
    1.50 -	fpp = PAGE_SIZE/sizeof(unsigned long);
    1.51 -	for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ )
    1.52 -	{
    1.53 -	    if ( (j % fpp) == 0 )
    1.54 -	    {
    1.55 -	        k++;
    1.56 -		BUG_ON(k>=16);
    1.57 -		pfn_to_mfn_frame_list[k] = alloc_bootmem_low_pages(PAGE_SIZE);
    1.58 -		pfn_to_mfn_frame_list_list[k] = 
    1.59 -		    virt_to_mfn(pfn_to_mfn_frame_list[k]);
    1.60 -		j=0;
    1.61 -	    }
    1.62 -	    pfn_to_mfn_frame_list[k][j] = 
    1.63 -	        virt_to_mfn(&phys_to_machine_mapping[i]);
    1.64 +		/*
    1.65 +		 * Initialise the list of the frames that specify the list of
    1.66 +		 * frames that make up the p2m table. Used by save/restore
    1.67 +		 */
    1.68 +		pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
    1.69 +		HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
    1.70 +		     virt_to_mfn(pfn_to_mfn_frame_list_list);
    1.71 +
    1.72 +		fpp = PAGE_SIZE/sizeof(unsigned long);
    1.73 +		for (i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++) {
    1.74 +			if ((j % fpp) == 0) {
    1.75 +				k++;
    1.76 +				BUG_ON(k>=16);
    1.77 +				pfn_to_mfn_frame_list[k] =
    1.78 +					alloc_bootmem_low_pages(PAGE_SIZE);
    1.79 +				pfn_to_mfn_frame_list_list[k] =
    1.80 +					virt_to_mfn(pfn_to_mfn_frame_list[k]);
    1.81 +				j=0;
    1.82 +			}
    1.83 +			pfn_to_mfn_frame_list[k][j] =
    1.84 +				virt_to_mfn(&phys_to_machine_mapping[i]);
    1.85 +		}
    1.86 +		HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
    1.87  	}
    1.88 -	HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
    1.89  
    1.90  	/*
    1.91  	 * NOTE: at this point the bootmem allocator is fully available.
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Feb 01 20:11:18 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Feb 01 20:12:51 2006 +0000
     2.3 @@ -35,6 +35,7 @@
     2.4  #include <asm/pgtable.h>
     2.5  #include <asm/hypervisor.h>
     2.6  #include <xen/balloon.h>
     2.7 +#include <xen/features.h>
     2.8  #include <xen/interface/memory.h>
     2.9  #include <linux/module.h>
    2.10  #include <linux/percpu.h>
    2.11 @@ -100,6 +101,10 @@ void xen_l4_entry_update(pgd_t *ptr, pgd
    2.12  void xen_machphys_update(unsigned long mfn, unsigned long pfn)
    2.13  {
    2.14  	mmu_update_t u;
    2.15 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
    2.16 +		BUG_ON(pfn != mfn);
    2.17 +		return;
    2.18 +	}
    2.19  	u.ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
    2.20  	u.val = pfn;
    2.21  	BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
    2.22 @@ -323,6 +328,11 @@ int xen_create_contiguous_region(
    2.23  		.domid        = DOMID_SELF
    2.24  	};
    2.25  
    2.26 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
    2.27 +		BUG_ON(order >= 1);
    2.28 +		return 0;
    2.29 +	}
    2.30 +
    2.31  	scrub_pages(vstart, 1 << order);
    2.32  
    2.33  	balloon_lock(flags);
    2.34 @@ -401,6 +411,9 @@ void xen_destroy_contiguous_region(unsig
    2.35  		.domid        = DOMID_SELF
    2.36  	};
    2.37  
    2.38 +	if (xen_feature(XENFEAT_auto_translated_physmap))
    2.39 +		return;
    2.40 +
    2.41  	scrub_pages(vstart, 1 << order);
    2.42  
    2.43  	balloon_lock(flags);
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c	Wed Feb 01 20:11:18 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c	Wed Feb 01 20:12:51 2006 +0000
     3.3 @@ -177,15 +177,13 @@ EXPORT_SYMBOL(touch_pte_range);
     3.4  /*
     3.5   * Does @address reside within a non-highmem page that is local to this virtual
     3.6   * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
     3.7 - * See the comment that accompanies pte_pfn() in pgtable-2level.h to understand
     3.8 + * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
     3.9   * why this works.
    3.10   */
    3.11  static inline int is_local_lowmem(unsigned long address)
    3.12  {
    3.13  	extern unsigned long max_low_pfn;
    3.14 -	unsigned long mfn = address >> PAGE_SHIFT;
    3.15 -	unsigned long pfn = mfn_to_pfn(mfn);
    3.16 -	return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
    3.17 +	return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
    3.18  }
    3.19  
    3.20  /*
     4.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Wed Feb 01 20:11:18 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Wed Feb 01 20:12:51 2006 +0000
     4.3 @@ -522,6 +522,9 @@ static void pgd_walk(pgd_t *pgd_base, pg
     4.4  	pte_t *pte;
     4.5  	int    g, u, m;
     4.6  
     4.7 +	if (xen_feature(XENFEAT_auto_translated_physmap))
     4.8 +		return;
     4.9 +
    4.10  	for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    4.11  		if (pgd_none(*pgd))
    4.12  			continue;
     5.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Wed Feb 01 20:11:18 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Wed Feb 01 20:12:51 2006 +0000
     5.3 @@ -89,9 +89,12 @@ void __init x86_64_start_kernel(char * r
     5.4  {
     5.5  	int i;
     5.6  
     5.7 -        phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list;
     5.8 -        start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) + 
     5.9 -		xen_start_info->nr_pt_frames;
    5.10 +	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    5.11 +		phys_to_machine_mapping =
    5.12 +			(unsigned long *)xen_start_info->mfn_list;
    5.13 +		start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) +
    5.14 +			xen_start_info->nr_pt_frames;
    5.15 +	}
    5.16  
    5.17  	for (i = 0; i < 256; i++)
    5.18  		set_intr_gate(i, early_idt_handler);
     6.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Wed Feb 01 20:11:18 2006 +0000
     6.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Wed Feb 01 20:12:51 2006 +0000
     6.3 @@ -784,27 +784,6 @@ void __init setup_arch(char **cmdline_p)
     6.4  		int i, j, k, fpp;
     6.5  		unsigned long va;
     6.6  
     6.7 -		/* Make sure we have a large enough P->M table. */
     6.8 -		phys_to_machine_mapping = alloc_bootmem(
     6.9 -			end_pfn * sizeof(unsigned long));
    6.10 -		memset(phys_to_machine_mapping, ~0,
    6.11 -		       end_pfn * sizeof(unsigned long));
    6.12 -		memcpy(phys_to_machine_mapping,
    6.13 -		       (unsigned long *)xen_start_info->mfn_list,
    6.14 -		       xen_start_info->nr_pages * sizeof(unsigned long));
    6.15 -		free_bootmem(
    6.16 -			__pa(xen_start_info->mfn_list), 
    6.17 -			PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    6.18 -					sizeof(unsigned long))));
    6.19 -
    6.20 -		/* 'Initial mapping' of old p2m table must be destroyed. */
    6.21 -		for (va = xen_start_info->mfn_list;
    6.22 -		     va < (xen_start_info->mfn_list +
    6.23 -			   (xen_start_info->nr_pages*sizeof(unsigned long)));
    6.24 -		     va += PAGE_SIZE) {
    6.25 -			HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
    6.26 -		}
    6.27 -
    6.28  		/* 'Initial mapping' of initrd must be destroyed. */
    6.29  		for (va = xen_start_info->mod_start;
    6.30  		     va < (xen_start_info->mod_start+xen_start_info->mod_len);
    6.31 @@ -812,30 +791,53 @@ void __init setup_arch(char **cmdline_p)
    6.32  			HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
    6.33  		}
    6.34  
    6.35 -		/* 
    6.36 -		 * Initialise the list of the frames that specify the list of 
    6.37 -		 * frames that make up the p2m table. Used by save/restore
    6.38 -		 */
    6.39 -		pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
    6.40 -		HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
    6.41 -		  virt_to_mfn(pfn_to_mfn_frame_list_list);
    6.42 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    6.43 +			/* Make sure we have a large enough P->M table. */
    6.44 +			phys_to_machine_mapping = alloc_bootmem(
    6.45 +				end_pfn * sizeof(unsigned long));
    6.46 +			memset(phys_to_machine_mapping, ~0,
    6.47 +			       end_pfn * sizeof(unsigned long));
    6.48 +			memcpy(phys_to_machine_mapping,
    6.49 +			       (unsigned long *)xen_start_info->mfn_list,
    6.50 +			       xen_start_info->nr_pages * sizeof(unsigned long));
    6.51 +			free_bootmem(
    6.52 +				__pa(xen_start_info->mfn_list),
    6.53 +				PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
    6.54 +						sizeof(unsigned long))));
    6.55  
    6.56 -		fpp = PAGE_SIZE/sizeof(unsigned long);
    6.57 -		for ( i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++ )
    6.58 -		{
    6.59 -			if ( (j % fpp) == 0 )
    6.60 -			{
    6.61 -				k++;
    6.62 -				BUG_ON(k>=fpp);
    6.63 -				pfn_to_mfn_frame_list[k] = alloc_bootmem(PAGE_SIZE);
    6.64 -				pfn_to_mfn_frame_list_list[k] = 
    6.65 -					virt_to_mfn(pfn_to_mfn_frame_list[k]);
    6.66 -				j=0;
    6.67 +			/* Destroyed 'initial mapping' of old p2m table. */
    6.68 +			for (va = xen_start_info->mfn_list;
    6.69 +			     va < (xen_start_info->mfn_list +
    6.70 +				   (xen_start_info->nr_pages*sizeof(unsigned long)));
    6.71 +			     va += PAGE_SIZE) {
    6.72 +				HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
    6.73  			}
    6.74 -			pfn_to_mfn_frame_list[k][j] = 
    6.75 -				virt_to_mfn(&phys_to_machine_mapping[i]);
    6.76 +
    6.77 +			/*
    6.78 +			 * Initialise the list of the frames that specify the
    6.79 +			 * list of frames that make up the p2m table. Used by
    6.80 +                         * save/restore.
    6.81 +			 */
    6.82 +			pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
    6.83 +			HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
    6.84 +				virt_to_mfn(pfn_to_mfn_frame_list_list);
    6.85 +
    6.86 +			fpp = PAGE_SIZE/sizeof(unsigned long);
    6.87 +			for (i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++) {
    6.88 +				if ((j % fpp) == 0) {
    6.89 +					k++;
    6.90 +					BUG_ON(k>=fpp);
    6.91 +					pfn_to_mfn_frame_list[k] =
    6.92 +						alloc_bootmem(PAGE_SIZE);
    6.93 +					pfn_to_mfn_frame_list_list[k] =
    6.94 +						virt_to_mfn(pfn_to_mfn_frame_list[k]);
    6.95 +					j=0;
    6.96 +				}
    6.97 +				pfn_to_mfn_frame_list[k][j] =
    6.98 +					virt_to_mfn(&phys_to_machine_mapping[i]);
    6.99 +			}
   6.100 +			HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
   6.101  		}
   6.102 -		HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
   6.103  
   6.104  	}
   6.105  
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Wed Feb 01 20:11:18 2006 +0000
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Wed Feb 01 20:12:51 2006 +0000
     7.3 @@ -102,6 +102,12 @@ static int __do_suspend(void *ignore)
     7.4  	BUG_ON(smp_processor_id() != 0);
     7.5  	BUG_ON(in_interrupt());
     7.6  
     7.7 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
     7.8 +		printk(KERN_WARNING "Cannot suspend in "
     7.9 +		       "auto_translated_physmap mode.\n");
    7.10 +		return -EOPNOTSUPP;
    7.11 +	}
    7.12 +
    7.13  #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
    7.14  	if (num_online_cpus() > 1) {
    7.15  		printk(KERN_WARNING "Can't suspend SMP guests "
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Feb 01 20:11:18 2006 +0000
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Feb 01 20:12:51 2006 +0000
     8.3 @@ -236,10 +236,12 @@ static void net_rx_action(unsigned long 
     8.4  		netif->rx.req_cons++;
     8.5  		gop++;
     8.6  
     8.7 -		mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
     8.8 -			MMU_MACHPHYS_UPDATE;
     8.9 -		mmu->val = __pa(vdata) >> PAGE_SHIFT;  
    8.10 -		mmu++;
    8.11 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    8.12 +			mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
    8.13 +				MMU_MACHPHYS_UPDATE;
    8.14 +			mmu->val = __pa(vdata) >> PAGE_SHIFT;
    8.15 +			mmu++;
    8.16 +		}
    8.17  
    8.18  		__skb_queue_tail(&rxq, skb);
    8.19  
    8.20 @@ -251,14 +253,17 @@ static void net_rx_action(unsigned long 
    8.21  	if (mcl == rx_mcl)
    8.22  		return;
    8.23  
    8.24 -	mcl->op = __HYPERVISOR_mmu_update;
    8.25 -	mcl->args[0] = (unsigned long)rx_mmu;
    8.26 -	mcl->args[1] = mmu - rx_mmu;
    8.27 -	mcl->args[2] = 0;
    8.28 -	mcl->args[3] = DOMID_SELF;
    8.29 -	mcl++;
    8.30 +	mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
    8.31  
    8.32 -	mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
    8.33 +	if (mmu - rx_mmu) {
    8.34 +		mcl->op = __HYPERVISOR_mmu_update;
    8.35 +		mcl->args[0] = (unsigned long)rx_mmu;
    8.36 +		mcl->args[1] = mmu - rx_mmu;
    8.37 +		mcl->args[2] = 0;
    8.38 +		mcl->args[3] = DOMID_SELF;
    8.39 +		mcl++;
    8.40 +	}
    8.41 +
    8.42  	ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
    8.43  	BUG_ON(ret != 0);
    8.44  
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Feb 01 20:11:18 2006 +0000
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Feb 01 20:12:51 2006 +0000
     9.3 @@ -802,14 +802,17 @@ static int netif_poll(struct net_device 
     9.4  		np->stats.rx_bytes += rx->status;
     9.5  
     9.6  		/* Remap the page. */
     9.7 -		mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
     9.8 -		mmu->val  = __pa(skb->head) >> PAGE_SHIFT;
     9.9 -		mmu++;
    9.10  		MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
    9.11  					pfn_pte_ma(mfn, PAGE_KERNEL), 0);
    9.12  		mcl++;
    9.13 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
    9.14 +			mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
    9.15 +				| MMU_MACHPHYS_UPDATE;
    9.16 +			mmu->val = __pa(skb->head) >> PAGE_SHIFT;
    9.17 +			mmu++;
    9.18  
    9.19 -		set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
    9.20 +			set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
    9.21 +		}
    9.22  
    9.23  		__skb_queue_tail(&rxq, skb);
    9.24  	}
    10.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Wed Feb 01 20:11:18 2006 +0000
    10.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Wed Feb 01 20:12:51 2006 +0000
    10.3 @@ -18,6 +18,7 @@
    10.4  #include <linux/kernel.h>
    10.5  #include <asm/bug.h>
    10.6  #include <xen/interface/xen.h>
    10.7 +#include <xen/features.h>
    10.8  #include <xen/foreign_page.h>
    10.9  
   10.10  #define arch_free_page(_page,_order)			\
   10.11 @@ -61,16 +62,32 @@
   10.12  
   10.13  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
   10.14  #define INVALID_P2M_ENTRY	(~0UL)
   10.15 -#define FOREIGN_FRAME(m)	((m) | (1UL<<31))
   10.16 +#define FOREIGN_FRAME_BIT	(1UL<<31)
   10.17 +#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
   10.18 +
   10.19  extern unsigned long *phys_to_machine_mapping;
   10.20 -#define pfn_to_mfn(pfn)	\
   10.21 -(phys_to_machine_mapping[(unsigned int)(pfn)] & ~(1UL<<31))
   10.22 -#define	phys_to_machine_mapping_valid(pfn) \
   10.23 -	(phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY)
   10.24 +
   10.25 +static inline unsigned long pfn_to_mfn(unsigned long pfn)
   10.26 +{
   10.27 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   10.28 +		return pfn;
   10.29 +	return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
   10.30 +}
   10.31 +
   10.32 +static inline int phys_to_machine_mapping_valid(unsigned long pfn)
   10.33 +{
   10.34 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   10.35 +		return 1;
   10.36 +	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
   10.37 +}
   10.38 +
   10.39  static inline unsigned long mfn_to_pfn(unsigned long mfn)
   10.40  {
   10.41  	unsigned long pfn;
   10.42  
   10.43 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   10.44 +		return mfn;
   10.45 +
   10.46  	/*
   10.47  	 * The array access can fail (e.g., device space beyond end of RAM).
   10.48  	 * In such cases it doesn't matter what we return (we return garbage),
   10.49 @@ -88,8 +105,43 @@ static inline unsigned long mfn_to_pfn(u
   10.50  	return pfn;
   10.51  }
   10.52  
   10.53 +/*
   10.54 + * We detect special mappings in one of two ways:
   10.55 + *  1. If the MFN is an I/O page then Xen will set the m2p entry
   10.56 + *     to be outside our maximum possible pseudophys range.
   10.57 + *  2. If the MFN belongs to a different domain then we will certainly
   10.58 + *     not have MFN in our p2m table. Conversely, if the page is ours,
   10.59 + *     then we'll have p2m(m2p(MFN))==MFN.
   10.60 + * If we detect a special mapping then it doesn't have a 'struct page'.
   10.61 + * We force !pfn_valid() by returning an out-of-range pointer.
   10.62 + *
   10.63 + * NB. These checks require that, for any MFN that is not in our reservation,
   10.64 + * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
   10.65 + * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
   10.66 + * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
   10.67 + *
   10.68 + * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
   10.69 + *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
   10.70 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   10.71 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   10.72 + */
   10.73 +static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
   10.74 +{
   10.75 +	extern unsigned long max_mapnr;
   10.76 +	unsigned long pfn = mfn_to_pfn(mfn);
   10.77 +	if ((pfn < max_mapnr)
   10.78 +	    && !xen_feature(XENFEAT_auto_translated_physmap)
   10.79 +	    && (phys_to_machine_mapping[pfn] != mfn))
   10.80 +		return max_mapnr; /* force !pfn_valid() */
   10.81 +	return pfn;
   10.82 +}
   10.83 +
   10.84  static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
   10.85  {
   10.86 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   10.87 +		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
   10.88 +		return;
   10.89 +	}
   10.90  	phys_to_machine_mapping[pfn] = mfn;
   10.91  }
   10.92  
    11.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Wed Feb 01 20:11:18 2006 +0000
    11.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Wed Feb 01 20:12:51 2006 +0000
    11.3 @@ -39,35 +39,8 @@
    11.4  
    11.5  #define ptep_get_and_clear(mm,addr,xp)	__pte_ma(xchg(&(xp)->pte_low, 0))
    11.6  #define pte_same(a, b)		((a).pte_low == (b).pte_low)
    11.7 -/*
    11.8 - * We detect special mappings in one of two ways:
    11.9 - *  1. If the MFN is an I/O page then Xen will set the m2p entry
   11.10 - *     to be outside our maximum possible pseudophys range.
   11.11 - *  2. If the MFN belongs to a different domain then we will certainly
   11.12 - *     not have MFN in our p2m table. Conversely, if the page is ours,
   11.13 - *     then we'll have p2m(m2p(MFN))==MFN.
   11.14 - * If we detect a special mapping then it doesn't have a 'struct page'.
   11.15 - * We force !pfn_valid() by returning an out-of-range pointer.
   11.16 - *
   11.17 - * NB. These checks require that, for any MFN that is not in our reservation,
   11.18 - * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
   11.19 - * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
   11.20 - * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
   11.21 - * 
   11.22 - * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
   11.23 - *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
   11.24 - *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   11.25 - *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   11.26 - */
   11.27  #define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
   11.28 -#define pte_pfn(_pte)							\
   11.29 -({									\
   11.30 -	unsigned long mfn = pte_mfn(_pte);				\
   11.31 -	unsigned long pfn = mfn_to_pfn(mfn);				\
   11.32 -	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
   11.33 -		pfn = max_mapnr; /* special: force !pfn_valid() */	\
   11.34 -	pfn;								\
   11.35 -})
   11.36 +#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
   11.37  
   11.38  #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
   11.39  
    12.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Wed Feb 01 20:11:18 2006 +0000
    12.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Wed Feb 01 20:12:51 2006 +0000
    12.3 @@ -140,14 +140,7 @@ static inline int pte_none(pte_t pte)
    12.4  
    12.5  #define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
    12.6  		        (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
    12.7 -#define pte_pfn(_pte)                                                  \
    12.8 -({                                                                     \
    12.9 -       unsigned long mfn = pte_mfn(_pte);                              \
   12.10 -       unsigned long pfn = mfn_to_pfn(mfn);                            \
   12.11 -       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
   12.12 -               pfn = max_mapnr; /* special: force !pfn_valid() */      \
   12.13 -       pfn;                                                            \
   12.14 -})
   12.15 +#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
   12.16  
   12.17  extern unsigned long long __supported_pte_mask;
   12.18  
    13.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Wed Feb 01 20:11:18 2006 +0000
    13.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Wed Feb 01 20:12:51 2006 +0000
    13.3 @@ -4,7 +4,10 @@
    13.4  #include <linux/config.h>
    13.5  /* #include <linux/string.h> */
    13.6  #ifndef __ASSEMBLY__
    13.7 +#include <linux/kernel.h>
    13.8  #include <linux/types.h>
    13.9 +#include <asm/bug.h>
   13.10 +#include <xen/features.h>
   13.11  #endif
   13.12  #include <xen/interface/xen.h> 
   13.13  #include <xen/foreign_page.h>
   13.14 @@ -65,16 +68,32 @@ void copy_page(void *, void *);
   13.15  
   13.16  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
   13.17  #define INVALID_P2M_ENTRY	(~0UL)
   13.18 -#define FOREIGN_FRAME(m)	((m) | (1UL<<63))
   13.19 +#define FOREIGN_FRAME_BIT	(1UL<<63)
   13.20 +#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
   13.21 +
   13.22  extern unsigned long *phys_to_machine_mapping;
   13.23 -#define pfn_to_mfn(pfn)	\
   13.24 -(phys_to_machine_mapping[(unsigned int)(pfn)] & ~(1UL << 63))
   13.25 -#define	phys_to_machine_mapping_valid(pfn) \
   13.26 -	(phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY)
   13.27 +
   13.28 +static inline unsigned long pfn_to_mfn(unsigned long pfn)
   13.29 +{
   13.30 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   13.31 +		return pfn;
   13.32 +	return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
   13.33 +}
   13.34 +
   13.35 +static inline int phys_to_machine_mapping_valid(unsigned long pfn)
   13.36 +{
   13.37 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   13.38 +		return 1;
   13.39 +	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
   13.40 +}
   13.41 +
   13.42  static inline unsigned long mfn_to_pfn(unsigned long mfn)
   13.43  {
   13.44  	unsigned long pfn;
   13.45  
   13.46 +	if (xen_feature(XENFEAT_auto_translated_physmap))
   13.47 +		return mfn;
   13.48 +
   13.49  	/*
   13.50  	 * The array access can fail (e.g., device space beyond end of RAM).
   13.51  	 * In such cases it doesn't matter what we return (we return garbage),
   13.52 @@ -92,8 +111,43 @@ static inline unsigned long mfn_to_pfn(u
   13.53  	return pfn;
   13.54  }
   13.55  
   13.56 +/*
   13.57 + * We detect special mappings in one of two ways:
   13.58 + *  1. If the MFN is an I/O page then Xen will set the m2p entry
   13.59 + *     to be outside our maximum possible pseudophys range.
   13.60 + *  2. If the MFN belongs to a different domain then we will certainly
   13.61 + *     not have MFN in our p2m table. Conversely, if the page is ours,
   13.62 + *     then we'll have p2m(m2p(MFN))==MFN.
   13.63 + * If we detect a special mapping then it doesn't have a 'struct page'.
   13.64 + * We force !pfn_valid() by returning an out-of-range pointer.
   13.65 + *
   13.66 + * NB. These checks require that, for any MFN that is not in our reservation,
   13.67 + * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
   13.68 + * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
   13.69 + * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
   13.70 + *
   13.71 + * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
   13.72 + *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
   13.73 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   13.74 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   13.75 + */
   13.76 +static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
   13.77 +{
   13.78 +	unsigned long pfn = mfn_to_pfn(mfn);
   13.79 +	if ((pfn < end_pfn)
   13.80 +	    && !xen_feature(XENFEAT_auto_translated_physmap)
   13.81 +	    && (phys_to_machine_mapping[pfn] != mfn))
   13.82 +		return end_pfn; /* force !pfn_valid() */
   13.83 +	return pfn;
   13.84 +}
   13.85 +
   13.86 +
   13.87  static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
   13.88  {
   13.89 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   13.90 +		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
   13.91 +		return;
   13.92 +	}
   13.93  	phys_to_machine_mapping[pfn] = mfn;
   13.94  }
   13.95  
   13.96 @@ -208,12 +262,6 @@ static inline pgd_t __pgd(unsigned long 
   13.97  #define KERNEL_TEXT_SIZE  (40UL*1024*1024)
   13.98  #define KERNEL_TEXT_START 0xffffffff80000000UL 
   13.99  
  13.100 -#ifndef __ASSEMBLY__
  13.101 -
  13.102 -#include <asm/bug.h>
  13.103 -
  13.104 -#endif /* __ASSEMBLY__ */
  13.105 -
  13.106  #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
  13.107  
  13.108  /* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol.
    14.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Wed Feb 01 20:11:18 2006 +0000
    14.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Wed Feb 01 20:12:51 2006 +0000
    14.3 @@ -295,35 +295,8 @@ static inline unsigned long pud_bad(pud_
    14.4  
    14.5  #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
    14.6  
    14.7 -/*
    14.8 - * We detect special mappings in one of two ways:
    14.9 - *  1. If the MFN is an I/O page then Xen will set the m2p entry
   14.10 - *     to be outside our maximum possible pseudophys range.
   14.11 - *  2. If the MFN belongs to a different domain then we will certainly
   14.12 - *     not have MFN in our p2m table. Conversely, if the page is ours,
   14.13 - *     then we'll have p2m(m2p(MFN))==MFN.
   14.14 - * If we detect a special mapping then it doesn't have a 'struct page'.
   14.15 - * We force !pfn_valid() by returning an out-of-range pointer.
   14.16 - *
   14.17 - * NB. These checks require that, for any MFN that is not in our reservation,
   14.18 - * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
   14.19 - * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
   14.20 - * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
   14.21 - * 
   14.22 - * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
   14.23 - *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
   14.24 - *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   14.25 - *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   14.26 - */
   14.27  #define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
   14.28 -#define pte_pfn(_pte)							\
   14.29 -({									\
   14.30 -	unsigned long mfn = pte_mfn(_pte);                              \
   14.31 -	unsigned long pfn = mfn_to_pfn(mfn);                            \
   14.32 -	if ((pfn >= end_pfn) || (phys_to_machine_mapping[pfn] != mfn))\
   14.33 -		pfn = end_pfn; /* special: force !pfn_valid() */	\
   14.34 -	pfn;								\
   14.35 -})
   14.36 +#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
   14.37  
   14.38  #define pte_page(x)	pfn_to_page(pte_pfn(x))
   14.39  
    15.1 --- a/xen/include/public/version.h	Wed Feb 01 20:11:18 2006 +0000
    15.2 +++ b/xen/include/public/version.h	Wed Feb 01 20:12:51 2006 +0000
    15.3 @@ -47,6 +47,7 @@ typedef struct xen_feature_info {
    15.4  
    15.5  #define XENFEAT_writable_page_tables       0
    15.6  #define XENFEAT_writable_descriptor_tables 1
    15.7 +#define XENFEAT_auto_translated_physmap    2
    15.8  
    15.9  #define XENFEAT_NR_SUBMAPS 1
   15.10