From: kfraser@dhcp93.uk.xensource.com Date: Tue, 20 Jun 2006 13:45:46 +0000 (+0100) Subject: Add new XENMEM_machphys_mapping to get info about location and X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15921^2~14 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=19c8828f4ba96dd029b03064b03da301afbb71ab;p=xen.git 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 --- diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c index 77176d0a32..de53871f36 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -92,8 +93,16 @@ static void __init setup_boot_cpu_data(void) boot_cpu_data.x86_mask = eax & 0xf; } +#include +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; @@ -105,6 +114,16 @@ void __init x86_64_start_kernel(char * real_mode_data) 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++) set_intr_gate(i, early_idt_handler); diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h index a31f62f849..9a4c6f95a4 100644 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h @@ -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(unsigned long mfn) 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(unsigned long mfn) " .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 --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h index 1b678d12f6..0f1caa0604 100644 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h @@ -7,6 +7,7 @@ **/ #include +#include static char * __init machine_specific_memory_setup(void) { @@ -44,9 +45,16 @@ extern void hypervisor_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_setup(void) 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 --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h index 92fdee2fab..8cffad59f5 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h @@ -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(unsigned long mfn) 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(unsigned long mfn) " .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 --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 1d5ffdb44b..573726fd3a 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3051,6 +3051,20 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) 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 --git a/xen/include/public/memory.h b/xen/include/public/memory.h index a467ae5038..9791437ca0 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -140,6 +140,20 @@ struct xen_machphys_mfn_list { typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t; 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.