[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [patch 1/3] 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. Subsequent patches will add architecture specific code under xen/arch/ Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx> --- xen/common/compat/kexec.c | 5 -- xen/common/kexec.c | 79 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 22 deletions(-) Index: xen-unstable.hg/xen/common/compat/kexec.c =================================================================== --- xen-unstable.hg.orig/xen/common/compat/kexec.c 2008-02-25 16:24:12.000000000 +0900 +++ xen-unstable.hg/xen/common/compat/kexec.c 2008-02-25 16:31:10.000000000 +0900 @@ -9,11 +9,6 @@ #define do_kexec_op compat_kexec_op -#undef kexec_get -#define kexec_get(x) compat_kexec_get_##x -#define xen_kexec_range compat_kexec_range -#define xen_kexec_range_t compat_kexec_range_t - #define kexec_load_unload compat_kexec_load_unload #define xen_kexec_load compat_kexec_load #define xen_kexec_load_t compat_kexec_load_t Index: xen-unstable.hg/xen/common/kexec.c =================================================================== --- xen-unstable.hg.orig/xen/common/kexec.c 2008-02-25 16:06:24.000000000 +0900 +++ xen-unstable.hg/xen/common/kexec.c 2008-02-25 17:04:20.000000000 +0900 @@ -153,11 +153,7 @@ static int sizeof_note(const char *name, ELFNOTE_ALIGN(descsz)); } -#define kexec_get(x) kexec_get_##x - -#endif - -static int kexec_get(reserve)(xen_kexec_range_t *range) +static int kexec_get_reserve(xen_kexec_range_t *range) { if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0) { range->start = kexec_crash_area.start; @@ -168,7 +164,7 @@ static int kexec_get(reserve)(xen_kexec_ return 0; } -static int kexec_get(xen)(xen_kexec_range_t *range) +static int kexec_get_xen(xen_kexec_range_t *range) { #ifdef CONFIG_X86_64 range->start = xenheap_phys_start; @@ -179,7 +175,7 @@ static int kexec_get(xen)(xen_kexec_rang return 0; } -static int kexec_get(cpu)(xen_kexec_range_t *range) +static int kexec_get_cpu(xen_kexec_range_t *range) { int nr = range->nr; int nr_bytes = 0; @@ -223,33 +219,78 @@ static int kexec_get(cpu)(xen_kexec_rang return 0; } -static int kexec_get(range)(XEN_GUEST_HANDLE(void) uarg) +static int kexec_get_range_internal(xen_kexec_range_t *range) { - xen_kexec_range_t range; int ret = -EINVAL; - if ( unlikely(copy_from_guest(&range, uarg, 1)) ) - return -EFAULT; - - switch ( range.range ) + switch ( range->range ) { case KEXEC_RANGE_MA_CRASH: - ret = kexec_get(reserve)(&range); + ret = kexec_get_reserve(range); break; case KEXEC_RANGE_MA_XEN: - ret = kexec_get(xen)(&range); + ret = kexec_get_xen(range); break; case KEXEC_RANGE_MA_CPU: - ret = kexec_get(cpu)(&range); + ret = kexec_get_cpu(range); break; } + return ret; +} + +static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) +{ + xen_kexec_range_t range; + int ret = -EINVAL; + + if ( unlikely(copy_from_guest(&range, uarg, 1)) ) + return -EFAULT; + + ret = kexec_get_range_internal(&range); + if ( ret == 0 && unlikely(copy_to_guest(uarg, &range, 1)) ) return -EFAULT; return ret; } +#else /* COMPAT */ + +#ifdef CONFIG_COMPAT +static int kexec_get_range_compat(XEN_GUEST_HANDLE(void) uarg) +{ + xen_kexec_range_t range; + compat_kexec_range_t compat_range; + int ret = -EINVAL; + + if ( unlikely(copy_from_guest(&compat_range, uarg, 1)) ) + return -EFAULT; + + range.range = compat_range.range; + range.nr = compat_range.nr; + range.size = compat_range.size; + range.start = compat_range.start; + + ret = kexec_get_range_internal(&range); + + if ( ret == 0 ) { + range.range = compat_range.range; + range.nr = compat_range.nr; + range.size = compat_range.size; + range.start = compat_range.start; + + if ( unlikely(copy_to_guest(uarg, &compat_range, 1)) ) + return -EFAULT; + } + + return ret; +} +#endif /* CONFIG_COMPAT */ + +#endif /* COMPAT */ + + #ifndef COMPAT static int kexec_load_get_bits(int type, int *base, int *bit) @@ -375,7 +416,11 @@ ret_t do_kexec_op(unsigned long op, XEN_ switch ( op ) { case KEXEC_CMD_kexec_get_range: - ret = kexec_get(range)(uarg); +#ifndef COMPAT + ret = kexec_get_range(uarg); +#else + ret = kexec_get_range_compat(uarg); +#endif break; case KEXEC_CMD_kexec_load: case KEXEC_CMD_kexec_unload: -- -- Horms _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |