diff options
author | Jan Beulich <jbeulich@suse.com> | 2011-11-11 14:27:41 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2011-11-11 14:27:41 +0100 |
commit | 3d4e3e903e3b4bbfdab4924a71bdab28fb62f84f (patch) | |
tree | 3c3f6e66155d2d543b3dd440296709315b56ec3a /xen/common/multicall.c | |
parent | 62a359f77b27392926a387bb1d3d5c05be1c1e21 (diff) | |
download | xen-3d4e3e903e3b4bbfdab4924a71bdab28fb62f84f.tar.gz xen-3d4e3e903e3b4bbfdab4924a71bdab28fb62f84f.tar.bz2 xen-3d4e3e903e3b4bbfdab4924a71bdab28fb62f84f.zip |
multicall: don't ignore failure from __copy_to_guest() upon preemption
At once adjust perf counter updates to also count calls from here even
if a guest memory access failed.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common/multicall.c')
-rw-r--r-- | xen/common/multicall.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/xen/common/multicall.c b/xen/common/multicall.c index 58b96b28a3..6c1a9d7a67 100644 --- a/xen/common/multicall.c +++ b/xen/common/multicall.c @@ -25,6 +25,7 @@ do_multicall( { struct mc_state *mcs = ¤t->mc_state; unsigned int i; + int rc = 0; if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) ) { @@ -33,15 +34,18 @@ do_multicall( } if ( unlikely(!guest_handle_okay(call_list, nr_calls)) ) - goto fault; + rc = -EFAULT; - for ( i = 0; i < nr_calls; i++ ) + for ( i = 0; !rc && i < nr_calls; i++ ) { if ( hypercall_preempt_check() ) goto preempted; if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) ) - goto fault; + { + rc = -EFAULT; + break; + } do_multicall_call(&mcs->call); @@ -58,30 +62,25 @@ do_multicall( #endif if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) ) - goto fault; - - if ( test_bit(_MCSF_call_preempted, &mcs->flags) ) + rc = -EFAULT; + else if ( test_bit(_MCSF_call_preempted, &mcs->flags) ) { /* Translate sub-call continuation to guest layout */ xlat_multicall_entry(mcs); /* Copy the sub-call continuation. */ - (void)__copy_to_guest(call_list, &mcs->call, 1); - goto preempted; + if ( likely(!__copy_to_guest(call_list, &mcs->call, 1)) ) + goto preempted; + rc = -EFAULT; } - - guest_handle_add_offset(call_list, 1); + else + guest_handle_add_offset(call_list, 1); } perfc_incr(calls_to_multicall); - perfc_add(calls_from_multicall, nr_calls); - mcs->flags = 0; - return 0; - - fault: - perfc_incr(calls_to_multicall); + perfc_add(calls_from_multicall, i); mcs->flags = 0; - return -EFAULT; + return rc; preempted: perfc_add(calls_from_multicall, i); |