mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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>
This commit is contained in:
1 parent
62a359f77b
commit
3d4e3e903e
1 file changed
+16
-17
+16
-17
@@ -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);
|
||||
perfc_add(calls_from_multicall, i);
|
||||
mcs->flags = 0;
|
||||
return 0;
|
||||
|
||||
fault:
|
||||
perfc_incr(calls_to_multicall);
|
||||
mcs->flags = 0;
|
||||
return -EFAULT;
|
||||
return rc;
|
||||
|
||||
preempted:
|
||||
perfc_add(calls_from_multicall, i);
|
||||
|
||||