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

[Xen-changelog] [xen-unstable] Handle the creation of startup info for compatibility mode guests. This



# HG changeset patch
# User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx>
# Date 1168018468 0
# Node ID 4a164bf1edfcd8bcff422db5b31710babd43162e
# Parent  e98b092c205771017f39bb6995c7333b62c16159
Handle the creation of startup info for compatibility mode guests. This
includes a script to auto-generate checking or translation code between
native and compatibility mode hypercall argument structures.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 Config.mk                   |    2 
 xen/arch/x86/domain_build.c |    6 
 xen/arch/x86/setup.c        |   12 +
 xen/common/compat/Makefile  |    1 
 xen/common/compat/xlat.c    |   32 +++
 xen/include/Makefile        |    9 
 xen/include/xlat.lst        |    5 
 xen/tools/get-fields.sh     |  425 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 491 insertions(+), 1 deletion(-)

diff -r e98b092c2057 -r 4a164bf1edfc Config.mk
--- a/Config.mk Fri Jan 05 17:34:28 2007 +0000
+++ b/Config.mk Fri Jan 05 17:34:28 2007 +0000
@@ -10,6 +10,8 @@ XEN_OS              ?= $(shell uname -s)
 XEN_OS              ?= $(shell uname -s)
 
 CONFIG_$(XEN_OS) := y
+
+SHELL     ?= /bin/sh
 
 # Tools to run on system hosting the build
 HOSTCC     = gcc
diff -r e98b092c2057 -r 4a164bf1edfc xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Jan 05 17:34:28 2007 +0000
+++ b/xen/arch/x86/domain_build.c       Fri Jan 05 17:34:28 2007 +0000
@@ -19,6 +19,7 @@
 #include <xen/version.h>
 #include <xen/iocap.h>
 #include <xen/bitops.h>
+#include <xen/compat.h>
 #include <asm/regs.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -848,6 +849,11 @@ int construct_dom0(struct domain *d,
         si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
     }
 
+#ifdef CONFIG_COMPAT
+    if ( IS_COMPAT(d) )
+        xlat_start_info(si, XLAT_start_info_console_dom0);
+#endif
+
     /* Reinstate the caller's page tables. */
     write_ptbase(current);
     local_irq_enable();
diff -r e98b092c2057 -r 4a164bf1edfc xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Fri Jan 05 17:34:28 2007 +0000
+++ b/xen/arch/x86/setup.c      Fri Jan 05 17:34:28 2007 +0000
@@ -18,6 +18,10 @@
 #include <xen/keyhandler.h>
 #include <xen/numa.h>
 #include <public/version.h>
+#ifdef CONFIG_COMPAT
+#include <compat/platform.h>
+#include <compat/xen.h>
+#endif
 #include <asm/bitops.h>
 #include <asm/smp.h>
 #include <asm/processor.h>
@@ -546,6 +550,14 @@ void __init __start_xen(multiboot_info_t
     BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
     BUILD_BUG_ON(sizeof(vcpu_info_t) != 64);
 
+#ifdef CONFIG_COMPAT
+    BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) !=
+                 sizeof(((struct compat_platform_op *)0)->u.pad));
+    BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE);
+    BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE);
+    BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64);
+#endif
+
     /* Check definitions in public headers match internal defs. */
     BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
 #ifdef HYPERVISOR_VIRT_END
diff -r e98b092c2057 -r 4a164bf1edfc xen/common/compat/Makefile
--- a/xen/common/compat/Makefile        Fri Jan 05 17:34:28 2007 +0000
+++ b/xen/common/compat/Makefile        Fri Jan 05 17:34:28 2007 +0000
@@ -1,4 +1,5 @@ obj-y += kernel.o
 obj-y += kernel.o
+obj-y += xlat.o
 
 # extra dependencies
 kernel.o:      ../kernel.c
