aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-12-06 11:07:56 +0100
committerJan Beulich <jbeulich@suse.com>2012-12-06 11:07:56 +0100
commitcd7dc899a6dad96aa3df23e29c55110eb18e3ec3 (patch)
tree4ffd0c42e10669823d63850c50d8f82ffab601f8
parentc90224367c53bdbeae923359f6f78fa085753c38 (diff)
downloadxen-cd7dc899a6dad96aa3df23e29c55110eb18e3ec3.tar.gz
xen-cd7dc899a6dad96aa3df23e29c55110eb18e3ec3.tar.bz2
xen-cd7dc899a6dad96aa3df23e29c55110eb18e3ec3.zip
x86: fix hypercall continuation cancellation in XENMAPSPACE_gmfn_range compat wrapper
When no continuation was established, there must also not be an attempt to cancel it - hypercall_cancel_continuation(), in the non-HVM, non- multicall case, adjusts the guest mode return address in a way assuming that an earlier call hypercall_create_continuation() took place. Once touching this code, also restructure it slightly to improve readability and switch to using the more relaxed copy function (copying from the same guest memory already validated the virtual address range). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> xen-unstable changeset: 26195:7670eabcbafc xen-unstable date: Wed Nov 28 09:02:26 UTC 2012
-rw-r--r--xen/arch/x86/x86_64/compat/mm.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c
index f497503769..fb7baca2e2 100644
--- a/xen/arch/x86/x86_64/compat/mm.c
+++ b/xen/arch/x86/x86_64/compat/mm.c
@@ -66,21 +66,20 @@ int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
XLAT_add_to_physmap(nat, &cmp);
rc = arch_memory_op(op, guest_handle_from_ptr(nat, void));
- if ( cmp.space == XENMAPSPACE_gmfn_range )
+ if ( !rc || cmp.space != XENMAPSPACE_gmfn_range )
+ break;
+
+ XLAT_add_to_physmap(&cmp, nat);
+ if ( __copy_to_guest(arg, &cmp, 1) )
{
- if ( rc )
- {
- XLAT_add_to_physmap(&cmp, nat);
- if ( copy_to_guest(arg, &cmp, 1) )
- {
- hypercall_cancel_continuation();
- return -EFAULT;
- }
- }
if ( rc == __HYPERVISOR_memory_op )
- hypercall_xlat_continuation(NULL, 0x2, nat, arg);
+ hypercall_cancel_continuation();
+ return -EFAULT;
}
+ if ( rc == __HYPERVISOR_memory_op )
+ hypercall_xlat_continuation(NULL, 0x2, nat, arg);
+
break;
}