# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 3889ca17ff5867d5efa19eaf25463d59dd6c8c7d
# Parent b0d820178b8109f2d081e50920aac2c6b8273af6
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@xxxxxxxxxxxxx>
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Tue Aug 23 09:49:12 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Tue Aug 23 12:30:35 2005
@@ -1575,19 +1575,20 @@
/* Make sure we have a correctly sized P->M table. */
if (max_pfn != xen_start_info.nr_pages) {
phys_to_machine_mapping = alloc_bootmem_low_pages(
- max_pfn * sizeof(unsigned long));
+ max_pfn * sizeof(unsigned int));
if (max_pfn > xen_start_info.nr_pages) {
/* set to INVALID_P2M_ENTRY */
memset(phys_to_machine_mapping, ~0,
- max_pfn * sizeof(unsigned long));
+ max_pfn * sizeof(unsigned int));
memcpy(phys_to_machine_mapping,
- (unsigned long *)xen_start_info.mfn_list,
- xen_start_info.nr_pages * sizeof(unsigned
long));
+ (unsigned int *)xen_start_info.mfn_list,
+ xen_start_info.nr_pages * sizeof(unsigned int));
} else {
memcpy(phys_to_machine_mapping,
- (unsigned long *)xen_start_info.mfn_list,
- max_pfn * sizeof(unsigned long));
+ (unsigned int *)xen_start_info.mfn_list,
+ max_pfn * sizeof(unsigned int));
+ /* N.B. below relies on sizeof(int) == sizeof(long). */
if (HYPERVISOR_dom_mem_op(
MEMOP_decrease_reservation,
(unsigned long *)xen_start_info.mfn_list +
max_pfn,
@@ -1597,11 +1598,11 @@
free_bootmem(
__pa(xen_start_info.mfn_list),
PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
- sizeof(unsigned long))));
+ sizeof(unsigned int))));
}
pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
- for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
+ for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned int)), j++ )
{
pfn_to_mfn_frame_list[j] =
virt_to_mfn(&phys_to_machine_mapping[i]);
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c Tue Aug 23 09:49:12 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c Tue Aug 23 12:30:35 2005
@@ -58,7 +58,7 @@
extern unsigned long max_low_pfn;
unsigned long mfn = address >> PAGE_SHIFT;
unsigned long pfn = mfn_to_pfn(mfn);
- return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
+ return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
}
/*
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Tue Aug 23
09:49:12 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Tue Aug 23
12:30:35 2005
@@ -778,21 +778,21 @@
/* Make sure we have a large enough P->M table. */
if (end_pfn > xen_start_info.nr_pages) {
phys_to_machine_mapping = alloc_bootmem(
- max_pfn * sizeof(unsigned long));
+ max_pfn * sizeof(u32));
memset(phys_to_machine_mapping, ~0,
- max_pfn * sizeof(unsigned long));
+ max_pfn * sizeof(u32));
memcpy(phys_to_machine_mapping,
- (unsigned long *)xen_start_info.mfn_list,
- xen_start_info.nr_pages * sizeof(unsigned long));
+ (u32 *)xen_start_info.mfn_list,
+ xen_start_info.nr_pages * sizeof(u32));
free_bootmem(
__pa(xen_start_info.mfn_list),
PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
- sizeof(unsigned long))));
+ sizeof(u32))));
}
pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE);
- for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned
long)), j++ )
+ for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(u32)), j++ )
{
pfn_to_mfn_frame_list[j] =
virt_to_mfn(&phys_to_machine_mapping[i]);
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c Tue Aug 23 09:49:12 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c Tue Aug 23 12:30:35 2005
@@ -62,7 +62,7 @@
extern unsigned long max_low_pfn;
unsigned long mfn = address >> PAGE_SHIFT;
unsigned long pfn = mfn_to_pfn(mfn);
- return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
+ return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
}
#elif defined(__x86_64__)
/*
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h Tue Aug 23
09:49:12 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h Tue Aug 23
12:30:35 2005
@@ -60,9 +60,13 @@
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+#define INVALID_P2M_ENTRY (~0U)
+#define FOREIGN_FRAME(m) ((m) | 0x80000000U)
extern unsigned int *phys_to_machine_mapping;
-#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
-#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
+#define pfn_to_mfn(pfn) \
+((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
+#define mfn_to_pfn(mfn) \
+((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h Tue Aug
23 09:49:12 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h Tue Aug
23 12:30:35 2005
@@ -63,17 +63,15 @@
*
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
- * require. In all the cases we care about, the high bit gets shifted out
- * (e.g., phys_to_machine()) so behaviour there is correct.
+ * require. In all the cases we care about, the FOREIGN_FRAME bit is
+ * masked (e.g., pfn_to_mfn()) so behaviour there is correct.
*/
-#define INVALID_P2M_ENTRY (~0U)
-#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned long pfn = mfn_to_pfn(mfn); \
- if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
+ if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h Tue Aug
23 09:49:12 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h Tue Aug
23 12:30:35 2005
@@ -150,15 +150,13 @@
return !pte.pte_low && !pte.pte_high;
}
-#define INVALID_P2M_ENTRY (~0U)
-#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
(((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned long pfn = mfn_to_pfn(mfn); \
- if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
+ if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h Tue Aug 23
09:49:12 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h Tue Aug 23
12:30:35 2005
@@ -62,9 +62,13 @@
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+#define INVALID_P2M_ENTRY (~0U)
+#define FOREIGN_FRAME(m) ((m) | 0x80000000U)
extern u32 *phys_to_machine_mapping;
-#define pfn_to_mfn(_pfn) ((unsigned long) phys_to_machine_mapping[(unsigned
int)(_pfn)])
-#define mfn_to_pfn(_mfn) ((unsigned long) machine_to_phys_mapping[(unsigned
int)(_mfn)])
+#define pfn_to_mfn(pfn) \
+((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
+#define mfn_to_pfn(mfn) \
+((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
/* Definitions for machine and pseudophysical addresses. */
typedef unsigned long paddr_t;
diff -r b0d820178b81 -r 3889ca17ff58
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Aug 23
09:49:12 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Aug 23
12:30:35 2005
@@ -300,17 +300,15 @@
*
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
- * require. In all the cases we care about, the high bit gets shifted out
- * (e.g., phys_to_machine()) so behaviour there is correct.
- */
-#define INVALID_P2M_ENTRY (~0U)
-#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
+ * require. In all the cases we care about, the FOREIGN_FRAME bit is
+ * masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned pfn = mfn_to_pfn(mfn); \
- if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
+ if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|