# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1163155082 -32400 # Node ID 9c2edde14184d7b5600b09f7571e6752ed097ae9 # Parent b4e7365d451de6ffa84f24cfc29d59fea9aa50be fix xenmem hypercall for non-trivial xencomm arch(i.e. ia64, and powerpc) On ia64 and powerpc, guest_handle_add_offset() effect persists over hypercall continuation because its consumed offset is recorced in guest domains memory space. On the other hand, x86 guest_handle_add_offset() effect is volatile over hypercall continuation. So xenmem hypercall(more specifically increase_reservation, decrease_reservaton, populate_memory and exchange) is broken on ia64 and powerpc. On the other hand, do_multicall() @ xen/common/multicall.c and guest_console_write() @ xen/drivers/char/console.c depends on guest_handle_add_offset() behaviour. #ifndef ARCH_HAS_XENCOMM is used to solve this issue without breaking the existing ABI. #ifndef is ugly and ARCH_HAS_XENCOMM should be used in only XENMEM hypercall. PATCHNAME: xencomm_and_xenmem_hypercall Signed-off-by: Isaku Yamahata diff -r b4e7365d451d -r 9c2edde14184 xen/common/memory.c --- a/xen/common/memory.c Fri Nov 10 07:48:25 2006 +0000 +++ b/xen/common/memory.c Fri Nov 10 19:38:02 2006 +0900 @@ -341,23 +341,35 @@ memory_exchange(XEN_GUEST_HANDLE(xen_mem memflags = MEMF_dma; } +#ifndef ARCH_HAS_XENCOMM + /* on x86 its effect is volatile over hypercall continuation, + * so this adjustment is necessary. + * OTOH on ia64 and powerpc, guest_handle_add_offset() effects + * persists over hypercall continuation so that this adjustment + * isn't necessary. + */ guest_handle_add_offset(exch.in.extent_start, exch.nr_exchanged); +#endif exch.in.nr_extents -= exch.nr_exchanged; if ( exch.in.extent_order <= exch.out.extent_order ) { in_chunk_order = exch.out.extent_order - exch.in.extent_order; out_chunk_order = 0; +#ifndef ARCH_HAS_XENCOMM guest_handle_add_offset( exch.out.extent_start, exch.nr_exchanged >> in_chunk_order); +#endif exch.out.nr_extents -= exch.nr_exchanged >> in_chunk_order; } else { in_chunk_order = 0; out_chunk_order = exch.in.extent_order - exch.out.extent_order; +#ifndef ARCH_HAS_XENCOMM guest_handle_add_offset( exch.out.extent_start, exch.nr_exchanged << out_chunk_order); +#endif exch.out.nr_extents -= exch.nr_exchanged << out_chunk_order; } @@ -379,6 +391,17 @@ memory_exchange(XEN_GUEST_HANDLE(xen_mem { if ( hypercall_preempt_check() ) { + /* This is for ia64 and powerpc. + * on x86 this results in nop because its effect is volatile + * over hypercall continuation. + */ + guest_handle_add_offset(exch.in.extent_start, i); + if ( exch.in.extent_order <= exch.out.extent_order ) + guest_handle_add_offset( + exch.out.extent_start, i >> in_chunk_order); + else + guest_handle_add_offset( + exch.out.extent_start, i << out_chunk_order); exch.nr_exchanged += i << in_chunk_order; if ( copy_field_to_guest(arg, &exch, nr_exchanged) ) return -EFAULT; @@ -543,8 +566,16 @@ long do_memory_op(unsigned long cmd, XEN if ( unlikely(start_extent > reservation.nr_extents) ) return start_extent; +#ifndef ARCH_HAS_XENCOMM + /* on x86 its effect is volatile over hypercall continuation, + * so this adjustment is necessary. + * OTOH on ia64 and powerpc, guest_handle_add_offset() effects + * persists over hypercall continuation so that this adjustment + * isn't necessary. + */ if ( !guest_handle_is_null(reservation.extent_start) ) guest_handle_add_offset(reservation.extent_start, start_extent); +#endif reservation.nr_extents -= start_extent; if ( (reservation.address_bits != 0) && @@ -596,6 +627,12 @@ long do_memory_op(unsigned long cmd, XEN if ( unlikely(reservation.domid != DOMID_SELF) ) put_domain(d); + /* This is for ia64 and powerpc. + * on x86 this results in nop because its effect is volatile + * over hypercall continuation. + */ + if ( rc > 0 && !guest_handle_is_null(reservation.extent_start) ) + guest_handle_add_offset(reservation.extent_start, rc); rc += start_extent; if ( preempted ) diff -r b4e7365d451d -r 9c2edde14184 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Fri Nov 10 07:48:25 2006 +0000 +++ b/xen/include/public/arch-ia64.h Fri Nov 10 19:38:02 2006 +0900 @@ -26,6 +26,7 @@ #ifndef __HYPERVISOR_IF_IA64_H__ #define __HYPERVISOR_IF_IA64_H__ +#define ARCH_HAS_XENCOMM 1 /* Structural guest handles introduced in 0x00030201. */ #if __XEN_INTERFACE_VERSION__ >= 0x00030201 #define __DEFINE_XEN_GUEST_HANDLE(name, type) \ diff -r b4e7365d451d -r 9c2edde14184 xen/include/public/arch-powerpc.h --- a/xen/include/public/arch-powerpc.h Fri Nov 10 07:48:25 2006 +0000 +++ b/xen/include/public/arch-powerpc.h Fri Nov 10 19:38:02 2006 +0900 @@ -21,6 +21,7 @@ #ifndef __XEN_PUBLIC_ARCH_PPC_64_H__ #define __XEN_PUBLIC_ARCH_PPC_64_H__ +#define ARCH_HAS_XENCOMM 1 #define __DEFINE_XEN_GUEST_HANDLE(name, type) \ typedef struct { \ int __pad[(sizeof (long long) - sizeof (void *)) / sizeof (int)]; \