aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/multicall.c
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-03-08 15:39:59 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-03-08 15:39:59 +0100
commit4507928009edaa9d8c3bcbb8c59f73f2b47d4726 (patch)
tree1c45be5bf97e72a8bb59adab32d25ad753d66a50 /xen/common/multicall.c
parent99efc13eb811a6adf976d00ad2b8e16b80d98792 (diff)
downloadxen-4507928009edaa9d8c3bcbb8c59f73f2b47d4726.tar.gz
xen-4507928009edaa9d8c3bcbb8c59f73f2b47d4726.tar.bz2
xen-4507928009edaa9d8c3bcbb8c59f73f2b47d4726.zip
Implement guest_access routines for copying to/from a sub-field of a structure.
Use this as part of a tidy-up of the multicall hypercall. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/common/multicall.c')
-rw-r--r--xen/common/multicall.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/xen/common/multicall.c b/xen/common/multicall.c
index 16e2fc1a1c..500bb38e86 100644
--- a/xen/common/multicall.c
+++ b/xen/common/multicall.c
@@ -34,7 +34,10 @@ do_multicall(
for ( i = 0; i < nr_calls; i++ )
{
- if ( unlikely(__copy_from_guest_offset(&mcs->call, call_list, i, 1)) )
+ if ( hypercall_preempt_check() )
+ goto preempted;
+
+ if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
goto fault;
do_multicall_call(&mcs->call);
@@ -47,33 +50,21 @@ do_multicall(
*/
struct multicall_entry corrupt;
memset(&corrupt, 0xAA, sizeof(corrupt));
- (void)__copy_to_guest_offset(call_list, i, &corrupt, 1);
+ (void)__copy_to_guest(call_list, &corrupt, 1);
}
#endif
- if ( unlikely(__copy_to_guest_offset(call_list, i, &mcs->call, 1)) )
+ if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) )
goto fault;
- if ( hypercall_preempt_check() )
+ if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
{
- /*
- * Copy the sub-call continuation if it was preempted.
- * Otherwise skip over the sub-call entirely.
- */
- if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
- i++;
- else
- (void)__copy_to_guest_offset(call_list, i, &mcs->call, 1);
-
- /* Only create a continuation if there is work left to be done. */
- if ( i < nr_calls )
- {
- mcs->flags = 0;
- guest_handle_add_offset(call_list, i);
- return hypercall_create_continuation(
- __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
- }
+ /* Copy the sub-call continuation. */
+ (void)__copy_to_guest(call_list, &mcs->call, 1);
+ goto preempted;
}
+
+ guest_handle_add_offset(call_list, 1);
}
mcs->flags = 0;
@@ -82,6 +73,11 @@ do_multicall(
fault:
mcs->flags = 0;
return -EFAULT;
+
+ preempted:
+ mcs->flags = 0;
+ return hypercall_create_continuation(
+ __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
}
/*