# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID 46e853c34a2eb537bbac8f45ba6adda949d305f0
# Parent b6ee2a730139b4e8b627c2f412fb8c46dac50185
Add new XENMEM_machphys_mapping to get info about location and
sizeof of the mach2phys table default mapping. Use this in Linux to
dynamically adapt the mfn_to_pfn() routine to undelrying hypervisor.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c | 19
++++++++++
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h | 8 +++-
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h | 17
++++++++
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h | 8 +++-
xen/arch/x86/mm.c | 14 +++++++
xen/include/public/memory.h | 14 +++++++
6 files changed, 76 insertions(+), 4 deletions(-)
diff -r b6ee2a730139 -r 46e853c34a2e
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c Tue Jun 20
13:45:23 2006 +0100
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c Tue Jun 20
14:45:46 2006 +0100
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/percpu.h>
+#include <linux/module.h>
#include <asm/processor.h>
#include <asm/proto.h>
@@ -92,8 +93,16 @@ static void __init setup_boot_cpu_data(v
boot_cpu_data.x86_mask = eax & 0xf;
}
+#include <xen/interface/memory.h>
+unsigned long *machine_to_phys_mapping;
+EXPORT_SYMBOL(machine_to_phys_mapping);
+unsigned int machine_to_phys_order;
+EXPORT_SYMBOL(machine_to_phys_order);
+
void __init x86_64_start_kernel(char * real_mode_data)
{
+ struct xen_machphys_mapping mapping;
+ unsigned long machine_to_phys_nr_ents;
char *s;
int i;
@@ -104,6 +113,16 @@ void __init x86_64_start_kernel(char * r
start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) +
xen_start_info->nr_pt_frames;
}
+
+
+ machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
+ machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+ if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
+ machine_to_phys_mapping = (unsigned long *)mapping.v_start;
+ machine_to_phys_nr_ents = mapping.max_mfn + 1;
+ }
+ while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
+ machine_to_phys_order++;
#if 0
for (i = 0; i < 256; i++)
diff -r b6ee2a730139 -r 46e853c34a2e
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Tue Jun 20
13:45:23 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Tue Jun 20
14:45:46 2006 +0100
@@ -67,6 +67,10 @@
extern unsigned long *phys_to_machine_mapping;
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int machine_to_phys_order;
+
static inline unsigned long pfn_to_mfn(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -90,7 +94,7 @@ static inline unsigned long mfn_to_pfn(u
if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn;
- if (mfn >= MACH2PHYS_NR_ENTRIES)
+ if (unlikely((mfn >> machine_to_phys_order) != 0))
return max_mapnr;
/* The array access can fail (e.g., device space beyond end of RAM). */
@@ -106,7 +110,7 @@ static inline unsigned long mfn_to_pfn(u
" .long 1b,3b\n"
".previous"
: "=r" (pfn)
- : "m" (machine_to_phys_mapping[mfn]), "ir" (max_mapnr) );
+ : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
return pfn;
}
diff -r b6ee2a730139 -r 46e853c34a2e
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Tue Jun
20 13:45:23 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Tue Jun
20 14:45:46 2006 +0100
@@ -7,6 +7,7 @@
**/
#include <xen/interface/callback.h>
+#include <xen/interface/memory.h>
static char * __init machine_specific_memory_setup(void)
{
@@ -44,9 +45,16 @@ extern void failsafe_callback(void);
extern void failsafe_callback(void);
extern void nmi(void);
+unsigned long *machine_to_phys_mapping;
+EXPORT_SYMBOL(machine_to_phys_mapping);
+unsigned int machine_to_phys_order;
+EXPORT_SYMBOL(machine_to_phys_order);
+
static void __init machine_specific_arch_setup(void)
{
int ret;
+ struct xen_machphys_mapping mapping;
+ unsigned long machine_to_phys_nr_ents;
struct xen_platform_parameters pp;
struct callback_register event = {
.type = CALLBACKTYPE_event,
@@ -81,4 +89,13 @@ static void __init machine_specific_arch
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
set_fixaddr_top(pp.virt_start - PAGE_SIZE);
+
+ machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
+ machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+ if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
+ machine_to_phys_mapping = (unsigned long *)mapping.v_start;
+ machine_to_phys_nr_ents = mapping.max_mfn + 1;
+ }
+ while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
+ machine_to_phys_order++;
}
diff -r b6ee2a730139 -r 46e853c34a2e
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Tue Jun
20 13:45:23 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Tue Jun
20 14:45:46 2006 +0100
@@ -85,6 +85,10 @@ void copy_page(void *, void *);
extern unsigned long *phys_to_machine_mapping;
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int machine_to_phys_order;
+
static inline unsigned long pfn_to_mfn(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -107,7 +111,7 @@ static inline unsigned long mfn_to_pfn(u
if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn;
- if (mfn >= MACH2PHYS_NR_ENTRIES)
+ if (unlikely((mfn >> machine_to_phys_order) != 0))
return end_pfn;
/* The array access can fail (e.g., device space beyond end of RAM). */
@@ -123,7 +127,7 @@ static inline unsigned long mfn_to_pfn(u
" .quad 1b,3b\n"
".previous"
: "=r" (pfn)
- : "m" (machine_to_phys_mapping[mfn]), "ir" (end_pfn) );
+ : "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
return pfn;
}
diff -r b6ee2a730139 -r 46e853c34a2e xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Jun 20 13:45:23 2006 +0100
+++ b/xen/arch/x86/mm.c Tue Jun 20 14:45:46 2006 +0100
@@ -3051,6 +3051,20 @@ long arch_memory_op(int op, XEN_GUEST_HA
return 0;
}
+ case XENMEM_machphys_mapping:
+ {
+ struct xen_machphys_mapping mapping = {
+ .v_start = MACH2PHYS_VIRT_START,
+ .v_end = MACH2PHYS_VIRT_END,
+ .max_mfn = MACH2PHYS_NR_ENTRIES - 1
+ };
+
+ if ( copy_to_guest(arg, &mapping, 1) )
+ return -EFAULT;
+
+ return 0;
+ }
+
default:
return subarch_memory_op(op, arg);
}
diff -r b6ee2a730139 -r 46e853c34a2e xen/include/public/memory.h
--- a/xen/include/public/memory.h Tue Jun 20 13:45:23 2006 +0100
+++ b/xen/include/public/memory.h Tue Jun 20 14:45:46 2006 +0100
@@ -141,6 +141,20 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn
DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
/*
+ * Returns the location in virtual address space of the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table, or which do not
+ * map it by default into guest address space, do not implement this command.
+ * arg == addr of xen_machphys_mapping_t.
+ */
+#define XENMEM_machphys_mapping 12
+struct xen_machphys_mapping {
+ unsigned long v_start, v_end; /* Start and end virtual addresses. */
+ unsigned long max_mfn; /* Maximum MFN that can be looked up. */
+};
+typedef struct xen_machphys_mapping xen_machphys_mapping_t;
+DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
+
+/*
* Sets the GPFN at which a particular page appears in the specified guest's
* pseudophysical address space.
* arg == addr of xen_add_to_physmap_t.
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|