# 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
|