aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-11-28 10:02:26 +0100
committerJan Beulich <jbeulich@suse.com>2012-11-28 10:02:26 +0100
commit79ea67d7a7f8aee357232680ca114e0d773b8a5e (patch)
treeac12e1ca96618b9e7381b7b90e8bd86d703eb4f0 /xen/arch/x86/x86_64
parent03f22f0070f3a609e6ae07a47ca90e75c65e329a (diff)
downloadxen-79ea67d7a7f8aee357232680ca114e0d773b8a5e.tar.gz
xen-79ea67d7a7f8aee357232680ca114e0d773b8a5e.tar.bz2
xen-79ea67d7a7f8aee357232680ca114e0d773b8a5e.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>
Diffstat (limited to 'xen/arch/x86/x86_64')
-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 d1eb785600..808e033a3f 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_PARAM(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;
}