[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.