mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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@novell.com>
This commit is contained in:
1 parent
c133cc38e2
commit
c93bd0e6ea
6 files changed
+112
-25
No files matched your search
@@ -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))
|
||||
|
||||
+18
-11
@@ -1842,7 +1842,8 @@ EXPORT long do_tmem_op(tmem_cli_op_t uops)
|
||||
{
|
||||
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 uops)
|
||||
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 uops)
|
||||
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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_cli_op_t;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
+58
-2
@@ -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"
|
||||
;;
|
||||
|
||||