diff -r e98b092c2057 -r 4a164bf1edfc xen/common/compat/xlat.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/compat/xlat.c  Fri Jan 05 17:34:28 2007 +0000
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * xlat.c
+ */
+
+#include <xen/compat.h>
+#include <xen/lib.h>
+#include <public/xen.h>
+#include <compat/xen.h>
+
+/* In-place translation functons: */
+void xlat_start_info(struct start_info *native,
+                     enum XLAT_start_info_console console)
+{
+    struct compat_start_info *compat = (void *)native;
+
+    BUILD_BUG_ON(sizeof(*native) < sizeof(*compat));
+    XLAT_start_info(compat, native);
+}
+
+#define xen_dom0_vga_console_info dom0_vga_console_info
+CHECK_dom0_vga_console_info;
+#undef dom0_vga_console_info
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r e98b092c2057 -r 4a164bf1edfc xen/include/Makefile
--- a/xen/include/Makefile      Fri Jan 05 17:34:28 2007 +0000
+++ b/xen/include/Makefile      Fri Jan 05 17:34:28 2007 +0000
@@ -4,7 +4,7 @@ compat-arch-$(CONFIG_X86) := x86_32
 
 headers-y                 := $(shell echo public/*.h | sed -e 
's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
 headers-y                 := $(filter-out %/dom0_ops.h,$(headers-y))
-headers-y                 += compat/arch-$(compat-arch-y).h
+headers-y                 += compat/arch-$(compat-arch-y).h compat/xlat.h
 
 cppflags-y                := -include public/xen-compat.h
 cppflags-$(CONFIG_X86)    += -m32
@@ -53,5 +53,12 @@ compat/%.c: public/%.h Makefile
            >$@.new
        mv -f $@.new $@
 
+compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) 
$(BASEDIR)/tools/get-fields.sh Makefile
+       grep -v '^[[:space:]]*#' xlat.lst | \
+       while read what name hdr; do \
+               $(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name 
$$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \
+       done >$@.new
+       mv -f $@.new $@
+
 clean::
        rm -rf compat
diff -r e98b092c2057 -r 4a164bf1edfc xen/include/xlat.lst
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xlat.lst      Fri Jan 05 17:34:28 2007 +0000
@@ -0,0 +1,5 @@
+# First column indicator:
+# ! - needs translation
+# ? - needs checking
+?      dom0_vga_console_info           xen.h
+!      start_info                      xen.h
diff -r e98b092c2057 -r 4a164bf1edfc xen/tools/get-fields.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/tools/get-fields.sh   Fri Jan 05 17:34:28 2007 +0000
@@ -0,0 +1,425 @@
+#!/bin/sh
+test -n "$1" -a -n "$2" -a -n "$3"
+set -ef
+
+get_fields() {
+       local level=1 aggr=0 name= fields=
+       for token in $2
+       do
+               case "$token" in
+               struct|union)
+                       test $level != 1 || aggr=1 fields= name=
+                       ;;
+               "{")
+                       level=$(expr $level + 1)
+                       ;;
+               "}")
+                       level=$(expr $level - 1)
+                       if [ $level = 1 -a $name = $1 ]
+                       then
+                               echo "$fields }"
+                               return 0
+                       fi
+                       ;;
+               [[:alpha:]_]*)
+                       test $aggr = 0 -o -n "$name" || name="$token"
+                       ;;
+               esac
+               test $aggr = 0 || fields="$fields $token"
+       done
+}
+
+build_enums() {
+       local level=1 kind= fields= members= named= id= token
+       for token in $2
+       do
+               case "$token" in
+               struct|union)
+                       test $level != 2 || fields=" "
+                       kind="$token;$kind"
+                       ;;
+               "{")
+                       level=$(expr $level + 1)
+                       ;;
+               "}")
+                       level=$(expr $level - 1)
+                       if [ $level = 1 ]
+                       then
+                               if [ "${kind%%;*}" = union ]
+                               then
+                                       echo
+                                       echo "enum XLAT_$1 {"
+                                       for m in $members
+                                       do
+                                               echo "    XLAT_${1}_$m,"
+                                       done
+                                       echo "};"
+                               fi
+                               return 0
+                       elif [ $level = 2 ]
+                       then
+                               named='?'
+                       fi
+                       ;;
+               [[:alpha:]]*)
+                       id=$token
+                       if [ -n "$named" -a -n "${kind#*;}" ]
+                       then
+                               build_enums ${1}_$token "$fields"
+                               named='!'
+                       fi
+                       ;;
+               ",")
+                       test $level != 2 || members="$members $id"
+                       ;;
+               ";")
+                       test $level != 2 || members="$members $id"
+                       test -z "$named" || kind=${kind#*;}
+                       named=
+                       ;;
+               esac
+               test -z "$fields" || fields="$fields $token"
+       done
+}
+
+handle_field() {
+       if [ -z "$5" ]
+       then
+               echo " \\"
+               if [ -z "$4" ]
+               then
+                       echo -n "$1(_d_)->$3 = (_s_)->$3;"
+               else
+                       echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 
's,\.,_,g')(_d_, _s_);"
+               fi
+       elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ]
+       then
+               local tag=$(echo "$5" | sed 
's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,')
+               echo " \\"
+               echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
+       else
+               local level=1 kind= fields= id= array= arrlvl=1 array_type= 
type= token
+               for token in $5
+               do
+                       case "$token" in
+                       struct|union)
+                               test $level != 2 || fields=" "
+                               if [ $level == 1 ]
+                               then
+                                       kind=$token
+                                       if [ $kind = union ]
+                                       then
+                                               echo " \\"
+                                               echo -n "${1}switch ($(echo $3 
| sed 's,\.,_,g')) {"
+                                       fi
+                               fi
+                               ;;
+                       "{")
+                               level=$(expr $level + 1) id=
+                               ;;
+                       "}")
+                               level=$(expr $level - 1) id=
+                               if [ $level == 1 -a $kind = union ]
+                               then
+                                       echo " \\"
+                                       echo -n "$1}"
+                               fi
+                               ;;
+                       "[")
+                               if [ $level != 2 -o $arrlvl != 1 ]
+                               then
+                                       :
+                               elif [ -z "$array" ]
+                               then
+                                       array=" "
+                               else
+                                       array="$array;"
+                               fi
+                               arrlvl=$(expr $arrlvl + 1)
+                               ;;
+                       "]")
+                               arrlvl=$(expr $arrlvl - 1)
+                               ;;
+                       COMPAT_HANDLE\(*\))
+                               if [ $level == 2 -a -z "$id" ]
+                               then
+                                       type=${token#COMPAT_HANDLE?}
+                                       type=${type%?}
+                                       type=${type#compat_}
+                               fi
+                               ;;
+                       compat_domain_handle_t)
+                               if [ $level == 2 -a -z "$id" ]
+                               then
+                                       array_type=$token
+                               fi
+                               ;;
+                       [[:alpha:]]*)
+                               id=$token
+                               ;;
+                       [\,\;])
+                               if [ $level == 2 -a -n "$(echo $id | sed 
's,^_pad[[:digit:]]*,,')" ]
+                               then
+                                       if [ $kind = union ]
+                                       then
+                                               echo " \\"
+                                               echo -n "${1}case 
XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):"
+                                               handle_field "$1    " $2 $3.$id 
"$type" "$fields"
+                                       elif [ -z "$array" -a -z "$array_type" ]
+                                       then
+                                               handle_field "$1" $2 $3.$id 
"$type" "$fields"
+                                       elif [ -z "$array" ]
+                                       then
+                                               copy_array "    " $3.$id
+                                       else
+                                               handle_array "$1" $2 $3.$id 
"${array#*;}" "$type" "$fields"
+                                       fi
+                                       test "$token" != ";" || fields= id= 
type=
+                                       array=
+                                       if [ $kind = union ]
+                                       then
+                                               echo " \\"
+                                               echo -n "$1    break;"
+                                       fi
+                               fi
+                               ;;
+                       *)
+                               if [ -n "$array" ]
+                               then
+                                       array="$array $token"
+                               fi
+                               ;;
+                       esac
+                       test -z "$fields" || fields="$fields $token"
+               done
+       fi
+}
+
+copy_array() {
+       echo " \\"
+       echo "${1}if ((_d_)->$2 != (_s_)->$2) \\"
+       echo -n "$1    memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));"
+}
+
+handle_array() {
+       local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)"
+       echo " \\"
+       echo "$1{ \\"
+       echo "$1    unsigned int $i; \\"
+       echo -n "$1    for ($i = 0; $i < "${4%%;*}"; ++$i) {"
+       if [ "$4" = "${4#*;}" ]
+       then
+               handle_field "$1        " $2 $3[$i] "$5" "$6"
+       else
+               handle_array "$1        " $2 $3[$i] "${4#*;}" "$5" "$6"
+       fi
+       echo " \\"
+       echo "$1    } \\"
+       echo -n "$1}"
+}
+
+build_body() {
+       echo
+       echo -n "#define XLAT_$1(_d_, _s_)"
+       local level=1 fields= id= array= arrlvl=1 array_type= type= token
+       for token in $2
+       do
+               case "$token" in
+               struct|union)
+                       test $level != 2 || fields=" "
+                       ;;
+               "{")
+                       level=$(expr $level + 1) id=
+                       ;;
+               "}")
+                       level=$(expr $level - 1) id=
+                       ;;
+               "[")
+                       if [ $level != 2 -o $arrlvl != 1 ]
+                       then
+                               :
+                       elif [ -z "$array" ]
+                       then
+                               array=" "
+                       else
+                               array="$array;"
+                       fi
+                       arrlvl=$(expr $arrlvl + 1)
+                       ;;
+               "]")
+                       arrlvl=$(expr $arrlvl - 1)
+                       ;;
+               COMPAT_HANDLE\(*\))
+                       if [ $level == 2 -a -z "$id" ]
+                       then
+                               type=${token#COMPAT_HANDLE?}
+                               type=${type%?}
+                               type=${type#compat_}
+                       fi
+                       ;;
+               compat_domain_handle_t)
+                       if [ $level == 2 -a -z "$id" ]
+                       then
+                               array_type=$token
+                       fi
+                       ;;
+               [[:alpha:]_]*)
+                       if [ -n "$array" ]
+                       then
+                               array="$array $token"
+                       else
+                               id=$token
+                       fi
+                       ;;
+               [\,\;])
+                       if [ $level == 2 -a -n "$(echo $id | sed 
's,^_pad[[:digit:]]*,,')" ]
+                       then
+                               if [ -z "$array" -a -z "$array_type" ]
+                               then
+                                       handle_field "    " $1 $id "$type" 
"$fields"
+                               elif [ -z "$array" ]
+                               then
+                                       copy_array "    " $id
+                               else
+                                       handle_array "    " $1 $id 
"${array#*;}" "$type" "$fields"
+                               fi
+                               test "$token" != ";" || fields= id= type=
+                               array=
+                       fi
+                       ;;
+               *)
+                       if [ -n "$array" ]
+                       then
+                               array="$array $token"
+                       fi
+                       ;;
+               esac
+               test -z "$fields" || fields="$fields $token"
+       done
+       echo ""
+}
+
+check_field() {
+       if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ]
+       then
+               echo "; \\"
+               local n=$(echo $3 | sed 's,[^.], ,g' | wc -w)
+               if [ -n "$4" ]
+               then
+                       for n in $4
+                       do
+                               case $n in
+                               struct|union)
+                                       ;;
+                               [[:alpha:]_]*)
+                                       echo -n "    CHECK_$n"
+                                       break
+                                       ;;
+                               *)
+                                       echo "Malformed compound declaration: 
'$n'" >&2
+                                       exit 1
+                                       ;;
+                               esac
+                       done
+               elif [ $n = 0 ]
+               then
+                       echo -n "    CHECK_FIELD_($1, $2, $3)"
+               else
+                       echo -n "    CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | 
sed 's!\.!, !g'))"
+               fi
+       else
+               local level=1 fields= id= token
+               for token in $4
+               do
+                       case "$token" in
+                       struct|union)
+                               test $level != 2 || fields=" "
+                               ;;
+                       "{")
+                               level=$(expr $level + 1) id=
+                               ;;
+                       "}")
+                               level=$(expr $level - 1) id=
+                               ;;
+                       [[:alpha:]]*)
+                               id=$token
+                               ;;
+                       [\,\;])
+                               if [ $level == 2 -a -n "$(echo $id | sed 
's,^_pad[[:digit:]]*,,')" ]
+                               then
+                                       check_field $1 $2 $3.$id "$fields"
+                                       test "$token" != ";" || fields= id=
+                               fi
+                               ;;
+                       esac
+                       test -z "$fields" || fields="$fields $token"
+               done
+       fi
+}
+
+build_check() {
+       echo
+       echo "#define CHECK_$1 \\"
+       local level=1 fields= kind= id= arrlvl=1 token
+       for token in $2
+       do
+               case "$token" in
+               struct|union)
+                       if [ $level == 1 ]
+                       then
+                               kind=$token
+                               echo -n "    CHECK_SIZE_($kind, $1)"
+                       elif [ $level == 2 ]
+                       then
+                               fields=" "
+                       fi
+                       ;;
+               "{")
+                       level=$(expr $level + 1) id=
+                       ;;
+               "}")
+                       level=$(expr $level - 1) id=
+                       ;;
+               "[")
+                       arrlvl=$(expr $arrlvl + 1)
+                       ;;
+               "]")
+                       arrlvl=$(expr $arrlvl - 1)
+                       ;;
+               [[:alpha:]_]*)
+                       test $level != 2 -o $arrlvl != 1 || id=$token
+                       ;;
+               [\,\;])
+                       if [ $level == 2 -a -n "$(echo $id | sed 
's,^_pad[[:digit:]]*,,')" ]
+                       then
+                               check_field $kind $1 $id "$fields"
+                               test "$token" != ";" || fields= id=
+                       fi
+                       ;;
+               esac
+               test -z "$fields" || fields="$fields $token"
+       done
+       echo ""
+}
+
+fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 
's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
+if [ -z "$fields" ]
+then
+       echo "Fields of '$2' not found in '$3'" >&2
+       exit 1
+fi
+name=${2#compat_}
+name=${name#xen}
+case "$1" in
+"!")
+       build_enums $name "$fields"
+       build_body $name "$fields"
+       ;;
+"?")
+       build_check $name "$fields"
+       ;;
+*)
+       echo "Invalid translation indicator: '$1'" >&2
+       exit 1
+       ;;
+esac

_______________________________________________
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®.