aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/multicall.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-11-11 14:27:41 +0100
committerJan Beulich <jbeulich@suse.com>2011-11-11 14:27:41 +0100
commit3d4e3e903e3b4bbfdab4924a71bdab28fb62f84f (patch)
tree3c3f6e66155d2d543b3dd440296709315b56ec3a /xen/common/multicall.c
parent62a359f77b27392926a387bb1d3d5c05be1c1e21 (diff)
downloadxen-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.c33
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 = &current->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);