[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] kexec: limit scope of the use of compat_kexec_range_t
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1204195547 0 # Node ID 90ae3dfdd3cc02aca07f5b8b53b4266e8fc48f95 # Parent f8624b023d67820a9ee92f3cf149ffc2f808311a 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@xxxxxxxxxxxx> --- xen/common/compat/kexec.c | 5 -- xen/common/kexec.c | 87 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 26 deletions(-) diff -r f8624b023d67 -r 90ae3dfdd3cc xen/common/compat/kexec.c --- a/xen/common/compat/kexec.c Thu Feb 28 10:31:45 2008 +0000 +++ b/xen/common/compat/kexec.c Thu Feb 28 10:45:47 2008 +0000 @@ -8,11 +8,6 @@ #define ret_t int #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 diff -r f8624b023d67 -r 90ae3dfdd3cc xen/common/kexec.c --- a/xen/common/kexec.c Thu Feb 28 10:31:45 2008 +0000 +++ b/xen/common/kexec.c Thu Feb 28 10:45:47 2008 +0000 @@ -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,7 +219,27 @@ 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) +{ + int ret = -EINVAL; + + switch ( range->range ) + { + case KEXEC_RANGE_MA_CRASH: + ret = kexec_get_reserve(range); + break; + case KEXEC_RANGE_MA_XEN: + ret = kexec_get_xen(range); + break; + case KEXEC_RANGE_MA_CPU: + 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; @@ -231,24 +247,49 @@ static int kexec_get(range)(XEN_GUEST_HA if ( unlikely(copy_from_guest(&range, uarg, 1)) ) return -EFAULT; - switch ( range.range ) - { - case KEXEC_RANGE_MA_CRASH: - ret = kexec_get(reserve)(&range); - break; - case KEXEC_RANGE_MA_XEN: - ret = kexec_get(xen)(&range); - break; - case KEXEC_RANGE_MA_CPU: - ret = kexec_get(cpu)(&range); - break; - } + 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 @@ -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: _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |