[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] tmem: fix 32-on-64 support



This implicitly required coverting the tmem_op structure from anonymous
to standard struct/union sub-fields, and extending the get-fields.sh
helper script to deal with typedef-ed guest handles used as types of
translated compound type fields.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- 2009-06-10.orig/tools/libxc/xc_tmem.c       2009-05-27 13:54:05.000000000 
+0200
+++ 2009-06-10/tools/libxc/xc_tmem.c    2009-06-16 16:39:08.000000000 +0200
@@ -43,11 +43,11 @@ int xc_tmem_control(int xc,
 
     op.cmd = TMEM_CONTROL;
     op.pool_id = pool_id;
-    op.subop = subop;
-    op.cli_id = cli_id;
-    op.arg1 = arg1;
-    op.arg2 = arg2;
-    op.buf.p = buf;
+    op.u.ctrl.subop = subop;
+    op.u.ctrl.cli_id = cli_id;
+    op.u.ctrl.arg1 = arg1;
+    op.u.ctrl.arg2 = arg2;
+    op.u.ctrl.buf.p = buf;
 
     if (subop == TMEMC_LIST) {
         if ((arg1 != 0) && (lock_pages(buf, arg1) != 0))
--- 2009-06-10.orig/xen/common/tmem.c   2009-06-16 16:38:02.000000000 +0200
+++ 2009-06-10/xen/common/tmem.c        2009-06-16 11:34:21.000000000 +0200
@@ -1842,7 +1842,8 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
     {
         tmem_write_lock(&tmem_rwlock);
         tmem_write_lock_set = 1;
-        rc = do_tmem_control(op.subop, op.cli_id, op.arg1, op.arg2, op.buf);
+        rc = do_tmem_control(op.u.ctrl.subop, op.u.ctrl.cli_id,
+                             op.u.ctrl.arg1, op.u.ctrl.arg2, op.u.ctrl.buf);
         goto out;
     }
 
@@ -1887,27 +1888,31 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
     switch ( op.cmd )
     {
     case TMEM_NEW_POOL:
-        rc = do_tmem_new_pool(op.flags,op.uuid[0],op.uuid[1]);
+        rc = do_tmem_new_pool(op.u.new.flags,
+                              op.u.new.uuid[0], op.u.new.uuid[1]);
         break;
     case TMEM_NEW_PAGE:
-        rc = do_tmem_put(pool, op.object, op.index, op.cmfn, 0, 0, 0);
+        rc = do_tmem_put(pool, op.u.gen.object, op.u.gen.index, op.u.gen.cmfn,
+                         0, 0, 0);
         break;
     case TMEM_PUT_PAGE:
-        rc = do_tmem_put(pool, op.object, op.index, op.cmfn, 0, 0, PAGE_SIZE);
+        rc = do_tmem_put(pool, op.u.gen.object, op.u.gen.index, op.u.gen.cmfn,
+                         0, 0, PAGE_SIZE);
         if (rc == 1) succ_put = 1;
         else non_succ_put = 1;
         break;
     case TMEM_GET_PAGE:
-        rc = do_tmem_get(pool, op.object, op.index, op.cmfn, 0, 0, PAGE_SIZE);
+        rc = do_tmem_get(pool, op.u.gen.object, op.u.gen.index, op.u.gen.cmfn,
+                         0, 0, PAGE_SIZE);
         if (rc == 1) succ_get = 1;
         else non_succ_get = 1;
         break;
     case TMEM_FLUSH_PAGE:
         flush = 1;
-        rc = do_tmem_flush_page(pool, op.object, op.index);
+        rc = do_tmem_flush_page(pool, op.u.gen.object, op.u.gen.index);
         break;
     case TMEM_FLUSH_OBJECT:
-        rc = do_tmem_flush_object(pool, op.object);
+        rc = do_tmem_flush_object(pool, op.u.gen.object);
         flush_obj = 1;
         break;
     case TMEM_DESTROY_POOL:
@@ -1915,12 +1920,14 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
         rc = do_tmem_destroy_pool(op.pool_id);
         break;
     case TMEM_READ:
-        rc = do_tmem_get(pool, op.object, op.index, op.cmfn,
-                         op.tmem_offset, op.pfn_offset, op.len);
+        rc = do_tmem_get(pool, op.u.gen.object, op.u.gen.index, op.u.gen.cmfn,
+                         op.u.gen.tmem_offset, op.u.gen.pfn_offset,
+                         op.u.gen.len);
         break;
     case TMEM_WRITE:
-        rc = do_tmem_put(pool, op.object, op.index, op.cmfn,
-                         op.tmem_offset, op.pfn_offset, op.len);
+        rc = do_tmem_put(pool, op.u.gen.object, op.u.gen.index, op.u.gen.cmfn,
+                         op.u.gen.tmem_offset, op.u.gen.pfn_offset,
+                         op.u.gen.len);
         break;
     case TMEM_XCHG:
         /* need to hold global lock to ensure xchg is atomic */
--- 2009-06-10.orig/xen/include/xen/tmem_xen.h  2009-06-15 15:11:54.000000000 
+0200
+++ 2009-06-10/xen/include/xen/tmem_xen.h       2009-06-16 15:09:40.000000000 
+0200
@@ -16,6 +16,9 @@
 #include <xen/guest_access.h> /* copy_from_guest */
 #include <xen/hash.h> /* hash_long */
 #include <public/tmem.h>
+#ifdef CONFIG_COMPAT
+#include <compat/tmem.h>
+#endif
 
 struct tmem_host_dependent_client {
     struct domain *domain;
@@ -286,6 +289,29 @@ typedef XEN_GUEST_HANDLE(tmem_op_t) tmem
 
 static inline int tmh_get_tmemop_from_client(tmem_op_t *op, tmem_cli_op_t uops)
 {
+#ifdef CONFIG_COMPAT
+    if ( is_pv_32on64_vcpu(current) )
+    {
+        int rc;
+        enum XLAT_tmem_op_u u;
+        tmem_op_compat_t cop;
+
+        rc = copy_from_guest(&cop, guest_handle_cast(uops, void), 1);
+        if ( rc )
+            return rc;
+        switch ( cop.cmd )
+        {
+        case TMEM_NEW_POOL: u = XLAT_tmem_op_u_new;  break;
+        case TMEM_CONTROL:  u = XLAT_tmem_op_u_ctrl; break;
+        default:            u = XLAT_tmem_op_u_gen;  break;
+        }
+#define XLAT_tmem_op_HNDL_u_ctrl_buf(_d_, _s_) \
+        guest_from_compat_handle((_d_)->u.ctrl.buf, (_s_)->u.ctrl.buf)
+        XLAT_tmem_op(op, &cop);
+#undef XLAT_tmem_op_HNDL_u_ctrl_buf
+        return 0;
+    }
+#endif
     return copy_from_guest(op, uops, 1);
 }
 
--- 2009-06-10.orig/xen/include/xlat.lst        2009-06-16 16:38:02.000000000 
+0200
+++ 2009-06-10/xen/include/xlat.lst     2009-06-15 15:14:25.000000000 +0200
@@ -57,6 +57,7 @@
 !      sched_poll                      sched.h
 ?      sched_remote_shutdown           sched.h
 ?      sched_shutdown                  sched.h
+!      tmem_op                         tmem.h
 ?      t_buf                           trace.h
 ?      vcpu_get_physid                 vcpu.h
 ?      vcpu_register_vcpu_info         vcpu.h
@@ -74,6 +75,3 @@
 ?      processor_px                    platform.h
 !      psd_package                     platform.h
 !      processor_performance           platform.h
-# ?    tmem_op_t                       tmem.h
-# ?    tmem_cli_mfn_t                  tmem.h
-# ?    tmem_cli_va_t                   tmem.h
--- 2009-06-10.orig/xen/include/public/tmem.h   2009-06-15 14:58:25.000000000 
+0200
+++ 2009-06-10/xen/include/public/tmem.h        2009-06-16 11:30:05.000000000 
+0200
@@ -75,14 +75,14 @@ struct tmem_op {
         struct {  /* for cmd == TMEM_NEW_POOL */
             uint64_t uuid[2];
             uint32_t flags;
-        };
+        } new;
         struct {  /* for cmd == TMEM_CONTROL */
             uint32_t subop;
             uint32_t cli_id;
             uint32_t arg1;
             uint32_t arg2;
             tmem_cli_va_t buf;
-        };
+        } ctrl;
         struct {
             uint64_t object;
             uint32_t index;
@@ -90,8 +90,8 @@ struct tmem_op {
             uint32_t pfn_offset;
             uint32_t len;
             tmem_cli_mfn_t cmfn; /* client machine page frame */
-        };
-    };
+        } gen;
+    } u;
 };
 typedef struct tmem_op tmem_op_t;
 DEFINE_XEN_GUEST_HANDLE(tmem_op_t);
