mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Fix preemption of multicalls in compat mode.
mcs->call (struct multicall_entry) always needs to be translated into mcs->compat_call (struct compat_multicall_entry) when a multicall is preempted in compat mode. Previously this translation only occured for those hypercalls which explicitly called hypercall_xlat_continuation() which doesn't cover all hypercalls which could potentially be preempted. Change hypercall_xlat_continuation() to only translate only the hypercall arguments themselves and not the multicall_entry layout. Translate the layout for all hypercalls in in compat_multicall() instead. Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
This commit is contained in:
1 parent
96469475a6
commit
ca938d8cc6
3 files changed
+15
-5
No files matched your search
@@ -1456,13 +1456,12 @@ int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...)
|
||||
id = NULL;
|
||||
}
|
||||
if ( (mask & 1) && mcs->call.args[i] == nval )
|
||||
++rc;
|
||||
else
|
||||
{
|
||||
cval = mcs->call.args[i];
|
||||
BUG_ON(mcs->call.args[i] != cval);
|
||||
mcs->call.args[i] = cval;
|
||||
++rc;
|
||||
}
|
||||
mcs->compat_call.args[i] = cval;
|
||||
else
|
||||
BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,6 +10,13 @@
|
||||
typedef int ret_t;
|
||||
#undef do_multicall_call
|
||||
|
||||
static inline void xlat_multicall_entry(struct mc_state *mcs)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<6; i++)
|
||||
mcs->compat_call.args[i] = mcs->call.args[i];
|
||||
}
|
||||
|
||||
DEFINE_XEN_GUEST_HANDLE(multicall_entry_compat_t);
|
||||
#define multicall_entry compat_multicall_entry
|
||||
#define multicall_entry_t multicall_entry_compat_t
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef COMPAT
|
||||
DEFINE_PER_CPU(struct mc_state, mc_state);
|
||||
typedef long ret_t;
|
||||
#define xlat_multicall_entry(mcs)
|
||||
#endif
|
||||
|
||||
ret_t
|
||||
@@ -62,6 +63,9 @@ do_multicall(
|
||||
|
||||
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;
|
||||
|
||||