diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-03-08 15:39:59 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-03-08 15:39:59 +0100 |
commit | 4507928009edaa9d8c3bcbb8c59f73f2b47d4726 (patch) | |
tree | 1c45be5bf97e72a8bb59adab32d25ad753d66a50 /xen/common/multicall.c | |
parent | 99efc13eb811a6adf976d00ad2b8e16b80d98792 (diff) | |
download | xen-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.c | 38 |
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); } /* |