--- 2009-06-10.orig/xen/tools/get-fields.sh     2009-06-16 16:38:02.000000000 
+0200
+++ 2009-06-10/xen/tools/get-fields.sh  2009-06-16 15:08:22.000000000 +0200
@@ -34,6 +34,34 @@ get_fields ()
        done
 }
 
+get_typedefs ()
+{
+       local level=1 state=
+       for token in $1
+       do
+               case "$token" in
+               typedef)
+                       test $level != 1 || state=1
+                       ;;
+               COMPAT_HANDLE\(*\))
+                       test $level != 1 -o "$state" != 1 || state=2
+                       ;;
+               [\{\[])
+                       level=$(expr $level + 1)
+                       ;;
+               [\}\]])
+                       level=$(expr $level - 1)
+                       ;;
+               ";")
+                       test $level != 1 || state=
+                       ;;
+               [a-zA-Z_]*)
+                       test $level != 1 -o "$state" != 2 || echo "$token"
+                       ;;
+               esac
+       done
+}
+
 build_enums ()
 {
        local level=1 kind= fields= members= named= id= token
@@ -166,7 +194,21 @@ for line in sys.stdin.readlines():
                                fi
                                ;;
                        [a-zA-Z]*)
-                               id=$token
+                               if [ -z "$id" -a -z "$type" -a -z "$array_type" 
]
+                               then
+                                       for id in $typedefs
+                                       do
+                                               test $id != "$token" || type=$id
+                                       done
+                                       if [ -z "$type" ]
+                                       then
+                                               id=$token
+                                       else
+                                               id=
+                                       fi
+                               else
+                                       id=$token
+                               fi
                                ;;
                        [\,\;])
                                if [ $level = 2 -a -n "$(echo $id | $SED 
's,^_pad[[:digit:]]*,,')" ]
@@ -281,6 +323,18 @@ build_body ()
                        if [ -n "$array" ]
                        then
                                array="$array $token"
+                       elif [ -z "$id" -a -z "$type" -a -z "$array_type" ]
+                       then
+                               for id in $typedefs
+                               do
+                                       test $id != "$token" || type=$id
+                               done
+                               if [ -z "$type" ]
+                               then
+                                       id=$token
+                               else
+                                       id=
+                               fi
                        else
                                id=$token
                        fi
@@ -419,7 +473,8 @@ build_check ()
        echo ""
 }
 
-fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$($SED -e 
's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
+list="$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)"
+fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$list")"
 if [ -z "$fields" ]
 then
        echo "Fields of '$2' not found in '$3'" >&2
@@ -429,6 +484,7 @@ name=${2#compat_}
 name=${name#xen}
 case "$1" in
 "!")
+       typedefs="$(get_typedefs "$list")"
        build_enums $name "$fields"
        build_body $name "$fields"
        ;;



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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