Ian Campbell
2009-Jul-03 12:54 UTC
[Xen-devel] [PATCH] 32on64: increase size of compat argument translation area to 2 pages
# HG changeset patch # User Ian Campbell <ian.campbell@citrix.com> # Date 1246625635 -3600 # Node ID cb45d91651df9b27d01a807a2be40e8a3460876f # Parent 31002ac6a13caadab7c163d387af558a2b2da7ce 32on64: increase size of compat argument translation area to 2 pages. The existing single page is not quite large enough to translate a XENMEM_exchange hypercall with order=9. Since Linux uses MAX_CONTIG_ORDER of 9 this seems like a reasonable upper bound to support. Increasing COMPAT_ARG_XLAT_SIZE to 2 pages is sufficient to support order 9 exchanges. PERCPU_SHIFT must also be increased since the translation area is percpu. This was observed through a driver which did a large pci_alloc_consistent request. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r 31002ac6a13c -r cb45d91651df xen/include/asm-x86/percpu.h --- a/xen/include/asm-x86/percpu.h Thu Jul 02 09:43:41 2009 +0100 +++ b/xen/include/asm-x86/percpu.h Fri Jul 03 13:53:55 2009 +0100 @@ -1,7 +1,7 @@ #ifndef __X86_PERCPU_H__ #define __X86_PERCPU_H__ -#define PERCPU_SHIFT 13 +#define PERCPU_SHIFT 14 #define PERCPU_SIZE (1UL << PERCPU_SHIFT) /* Separate out the type, so (int[3], foo) works. */ diff -r 31002ac6a13c -r cb45d91651df xen/include/asm-x86/x86_64/uaccess.h --- a/xen/include/asm-x86/x86_64/uaccess.h Thu Jul 02 09:43:41 2009 +0100 +++ b/xen/include/asm-x86/x86_64/uaccess.h Fri Jul 03 13:53:55 2009 +0100 @@ -2,7 +2,7 @@ #define __X86_64_UACCESS_H #define COMPAT_ARG_XLAT_VIRT_BASE this_cpu(compat_arg_xlat) -#define COMPAT_ARG_XLAT_SIZE PAGE_SIZE +#define COMPAT_ARG_XLAT_SIZE 2*PAGE_SIZE DECLARE_PER_CPU(char, compat_arg_xlat[COMPAT_ARG_XLAT_SIZE]); #define is_compat_arg_xlat_range(addr, size) ({ \ unsigned long __off; \ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2009-Jul-03 13:31 UTC
Re: [Xen-devel] [PATCH] 32on64: increase size of compat argumenttranslation area to 2 pages
>>> Ian Campbell <ian.campbell@citrix.com> 03.07.09 14:54 >>> >32on64: increase size of compat argument translation area to 2 pages. > >The existing single page is not quite large enough to translate a >XENMEM_exchange hypercall with order=9. Since Linux uses >MAX_CONTIG_ORDER of 9 this seems like a reasonable upper bound to >support. > >Increasing COMPAT_ARG_XLAT_SIZE to 2 pages is sufficient to support >order 9 exchanges. PERCPU_SHIFT must also be increased since the >translation area is percpu.Perhaps we should decouple this by allocating those pages as CPUs get brought up, and just have a pointer in per-CPU storage. Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Jul-03 13:47 UTC
Re: [Xen-devel] [PATCH] 32on64: increase size of compat argumenttranslation area to 2 pages
On 03/07/2009 14:31, "Jan Beulich" <JBeulich@novell.com> wrote:>> Increasing COMPAT_ARG_XLAT_SIZE to 2 pages is sufficient to support >> order 9 exchanges. PERCPU_SHIFT must also be increased since the >> translation area is percpu. > > Perhaps we should decouple this by allocating those pages as CPUs get > brought up, and just have a pointer in per-CPU storage.Good idea. I will sort out a patch to do so, and apply Ian''s patch on top. I will backport both for 3.4.1. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2009-Jul-03 15:16 UTC
Re: [Xen-devel] [PATCH] 32on64: increase size of compatargumenttranslation area to 2 pages
>>> Keir Fraser <keir.fraser@eu.citrix.com> 03.07.09 15:47 >>> >On 03/07/2009 14:31, "Jan Beulich" <JBeulich@novell.com> wrote: > >>> Increasing COMPAT_ARG_XLAT_SIZE to 2 pages is sufficient to support >>> order 9 exchanges. PERCPU_SHIFT must also be increased since the >>> translation area is percpu. >> >> Perhaps we should decouple this by allocating those pages as CPUs get >> brought up, and just have a pointer in per-CPU storage. > >Good idea. I will sort out a patch to do so, and apply Ian''s patch on top. I >will backport both for 3.4.1.Just in case - here''s my take on it. And I''d think 3.3.2 may also need this and Ian''s adjustment then. Jan Subject: avoid compat_arg_xlat to be a large per-CPU object Signed-off-by: Jan Beulich <jbeulich@novell.com> --- 2009-06-10.orig/xen/arch/x86/smpboot.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/arch/x86/smpboot.c 2009-07-03 16:48:29.000000000 +0200 @@ -878,6 +878,9 @@ static int __devinit do_boot_cpu(int api per_cpu(doublefault_tss, cpu) = alloc_xenheap_page(); memset(per_cpu(doublefault_tss, cpu), 0, PAGE_SIZE); } +#else + if (!per_cpu(compat_arg_xlat, cpu)) + setup_compat_arg_xlat(cpu, apicid_to_node[apicid]); #endif if (!idt_tables[cpu]) { --- 2009-06-10.orig/xen/arch/x86/x86_64/compat/mm.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/arch/x86/x86_64/compat/mm.c 2009-07-03 15:42:21.000000000 +0200 @@ -58,7 +58,7 @@ int compat_arch_memory_op(int op, XEN_GU case XENMEM_add_to_physmap: { struct compat_add_to_physmap cmp; - struct xen_add_to_physmap *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + struct xen_add_to_physmap *nat = COMPAT_ARG_XLAT_VIRT_BASE; if ( copy_from_guest(&cmp, arg, 1) ) return -EFAULT; @@ -72,7 +72,7 @@ int compat_arch_memory_op(int op, XEN_GU case XENMEM_set_memory_map: { struct compat_foreign_memory_map cmp; - struct xen_foreign_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + struct xen_foreign_memory_map *nat = COMPAT_ARG_XLAT_VIRT_BASE; if ( copy_from_guest(&cmp, arg, 1) ) return -EFAULT; @@ -91,7 +91,7 @@ int compat_arch_memory_op(int op, XEN_GU case XENMEM_machine_memory_map: { struct compat_memory_map cmp; - struct xen_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + struct xen_memory_map *nat = COMPAT_ARG_XLAT_VIRT_BASE; if ( copy_from_guest(&cmp, arg, 1) ) return -EFAULT; @@ -118,7 +118,7 @@ int compat_arch_memory_op(int op, XEN_GU case XENMEM_get_pod_target: { struct compat_pod_target cmp; - struct xen_pod_target *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + struct xen_pod_target *nat = COMPAT_ARG_XLAT_VIRT_BASE; if ( copy_from_guest(&cmp, arg, 1) ) return -EFAULT; @@ -212,7 +212,7 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm if ( unlikely(!guest_handle_okay(cmp_uops, count)) ) return -EFAULT; - set_xen_guest_handle(nat_ops, (void *)COMPAT_ARG_XLAT_VIRT_BASE); + set_xen_guest_handle(nat_ops, COMPAT_ARG_XLAT_VIRT_BASE); for ( ; count; count -= i ) { --- 2009-06-10.orig/xen/arch/x86/x86_64/mm.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/arch/x86/x86_64/mm.c 2009-07-03 17:04:19.000000000 +0200 @@ -22,6 +22,7 @@ #include <xen/init.h> #include <xen/mm.h> #include <xen/sched.h> +#include <xen/numa.h> #include <xen/guest_access.h> #include <asm/current.h> #include <asm/asm_defns.h> @@ -30,7 +31,6 @@ #include <asm/fixmap.h> #include <asm/hypercall.h> #include <asm/msr.h> -#include <asm/numa.h> #include <public/memory.h> #ifdef CONFIG_COMPAT @@ -37,7 +37,7 @@ int mpt_valid; unsigned int m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START; #endif -DEFINE_PER_CPU(char, compat_arg_xlat[COMPAT_ARG_XLAT_SIZE]); +DEFINE_PER_CPU(void *, compat_arg_xlat); /* Top-level master (and idle-domain) page directory. */ l4_pgentry_t __attribute__ ((__section__ (".bss.page_aligned"))) @@ -293,6 +293,25 @@ void __init zap_low_mappings(void) 0x10, __PAGE_HYPERVISOR); } +int __cpuinit setup_compat_arg_xlat(unsigned int cpu, int node) +{ + unsigned int order = get_order_from_bytes(COMPAT_ARG_XLAT_SIZE); + unsigned long sz = PAGE_SIZE << order; + unsigned int memflags = node != NUMA_NO_NODE ? MEMF_node(node) : 0; + struct page_info *pg; + + pg = alloc_domheap_pages(NULL, order, memflags); + if ( !pg ) + return -ENOMEM; + + for ( ; (sz -= PAGE_SIZE) >= COMPAT_ARG_XLAT_SIZE; ++pg ) + free_domheap_page(pg); + + per_cpu(compat_arg_xlat, cpu) = page_to_virt(pg); + + return 0; +} + void __init subarch_init_memory(void) { unsigned long i, n, v, m2p_start_mfn; @@ -350,6 +369,10 @@ void __init subarch_init_memory(void) share_xen_page_with_privileged_guests(page, XENSHARE_readonly); } } + + if ( setup_compat_arg_xlat(smp_processor_id(), + apicid_to_node[boot_cpu_physical_apicid]) ) + panic("Could not setup argument translation area"); } long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) --- 2009-06-10.orig/xen/common/compat/domain.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/common/compat/domain.c 2009-07-03 15:43:41.000000000 +0200 @@ -87,7 +87,7 @@ int compat_vcpu_op(int cmd, int vcpuid, if ( copy_from_guest(&cmp, arg, 1) ) return -EFAULT; - nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE; + nat = COMPAT_ARG_XLAT_VIRT_BASE; XLAT_vcpu_set_singleshot_timer(nat, &cmp); rc = do_vcpu_op(cmd, vcpuid, guest_handle_from_ptr(nat, void)); break; --- 2009-06-10.orig/xen/common/compat/grant_table.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/common/compat/grant_table.c 2009-07-03 15:43:54.000000000 +0200 @@ -99,7 +99,7 @@ int compat_grant_table_op(unsigned int c struct compat_gnttab_copy copy; } cmp; - set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_BASE); + set_xen_guest_handle(nat.uop, COMPAT_ARG_XLAT_VIRT_BASE); switch ( cmd ) { case GNTTABOP_setup_table: --- 2009-06-10.orig/xen/common/compat/memory.c 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/common/compat/memory.c 2009-07-03 15:44:00.000000000 +0200 @@ -25,7 +25,7 @@ int compat_memory_op(unsigned int cmd, X struct compat_memory_exchange xchg; } cmp; - set_xen_guest_handle(nat.hnd, (void *)COMPAT_ARG_XLAT_VIRT_BASE); + set_xen_guest_handle(nat.hnd, COMPAT_ARG_XLAT_VIRT_BASE); split = 0; switch ( op ) { --- 2009-06-10.orig/xen/include/asm-x86/x86_64/uaccess.h 2009-07-03 16:13:10.000000000 +0200 +++ 2009-06-10/xen/include/asm-x86/x86_64/uaccess.h 2009-07-03 16:49:28.000000000 +0200 @@ -3,7 +3,8 @@ #define COMPAT_ARG_XLAT_VIRT_BASE this_cpu(compat_arg_xlat) #define COMPAT_ARG_XLAT_SIZE PAGE_SIZE -DECLARE_PER_CPU(char, compat_arg_xlat[COMPAT_ARG_XLAT_SIZE]); +DECLARE_PER_CPU(void *, compat_arg_xlat); +int setup_compat_arg_xlat(unsigned int cpu, int node); #define is_compat_arg_xlat_range(addr, size) ({ \ unsigned long __off; \ __off = (unsigned long)(addr) - (unsigned long)COMPAT_ARG_XLAT_VIRT_BASE; \ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Jul-03 17:47 UTC
Re: [Xen-devel] [PATCH] 32on64: increase size of compatargumenttranslation area to 2 pages
On 03/07/2009 16:16, "Jan Beulich" <JBeulich@novell.com> wrote:>> Good idea. I will sort out a patch to do so, and apply Ian''s patch on top. I >> will backport both for 3.4.1. > > Just in case - here''s my take on it.Looks fine. Saves me a job, thanks.> And I''d think 3.3.2 may also need this and Ian''s adjustment then.Mmmmm.... I guess the patches look safe enough. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel