585 lines
14 KiB
Diff
585 lines
14 KiB
Diff
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.
|
|
|
|
Index: 2007-01-08/Config.mk
|
|
===================================================================
|
|
--- 2007-01-08.orig/Config.mk 2007-01-08 15:34:16.000000000 +0100
|
|
+++ 2007-01-08/Config.mk 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -11,6 +11,8 @@ XEN_OS ?= $(shell uname -s)
|
|
|
|
CONFIG_$(XEN_OS) := y
|
|
|
|
+SHELL ?= /bin/sh
|
|
+
|
|
# Tools to run on system hosting the build
|
|
HOSTCC = gcc
|
|
HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
|
|
Index: 2007-01-08/xen/arch/x86/domain_build.c
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:34:55.000000000 +0100
|
|
+++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:20.000000000 +0100
|
|
@@ -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();
|
|
Index: 2007-01-08/xen/arch/x86/setup.c
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 14:45:40.000000000 +0100
|
|
+++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -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
|
|
Index: 2007-01-08/xen/common/compat/Makefile
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100
|
|
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -1,4 +1,5 @@
|
|
obj-y += kernel.o
|
|
+obj-y += xlat.o
|
|
|
|
# extra dependencies
|
|
kernel.o: ../kernel.c
|
|
Index: 2007-01-08/xen/common/compat/xlat.c
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -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:
|
|
+ */
|
|
Index: 2007-01-08/xen/include/Makefile
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100
|
|
+++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:58.000000000 +0100
|
|
@@ -5,7 +5,7 @@ compat-arch-$(CONFIG_X86) := x86
|
|
|
|
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-subarch-y).h
|
|
+headers-y += compat/arch-$(compat-subarch-y).h compat/xlat.h
|
|
headers-y += compat/arch-$(compat-arch-y)/xen.h
|
|
headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-y).h
|
|
|
|
@@ -56,5 +56,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 -e 's,@arch@,$(compat-arch-y),g' -e 's,@subarch@,$(compat-subarch-y),g') || exit $$?; \
|
|
+ done >$@.new
|
|
+ mv -f $@.new $@
|
|
+
|
|
clean::
|
|
rm -rf compat
|
|
Index: 2007-01-08/xen/include/xlat.lst
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -0,0 +1,5 @@
|
|
+# First column indicator:
|
|
+# ! - needs translation
|
|
+# ? - needs checking
|
|
+? dom0_vga_console_info xen.h
|
|
+! start_info xen.h
|
|
Index: 2007-01-08/xen/tools/get-fields.sh
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/tools/get-fields.sh 2007-01-08 15:18:32.000000000 +0100
|
|
@@ -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
|