direct-io.hg

changeset 15183:63211a8027fa

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>
author Ian Campbell <ian.campbell@xensource.com>
date Wed May 30 11:55:38 2007 +0100 (2007-05-30)
parents c4f62fe631e4
children 1f1d1b43951e
files xen/arch/x86/domain.c xen/common/compat/multicall.c xen/common/multicall.c
line diff
     1.1 --- a/xen/arch/x86/domain.c	Wed May 30 10:47:05 2007 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Wed May 30 11:55:38 2007 +0100
     1.3 @@ -1456,13 +1456,12 @@ int hypercall_xlat_continuation(unsigned
     1.4                  id = NULL;
     1.5              }
     1.6              if ( (mask & 1) && mcs->call.args[i] == nval )
     1.7 +            {
     1.8 +                mcs->call.args[i] = cval;
     1.9                  ++rc;
    1.10 +            }
    1.11              else
    1.12 -            {
    1.13 -                cval = mcs->call.args[i];
    1.14 -                BUG_ON(mcs->call.args[i] != cval);
    1.15 -            }
    1.16 -            mcs->compat_call.args[i] = cval;
    1.17 +                BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]);
    1.18          }
    1.19      }
    1.20      else
     2.1 --- a/xen/common/compat/multicall.c	Wed May 30 10:47:05 2007 +0100
     2.2 +++ b/xen/common/compat/multicall.c	Wed May 30 11:55:38 2007 +0100
     2.3 @@ -10,6 +10,13 @@
     2.4  typedef int ret_t;
     2.5  #undef do_multicall_call
     2.6  
     2.7 +static inline void xlat_multicall_entry(struct mc_state *mcs)
     2.8 +{
     2.9 +    int i;
    2.10 +    for (i=0; i<6; i++)
    2.11 +        mcs->compat_call.args[i] = mcs->call.args[i];
    2.12 +}
    2.13 +
    2.14  DEFINE_XEN_GUEST_HANDLE(multicall_entry_compat_t);
    2.15  #define multicall_entry      compat_multicall_entry
    2.16  #define multicall_entry_t    multicall_entry_compat_t
     3.1 --- a/xen/common/multicall.c	Wed May 30 10:47:05 2007 +0100
     3.2 +++ b/xen/common/multicall.c	Wed May 30 11:55:38 2007 +0100
     3.3 @@ -17,6 +17,7 @@
     3.4  #ifndef COMPAT
     3.5  DEFINE_PER_CPU(struct mc_state, mc_state);
     3.6  typedef long ret_t;
     3.7 +#define xlat_multicall_entry(mcs)
     3.8  #endif
     3.9  
    3.10  ret_t
    3.11 @@ -62,6 +63,9 @@ do_multicall(
    3.12  
    3.13          if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
    3.14          {
    3.15 +            /* Translate sub-call continuation to guest layout */
    3.16 +            xlat_multicall_entry(mcs);
    3.17 +
    3.18              /* Copy the sub-call continuation. */
    3.19              (void)__copy_to_guest(call_list, &mcs->call, 1);
    3.20              goto preempted;