ia64/xen-unstable

changeset 9194:53b0dc1cb1db

Implement guest_access routines for copying to/from a sub-field of a structure.
Use this as part of a tidy-up of the multicall hypercall.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Mar 08 15:39:59 2006 +0100 (2006-03-08)
parents 3627061dcc9a
children 766817372cab
files xen/common/multicall.c xen/include/asm-ia64/guest_access.h xen/include/asm-x86/guest_access.h
line diff
     1.1 --- a/xen/common/multicall.c	Wed Mar 08 15:35:14 2006 +0100
     1.2 +++ b/xen/common/multicall.c	Wed Mar 08 15:39:59 2006 +0100
     1.3 @@ -34,7 +34,10 @@ do_multicall(
     1.4  
     1.5      for ( i = 0; i < nr_calls; i++ )
     1.6      {
     1.7 -        if ( unlikely(__copy_from_guest_offset(&mcs->call, call_list, i, 1)) )
     1.8 +        if ( hypercall_preempt_check() )
     1.9 +            goto preempted;
    1.10 +
    1.11 +        if ( unlikely(__copy_from_guest(&mcs->call, call_list, 1)) )
    1.12              goto fault;
    1.13  
    1.14          do_multicall_call(&mcs->call);
    1.15 @@ -47,33 +50,21 @@ do_multicall(
    1.16               */
    1.17              struct multicall_entry corrupt;
    1.18              memset(&corrupt, 0xAA, sizeof(corrupt));
    1.19 -            (void)__copy_to_guest_offset(call_list, i, &corrupt, 1);
    1.20 +            (void)__copy_to_guest(call_list, &corrupt, 1);
    1.21          }
    1.22  #endif
    1.23  
    1.24 -        if ( unlikely(__copy_to_guest_offset(call_list, i, &mcs->call, 1)) )
    1.25 +        if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) )
    1.26              goto fault;
    1.27  
    1.28 -        if ( hypercall_preempt_check() )
    1.29 +        if ( test_bit(_MCSF_call_preempted, &mcs->flags) )
    1.30          {
    1.31 -            /*
    1.32 -             * Copy the sub-call continuation if it was preempted.
    1.33 -             * Otherwise skip over the sub-call entirely.
    1.34 -             */
    1.35 -            if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
    1.36 -                i++;
    1.37 -            else
    1.38 -                (void)__copy_to_guest_offset(call_list, i, &mcs->call, 1);
    1.39 +            /* Copy the sub-call continuation. */
    1.40 +            (void)__copy_to_guest(call_list, &mcs->call, 1);
    1.41 +            goto preempted;
    1.42 +        }
    1.43  
    1.44 -            /* Only create a continuation if there is work left to be done. */
    1.45 -            if ( i < nr_calls )
    1.46 -            {
    1.47 -                mcs->flags = 0;
    1.48 -                guest_handle_add_offset(call_list, i);
    1.49 -                return hypercall_create_continuation(
    1.50 -                    __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
    1.51 -            }
    1.52 -        }
    1.53 +        guest_handle_add_offset(call_list, 1);
    1.54      }
    1.55  
    1.56      mcs->flags = 0;
    1.57 @@ -82,6 +73,11 @@ do_multicall(
    1.58   fault:
    1.59      mcs->flags = 0;
    1.60      return -EFAULT;
    1.61 +
    1.62 + preempted:
    1.63 +    mcs->flags = 0;
    1.64 +    return hypercall_create_continuation(
    1.65 +        __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
    1.66  }
    1.67  
    1.68  /*
     2.1 --- a/xen/include/asm-ia64/guest_access.h	Wed Mar 08 15:35:14 2006 +0100
     2.2 +++ b/xen/include/asm-ia64/guest_access.h	Wed Mar 08 15:39:59 2006 +0100
     2.3 @@ -43,6 +43,20 @@
     2.4      copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
     2.5  })
     2.6  
     2.7 +/* Copy sub-field of a structure to guest context via a guest handle. */
     2.8 +#define copy_field_to_guest(hnd, ptr, field) ({         \
     2.9 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    2.10 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    2.11 +    copy_to_user(_x, _y, sizeof(*_x));                  \
    2.12 +})
    2.13 +
    2.14 +/* Copy sub-field of a structure from guest context via a guest handle. */
    2.15 +#define copy_field_from_guest(ptr, hnd, field) ({       \
    2.16 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    2.17 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    2.18 +    copy_from_user(_y, _x, sizeof(*_x));                \
    2.19 +})
    2.20 +
    2.21  /*
    2.22   * Pre-validate a guest handle.
    2.23   * Allows use of faster __copy_* functions.
    2.24 @@ -62,4 +76,16 @@
    2.25      __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
    2.26  })
    2.27  
    2.28 +#define __copy_field_to_guest(hnd, ptr, field) ({       \
    2.29 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    2.30 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    2.31 +    __copy_to_user(_x, _y, sizeof(*_x));                \
    2.32 +})
    2.33 +
    2.34 +#define __copy_field_from_guest(ptr, hnd, field) ({     \
    2.35 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    2.36 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    2.37 +    __copy_from_user(_y, _x, sizeof(*_x));              \
    2.38 +})
    2.39 +
    2.40  #endif /* __ASM_IA64_GUEST_ACCESS_H__ */
     3.1 --- a/xen/include/asm-x86/guest_access.h	Wed Mar 08 15:35:14 2006 +0100
     3.2 +++ b/xen/include/asm-x86/guest_access.h	Wed Mar 08 15:39:59 2006 +0100
     3.3 @@ -41,6 +41,20 @@
     3.4      copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
     3.5  })
     3.6  
     3.7 +/* Copy sub-field of a structure to guest context via a guest handle. */
     3.8 +#define copy_field_to_guest(hnd, ptr, field) ({         \
     3.9 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    3.10 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    3.11 +    copy_to_user(_x, _y, sizeof(*_x));                  \
    3.12 +})
    3.13 +
    3.14 +/* Copy sub-field of a structure from guest context via a guest handle. */
    3.15 +#define copy_field_from_guest(ptr, hnd, field) ({       \
    3.16 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    3.17 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    3.18 +    copy_from_user(_y, _x, sizeof(*_x));                \
    3.19 +})
    3.20 +
    3.21  /*
    3.22   * Pre-validate a guest handle.
    3.23   * Allows use of faster __copy_* functions.
    3.24 @@ -60,4 +74,16 @@
    3.25      __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
    3.26  })
    3.27  
    3.28 +#define __copy_field_to_guest(hnd, ptr, field) ({       \
    3.29 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    3.30 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    3.31 +    __copy_to_user(_x, _y, sizeof(*_x));                \
    3.32 +})
    3.33 +
    3.34 +#define __copy_field_from_guest(ptr, hnd, field) ({     \
    3.35 +    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
    3.36 +    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
    3.37 +    __copy_from_user(_y, _x, sizeof(*_x));              \
    3.38 +})
    3.39 +
    3.40  #endif /* __ASM_X86_GUEST_ACCESS_H__ */