ia64/xen-unstable

changeset 17146:90ae3dfdd3cc

kexec: limit scope of the use of compat_kexec_range_t

Unless I am mistaken, the compat functions are provided a stable ABI.
This includes providing a stable version of xen_kexec_range_t in the
form of compat_kexec_range_t. However, internally it doesn't really
matter how xen represents the data.

Currently the code provides for the creation of a compat version of
all kexec range functions, which use the compat_kexec_range_t
function. This is difficult to extend if range code exists outside of
xen/common/kexec.c.

The existence of "#ifdef CONFIG_X86_64" in the code suggests that some
of the range code might be better off in architecture specific code.
Furthermore, subsequent patches will introduce ia64-specific range
handling code, which really would be much better off somewhere in
arch/ia64/.

With this in mind, the handling of compat_kexec_range_t is changed
such that the code which reads and returns data from user-space
translates between compat_kexec_range_t and xen_kexec_range_t. As,
padding aside, the two structures are currently the same this is quite
easy. Things may get more tricky in the future, but I don't believe
this change is likely to make things significantly worse (or better)
in that regard. In any case, refactoring can occur again as required.

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 28 10:45:47 2008 +0000 (2008-02-28)
parents f8624b023d67
children c88394b7c05a
files xen/common/compat/kexec.c xen/common/kexec.c
line diff
     1.1 --- a/xen/common/compat/kexec.c	Thu Feb 28 10:31:45 2008 +0000
     1.2 +++ b/xen/common/compat/kexec.c	Thu Feb 28 10:45:47 2008 +0000
     1.3 @@ -9,11 +9,6 @@
     1.4  
     1.5  #define do_kexec_op compat_kexec_op
     1.6  
     1.7 -#undef kexec_get
     1.8 -#define kexec_get(x)      compat_kexec_get_##x
     1.9 -#define xen_kexec_range   compat_kexec_range
    1.10 -#define xen_kexec_range_t compat_kexec_range_t
    1.11 -
    1.12  #define kexec_load_unload compat_kexec_load_unload
    1.13  #define xen_kexec_load    compat_kexec_load
    1.14  #define xen_kexec_load_t  compat_kexec_load_t
     2.1 --- a/xen/common/kexec.c	Thu Feb 28 10:31:45 2008 +0000
     2.2 +++ b/xen/common/kexec.c	Thu Feb 28 10:45:47 2008 +0000
     2.3 @@ -153,11 +153,7 @@ static int sizeof_note(const char *name,
     2.4              ELFNOTE_ALIGN(descsz));
     2.5  }
     2.6  
     2.7 -#define kexec_get(x)      kexec_get_##x
     2.8 -
     2.9 -#endif
    2.10 -
    2.11 -static int kexec_get(reserve)(xen_kexec_range_t *range)
    2.12 +static int kexec_get_reserve(xen_kexec_range_t *range)
    2.13  {
    2.14      if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0) {
    2.15          range->start = kexec_crash_area.start;
    2.16 @@ -168,7 +164,7 @@ static int kexec_get(reserve)(xen_kexec_
    2.17      return 0;
    2.18  }
    2.19  
    2.20 -static int kexec_get(xen)(xen_kexec_range_t *range)
    2.21 +static int kexec_get_xen(xen_kexec_range_t *range)
    2.22  {
    2.23  #ifdef CONFIG_X86_64
    2.24      range->start = xenheap_phys_start;
    2.25 @@ -179,7 +175,7 @@ static int kexec_get(xen)(xen_kexec_rang
    2.26      return 0;
    2.27  }
    2.28  
    2.29 -static int kexec_get(cpu)(xen_kexec_range_t *range)
    2.30 +static int kexec_get_cpu(xen_kexec_range_t *range)
    2.31  {
    2.32      int nr = range->nr;
    2.33      int nr_bytes = 0;
    2.34 @@ -223,7 +219,27 @@ static int kexec_get(cpu)(xen_kexec_rang
    2.35      return 0;
    2.36  }
    2.37  
    2.38 -static int kexec_get(range)(XEN_GUEST_HANDLE(void) uarg)
    2.39 +static int kexec_get_range_internal(xen_kexec_range_t *range)
    2.40 +{
    2.41 +    int ret = -EINVAL;
    2.42 +
    2.43 +    switch ( range->range )
    2.44 +    {
    2.45 +    case KEXEC_RANGE_MA_CRASH:
    2.46 +        ret = kexec_get_reserve(range);
    2.47 +        break;
    2.48 +    case KEXEC_RANGE_MA_XEN:
    2.49 +        ret = kexec_get_xen(range);
    2.50 +        break;
    2.51 +    case KEXEC_RANGE_MA_CPU:
    2.52 +        ret = kexec_get_cpu(range);
    2.53 +        break;
    2.54 +    }
    2.55 +
    2.56 +    return ret;
    2.57 +}
    2.58 +
    2.59 +static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg)
    2.60  {
    2.61      xen_kexec_range_t range;
    2.62      int ret = -EINVAL;
    2.63 @@ -231,18 +247,7 @@ static int kexec_get(range)(XEN_GUEST_HA
    2.64      if ( unlikely(copy_from_guest(&range, uarg, 1)) )
    2.65          return -EFAULT;
    2.66  
    2.67 -    switch ( range.range )
    2.68 -    {
    2.69 -    case KEXEC_RANGE_MA_CRASH:
    2.70 -        ret = kexec_get(reserve)(&range);
    2.71 -        break;
    2.72 -    case KEXEC_RANGE_MA_XEN:
    2.73 -        ret = kexec_get(xen)(&range);
    2.74 -        break;
    2.75 -    case KEXEC_RANGE_MA_CPU:
    2.76 -        ret = kexec_get(cpu)(&range);
    2.77 -        break;
    2.78 -    }
    2.79 +    ret = kexec_get_range_internal(&range);
    2.80  
    2.81      if ( ret == 0 && unlikely(copy_to_guest(uarg, &range, 1)) )
    2.82          return -EFAULT;
    2.83 @@ -250,6 +255,42 @@ static int kexec_get(range)(XEN_GUEST_HA
    2.84      return ret;
    2.85  }
    2.86  
    2.87 +#else /* COMPAT */
    2.88 +
    2.89 +#ifdef CONFIG_COMPAT
    2.90 +static int kexec_get_range_compat(XEN_GUEST_HANDLE(void) uarg)
    2.91 +{
    2.92 +    xen_kexec_range_t range;
    2.93 +    compat_kexec_range_t compat_range;
    2.94 +    int ret = -EINVAL;
    2.95 +
    2.96 +    if ( unlikely(copy_from_guest(&compat_range, uarg, 1)) )
    2.97 +        return -EFAULT;
    2.98 +
    2.99 +    range.range = compat_range.range;
   2.100 +    range.nr = compat_range.nr;
   2.101 +    range.size = compat_range.size;
   2.102 +    range.start = compat_range.start;
   2.103 +
   2.104 +    ret = kexec_get_range_internal(&range);
   2.105 +
   2.106 +    if ( ret == 0 ) {
   2.107 +        range.range = compat_range.range;
   2.108 +        range.nr = compat_range.nr;
   2.109 +        range.size = compat_range.size;
   2.110 +        range.start = compat_range.start;
   2.111 +
   2.112 +        if ( unlikely(copy_to_guest(uarg, &compat_range, 1)) )
   2.113 +             return -EFAULT;
   2.114 +    }
   2.115 +
   2.116 +    return ret;
   2.117 +}
   2.118 +#endif /* CONFIG_COMPAT */
   2.119 +
   2.120 +#endif /* COMPAT */
   2.121 +
   2.122 +
   2.123  #ifndef COMPAT
   2.124  
   2.125  static int kexec_load_get_bits(int type, int *base, int *bit)
   2.126 @@ -375,7 +416,11 @@ ret_t do_kexec_op(unsigned long op, XEN_
   2.127      switch ( op )
   2.128      {
   2.129      case KEXEC_CMD_kexec_get_range:
   2.130 -        ret = kexec_get(range)(uarg);
   2.131 +#ifndef COMPAT
   2.132 +        ret = kexec_get_range(uarg);
   2.133 +#else
   2.134 +        ret = kexec_get_range_compat(uarg);
   2.135 +#endif
   2.136          break;
   2.137      case KEXEC_CMD_kexec_load:
   2.138      case KEXEC_CMD_kexec_unload: