ia64/xen-unstable

changeset 6344:3889ca17ff58

phys_to_machine_mapping array is not an array of longs.
Fix start-of-day code and FOREIGN_FRAME() macro in light
of this. Also fix pfn_to_mfn() to mask off the foreign-frame
marker bit. The few places where we rely on that bit we read
out of the array directly, rather than using the pfn_to_mfn()
accessor macro.

This fixes, among other things, booting domU on PAE with swiotlb
disabled.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Aug 23 12:30:35 2005 +0000 (2005-08-23)
parents b0d820178b81
children 0b5ee83ea35c
files linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c 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-x86_64/page.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Aug 23 09:49:12 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Aug 23 12:30:35 2005 +0000
     1.3 @@ -1575,19 +1575,20 @@ void __init setup_arch(char **cmdline_p)
     1.4  	/* Make sure we have a correctly sized P->M table. */
     1.5  	if (max_pfn != xen_start_info.nr_pages) {
     1.6  		phys_to_machine_mapping = alloc_bootmem_low_pages(
     1.7 -			max_pfn * sizeof(unsigned long));
     1.8 +			max_pfn * sizeof(unsigned int));
     1.9  
    1.10  		if (max_pfn > xen_start_info.nr_pages) {
    1.11  			/* set to INVALID_P2M_ENTRY */
    1.12  			memset(phys_to_machine_mapping, ~0,
    1.13 -				max_pfn * sizeof(unsigned long));
    1.14 +				max_pfn * sizeof(unsigned int));
    1.15  			memcpy(phys_to_machine_mapping,
    1.16 -				(unsigned long *)xen_start_info.mfn_list,
    1.17 -				xen_start_info.nr_pages * sizeof(unsigned long));
    1.18 +				(unsigned int *)xen_start_info.mfn_list,
    1.19 +				xen_start_info.nr_pages * sizeof(unsigned int));
    1.20  		} else {
    1.21  			memcpy(phys_to_machine_mapping,
    1.22 -				(unsigned long *)xen_start_info.mfn_list,
    1.23 -				max_pfn * sizeof(unsigned long));
    1.24 +				(unsigned int *)xen_start_info.mfn_list,
    1.25 +				max_pfn * sizeof(unsigned int));
    1.26 +			/* N.B. below relies on sizeof(int) == sizeof(long). */
    1.27  			if (HYPERVISOR_dom_mem_op(
    1.28  				MEMOP_decrease_reservation,
    1.29  				(unsigned long *)xen_start_info.mfn_list + max_pfn,
    1.30 @@ -1597,11 +1598,11 @@ void __init setup_arch(char **cmdline_p)
    1.31  		free_bootmem(
    1.32  			__pa(xen_start_info.mfn_list), 
    1.33  			PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
    1.34 -			sizeof(unsigned long))));
    1.35 +			sizeof(unsigned int))));
    1.36  	}
    1.37  
    1.38  	pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
    1.39 -	for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    1.40 +	for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned int)), j++ )
    1.41  	{	
    1.42  	     pfn_to_mfn_frame_list[j] = 
    1.43  		  virt_to_mfn(&phys_to_machine_mapping[i]);
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Aug 23 09:49:12 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Aug 23 12:30:35 2005 +0000
     2.3 @@ -58,7 +58,7 @@ static inline int is_local_lowmem(unsign
     2.4  	extern unsigned long max_low_pfn;
     2.5  	unsigned long mfn = address >> PAGE_SHIFT;
     2.6  	unsigned long pfn = mfn_to_pfn(mfn);
     2.7 -	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
     2.8 +	return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
     2.9  }
    2.10  
    2.11  /*
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Aug 23 09:49:12 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Aug 23 12:30:35 2005 +0000
     3.3 @@ -778,21 +778,21 @@ void __init setup_arch(char **cmdline_p)
     3.4  		/* Make sure we have a large enough P->M table. */
     3.5  		if (end_pfn > xen_start_info.nr_pages) {
     3.6  			phys_to_machine_mapping = alloc_bootmem(
     3.7 -				max_pfn * sizeof(unsigned long));
     3.8 +				max_pfn * sizeof(u32));
     3.9  			memset(phys_to_machine_mapping, ~0,
    3.10 -			       max_pfn * sizeof(unsigned long));
    3.11 +			       max_pfn * sizeof(u32));
    3.12  			memcpy(phys_to_machine_mapping,
    3.13 -			       (unsigned long *)xen_start_info.mfn_list,
    3.14 -			       xen_start_info.nr_pages * sizeof(unsigned long));
    3.15 +			       (u32 *)xen_start_info.mfn_list,
    3.16 +			       xen_start_info.nr_pages * sizeof(u32));
    3.17  			free_bootmem(
    3.18  				__pa(xen_start_info.mfn_list), 
    3.19  				PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
    3.20 -						sizeof(unsigned long))));
    3.21 +						sizeof(u32))));
    3.22  		}
    3.23  
    3.24  		pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE);
    3.25  
    3.26 -		for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    3.27 +		for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(u32)), j++ )
    3.28  		{	
    3.29  			pfn_to_mfn_frame_list[j] = 
    3.30  				virt_to_mfn(&phys_to_machine_mapping[i]);
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c	Tue Aug 23 09:49:12 2005 +0000
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c	Tue Aug 23 12:30:35 2005 +0000
     4.3 @@ -62,7 +62,7 @@ static inline int is_local_lowmem(unsign
     4.4  	extern unsigned long max_low_pfn;
     4.5  	unsigned long mfn = address >> PAGE_SHIFT;
     4.6  	unsigned long pfn = mfn_to_pfn(mfn);
     4.7 -	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
     4.8 +	return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
     4.9  }
    4.10  #elif defined(__x86_64__)
    4.11  /*
     5.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Tue Aug 23 09:49:12 2005 +0000
     5.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Tue Aug 23 12:30:35 2005 +0000
     5.3 @@ -60,9 +60,13 @@
     5.4  #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
     5.5  
     5.6  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
     5.7 +#define INVALID_P2M_ENTRY	(~0U)
     5.8 +#define FOREIGN_FRAME(m)	((m) | 0x80000000U)
     5.9  extern unsigned int *phys_to_machine_mapping;
    5.10 -#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
    5.11 -#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
    5.12 +#define pfn_to_mfn(pfn)	\
    5.13 +((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
    5.14 +#define mfn_to_pfn(mfn)	\
    5.15 +((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
    5.16  
    5.17  /* Definitions for machine and pseudophysical addresses. */
    5.18  #ifdef CONFIG_X86_PAE
     6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Tue Aug 23 09:49:12 2005 +0000
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Tue Aug 23 12:30:35 2005 +0000
     6.3 @@ -63,17 +63,15 @@ inline static void set_pte_at_sync(struc
     6.4   * 
     6.5   * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
     6.6   *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
     6.7 - *      require. In all the cases we care about, the high bit gets shifted out
     6.8 - *      (e.g., phys_to_machine()) so behaviour there is correct.
     6.9 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
    6.10 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
    6.11   */
    6.12 -#define INVALID_P2M_ENTRY (~0U)
    6.13 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
    6.14  #define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
    6.15  #define pte_pfn(_pte)							\
    6.16  ({									\
    6.17  	unsigned long mfn = pte_mfn(_pte);				\
    6.18  	unsigned long pfn = mfn_to_pfn(mfn);				\
    6.19 -	if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))		\
    6.20 +	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
    6.21  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
    6.22  	pfn;								\
    6.23  })
     7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Tue Aug 23 09:49:12 2005 +0000
     7.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Tue Aug 23 12:30:35 2005 +0000
     7.3 @@ -150,15 +150,13 @@ static inline int pte_none(pte_t pte)
     7.4  	return !pte.pte_low && !pte.pte_high;
     7.5  }
     7.6  
     7.7 -#define INVALID_P2M_ENTRY (~0U)
     7.8 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
     7.9  #define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
    7.10  		        (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
    7.11  #define pte_pfn(_pte)                                                  \
    7.12  ({                                                                     \
    7.13         unsigned long mfn = pte_mfn(_pte);                              \
    7.14         unsigned long pfn = mfn_to_pfn(mfn);                            \
    7.15 -       if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))             \
    7.16 +       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
    7.17                 pfn = max_mapnr; /* special: force !pfn_valid() */      \
    7.18         pfn;                                                            \
    7.19  })
     8.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Tue Aug 23 09:49:12 2005 +0000
     8.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Tue Aug 23 12:30:35 2005 +0000
     8.3 @@ -62,9 +62,13 @@ void copy_page(void *, void *);
     8.4  #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
     8.5  
     8.6  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
     8.7 +#define INVALID_P2M_ENTRY	(~0U)
     8.8 +#define FOREIGN_FRAME(m)	((m) | 0x80000000U)
     8.9  extern u32 *phys_to_machine_mapping;
    8.10 -#define pfn_to_mfn(_pfn) ((unsigned long) phys_to_machine_mapping[(unsigned int)(_pfn)])
    8.11 -#define mfn_to_pfn(_mfn) ((unsigned long) machine_to_phys_mapping[(unsigned int)(_mfn)])
    8.12 +#define pfn_to_mfn(pfn)	\
    8.13 +((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
    8.14 +#define mfn_to_pfn(mfn)	\
    8.15 +((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
    8.16  
    8.17  /* Definitions for machine and pseudophysical addresses. */
    8.18  typedef unsigned long paddr_t;
     9.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Tue Aug 23 09:49:12 2005 +0000
     9.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Tue Aug 23 12:30:35 2005 +0000
     9.3 @@ -300,17 +300,15 @@ inline static void set_pte_at(struct mm_
     9.4   * 
     9.5   * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
     9.6   *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
     9.7 - *      require. In all the cases we care about, the high bit gets shifted out
     9.8 - *      (e.g., phys_to_machine()) so behaviour there is correct.
     9.9 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
    9.10 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
    9.11   */
    9.12 -#define INVALID_P2M_ENTRY (~0U)
    9.13 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
    9.14  #define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
    9.15  #define pte_pfn(_pte)							\
    9.16  ({									\
    9.17  	unsigned long mfn = pte_mfn(_pte);                              \
    9.18  	unsigned pfn = mfn_to_pfn(mfn);                                 \
    9.19 -	if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))		\
    9.20 +	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
    9.21  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
    9.22  	pfn;								\
    9.23  })