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>
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>
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 })