ia64/xen-unstable

changeset 13527:8475a4e0425e

[merge] with xen-unstable
author Christian Limpach <Christian.Limpach@xensource.com>
date Thu Jan 18 15:18:07 2007 +0000 (2007-01-18)
parents 3464bb656a9c 8e79d8d87ecd
children 3c8bb086025e
files buildconfigs/linux-defconfig_xen0_x86_32 buildconfigs/linux-defconfig_xenU_x86_32 buildconfigs/linux-defconfig_xen_x86_32 extras/mini-os/minios-x86_32.lds extras/mini-os/minios-x86_64.lds extras/mini-os/x86_32.S extras/mini-os/x86_64.S linux-2.6-xen-sparse/arch/i386/Kconfig linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h linux-2.6-xen-sparse/kernel/kexec.c patches/linux-2.6.16.33/series patches/linux-2.6.18/ipv6-no-autoconf.patch patches/linux-2.6.18/series tools/xm-test/lib/XmTestLib/XenManagedDomain.py
line diff
     1.1 --- a/.hgignore	Thu Jan 18 09:54:33 2007 +0000
     1.2 +++ b/.hgignore	Thu Jan 18 15:18:07 2007 +0000
     1.3 @@ -58,7 +58,7 @@
     1.4  ^docs/xen-api/xenapi-datamodel-graph.eps$
     1.5  ^extras/mini-os/h/hypervisor-ifs$
     1.6  ^extras/mini-os/h/xen-public$
     1.7 -^extras/mini-os/mini-os\..*$
     1.8 +^extras/mini-os/mini-os.*$
     1.9  ^install/.*$
    1.10  ^linux-[^/]*-native/.*$
    1.11  ^linux-[^/]*-xen/.*$
    1.12 @@ -142,6 +142,8 @@
    1.13  ^tools/python/build/.*$
    1.14  ^tools/security/secpol_tool$
    1.15  ^tools/security/xen/.*$
    1.16 +^tools/tests/blowfish\.bin$
    1.17 +^tools/tests/blowfish\.h$
    1.18  ^tools/tests/test_x86_emulator$
    1.19  ^tools/vnet/Make.local$
    1.20  ^tools/vnet/build/.*$
     2.1 --- a/Makefile	Thu Jan 18 09:54:33 2007 +0000
     2.2 +++ b/Makefile	Thu Jan 18 15:18:07 2007 +0000
     2.3 @@ -2,18 +2,15 @@
     2.4  # Grand Unified Makefile for Xen.
     2.5  #
     2.6  
     2.7 -# Export target architecture overrides to Xen and Linux sub-trees.
     2.8 -ifneq ($(XEN_TARGET_ARCH),)
     2.9 -SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH))
    2.10 -export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
    2.11 -endif
    2.12 -
    2.13  # Default target must appear before any include lines
    2.14  .PHONY: all
    2.15  all: dist
    2.16  
    2.17  export XEN_ROOT=$(CURDIR)
    2.18  include Config.mk
    2.19 +
    2.20 +SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH))
    2.21 +export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
    2.22  include buildconfigs/Rules.mk
    2.23  
    2.24  ifeq ($(XEN_TARGET_X86_PAE),y)
     3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Thu Jan 18 09:54:33 2007 +0000
     3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Thu Jan 18 15:18:07 2007 +0000
     3.3 @@ -177,6 +177,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
     3.4  # CONFIG_SPARSEMEM_STATIC is not set
     3.5  CONFIG_SPLIT_PTLOCK_CPUS=4096
     3.6  CONFIG_RESOURCES_64BIT=y
     3.7 +# CONFIG_HIGHPTE is not set
     3.8  CONFIG_MTRR=y
     3.9  # CONFIG_REGPARM is not set
    3.10  CONFIG_SECCOMP=y
     4.1 --- a/buildconfigs/linux-defconfig_xenU_x86_32	Thu Jan 18 09:54:33 2007 +0000
     4.2 +++ b/buildconfigs/linux-defconfig_xenU_x86_32	Thu Jan 18 15:18:07 2007 +0000
     4.3 @@ -174,6 +174,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
     4.4  # CONFIG_SPARSEMEM_STATIC is not set
     4.5  CONFIG_SPLIT_PTLOCK_CPUS=4096
     4.6  CONFIG_RESOURCES_64BIT=y
     4.7 +# CONFIG_HIGHPTE is not set
     4.8  # CONFIG_REGPARM is not set
     4.9  CONFIG_SECCOMP=y
    4.10  CONFIG_HZ_100=y
     5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Thu Jan 18 09:54:33 2007 +0000
     5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Thu Jan 18 15:18:07 2007 +0000
     5.3 @@ -182,6 +182,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
     5.4  # CONFIG_SPARSEMEM_STATIC is not set
     5.5  CONFIG_SPLIT_PTLOCK_CPUS=4096
     5.6  CONFIG_RESOURCES_64BIT=y
     5.7 +# CONFIG_HIGHPTE is not set
     5.8  CONFIG_MTRR=y
     5.9  CONFIG_REGPARM=y
    5.10  CONFIG_SECCOMP=y
     6.1 --- a/docs/man/xm.pod.1	Thu Jan 18 09:54:33 2007 +0000
     6.2 +++ b/docs/man/xm.pod.1	Thu Jan 18 15:18:07 2007 +0000
     6.3 @@ -451,6 +451,7 @@ make the man page more readable):
     6.4   xen_minor              : 0
     6.5   xen_extra              : -devel
     6.6   xen_caps               : xen-3.0-x86_32
     6.7 + xen_scheduler          : credit
     6.8   xen_pagesize           : 4096
     6.9   platform_params        : virt_start=0xfc000000
    6.10   xen_changeset          : Mon Nov 14 18:13:38 2005 +0100 
    6.11 @@ -460,7 +461,7 @@ make the man page more readable):
    6.12   cc_compile_by          : sdague
    6.13   cc_compile_domain      : (none)
    6.14   cc_compile_date        : Mon Nov 14 14:16:48 EST 2005
    6.15 - xend_config_format     : 2
    6.16 + xend_config_format     : 3
    6.17  
    6.18  B<FIELDS>
    6.19  
     7.1 --- a/docs/man/xmdomain.cfg.pod.5	Thu Jan 18 09:54:33 2007 +0000
     7.2 +++ b/docs/man/xmdomain.cfg.pod.5	Thu Jan 18 15:18:07 2007 +0000
     7.3 @@ -135,6 +135,55 @@ one will be randomly chosen by xen with 
     7.4  
     7.5  =back
     7.6  
     7.7 +=item B<vfb>
     7.8 +
     7.9 +A virtual frame buffer stanza in the form:
    7.10 +
    7.11 +    vfb = [ "stanza" ]
    7.12 +
    7.13 +The stanza specifies a set of I<name = value> options separated by
    7.14 +commas, in the form: "name1=value1, name2=value2, ..."
    7.15 +
    7.16 +B<OPTIONS>
    7.17 +
    7.18 +=over 4
    7.19 +
    7.20 +=item I<type>
    7.21 +
    7.22 +There are currently two valid options: I<vnc> starts a VNC server that
    7.23 +lets you connect an external VNC viewer, and I<sdl> starts an internal
    7.24 +viewer.
    7.25 +
    7.26 +=item I<vncdisplay>
    7.27 +
    7.28 +The VNC display number to use, defaults to the domain ID.  The
    7.29 +VNC server listens on port 5900 + display number.
    7.30 +
    7.31 +=item I<vnclisten>
    7.32 +
    7.33 +The listening address for the VNC server, default 127.0.0.1.
    7.34 +
    7.35 +=item I<vncunused>
    7.36 +
    7.37 +If non-zero, the VNC server listens on the first unused port above
    7.38 +5900.
    7.39 +
    7.40 +=item I<vncpasswd>
    7.41 +
    7.42 +Overrides the XenD configured default password.
    7.43 +
    7.44 +=item I<display>
    7.45 +
    7.46 +Display to use for the internal viewer, defaults to environment
    7.47 +variable I<DISPLAY>.
    7.48 +
    7.49 +=item I<xauthority>
    7.50 +
    7.51 +Authority file to use for the internal viewer, defaults to environment
    7.52 +variable I<XAUTHORITY>.
    7.53 +
    7.54 +=back
    7.55 +
    7.56  =back
    7.57  
    7.58  =head1 ADDITIONAL OPTIONS
     8.1 --- a/docs/xen-api/wire-protocol.tex	Thu Jan 18 09:54:33 2007 +0000
     8.2 +++ b/docs/xen-api/wire-protocol.tex	Thu Jan 18 15:18:07 2007 +0000
     8.3 @@ -153,7 +153,7 @@ you must login and initiate a session. F
     8.4  \end{verbatim}
     8.5  Where {\tt uname} and {\tt password} refer to your username and password
     8.6  respectively, as defined by the Xen administrator.
     8.7 -The {\tt session\_id} returned by {\tt session.login_with_password} is passed
     8.8 +The {\tt session\_id} returned by {\tt session.login\_with\_password} is passed
     8.9  to subequent RPC calls as an authentication token.
    8.10  
    8.11  A session can be terminated with the {\tt session.logout} function:
     9.1 --- a/extras/mini-os/Makefile	Thu Jan 18 09:54:33 2007 +0000
     9.2 +++ b/extras/mini-os/Makefile	Thu Jan 18 15:18:07 2007 +0000
     9.3 @@ -1,106 +1,88 @@
     9.4 -debug ?= y
     9.5 +# Common Makefile for mini-os.
     9.6 +#
     9.7 +# Every architecture directory below mini-os/arch has to have a
     9.8 +# Makefile and a arch.mk.
     9.9 +#
    9.10 +
    9.11  pae ?= n
    9.12  
    9.13  XEN_ROOT = ../..
    9.14  include $(XEN_ROOT)/Config.mk
    9.15  
    9.16 -# Set TARGET_ARCH
    9.17 -override TARGET_ARCH     := $(XEN_TARGET_ARCH)
    9.18 -
    9.19 -XEN_INTERFACE_VERSION := 0x00030203
    9.20 +XEN_INTERFACE_VERSION := 0x00030204
    9.21 +export XEN_INTERFACE_VERSION
    9.22  
    9.23 -# NB. '-Wcast-qual' is nasty, so I omitted it.
    9.24 -CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
    9.25 -CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
    9.26 -CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
    9.27 -
    9.28 -ASFLAGS = -D__ASSEMBLY__
    9.29 -
    9.30 -LDLIBS =  -L. -lminios
    9.31 -LDFLAGS := -N -T minios-$(TARGET_ARCH).lds
    9.32 +# Set TARGET_ARCH
    9.33 +override TARGET_ARCH := $(XEN_TARGET_ARCH)
    9.34  
    9.35 -# For possible special source directories.
    9.36 -EXTRA_SRC =
    9.37 -# For possible special header directories.
    9.38 -EXTRA_INC =
    9.39 +# Set mini-os root path, used in mini-os.mk.
    9.40 +MINI-OS_ROOT=$(PWD)
    9.41 +export MINI-OS_ROOT
    9.42  
    9.43 -# Standard name for architecture specific subdirectories.
    9.44 -TARGET_ARCH_DIR = $(TARGET_ARCH)
    9.45 -# This is used for architecture specific links.
    9.46 -ARCH_LINKS =
    9.47 -
    9.48 -ifeq ($(TARGET_ARCH),x86_32)
    9.49 -CFLAGS += -m32 -march=i686
    9.50 -LDFLAGS += -m elf_i386
    9.51 -TARGET_ARCH_DIR = x86
    9.52 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH)
    9.53 -EXTRA_SRC += arch/$(EXTRA_INC)
    9.54 +# Try to find out the architecture family TARGET_ARCH_FAM.
    9.55 +# First check whether x86_... is contained (for x86_32, x86_32y, x86_64).
    9.56 +# If not x86 then use $(TARGET_ARCH) -> for ia64, ...
    9.57 +ifeq ($(findstring x86_,$(TARGET_ARCH)),x86_)
    9.58 +TARGET_ARCH_FAM = x86
    9.59 +else
    9.60 +TARGET_ARCH_FAM = $(TARGET_ARCH)
    9.61  endif
    9.62  
    9.63 -ifeq ($(TARGET_ARCH)$(pae),x86_32y)
    9.64 -CFLAGS  += -DCONFIG_X86_PAE=1
    9.65 -ASFLAGS += -DCONFIG_X86_PAE=1
    9.66 -TARGET_ARCH_DIR = x86
    9.67 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH)
    9.68 -EXTRA_SRC += arch/$(EXTRA_INC)
    9.69 -endif
    9.70 +# The architecture family directory below mini-os.
    9.71 +TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM)
    9.72 +
    9.73 +# Export these variables for possible use in architecture dependent makefiles.
    9.74 +export TARGET_ARCH
    9.75 +export TARGET_ARCH_DIR
    9.76 +export TARGET_ARCH_FAM
    9.77  
    9.78 -ifeq ($(TARGET_ARCH),x86_64)
    9.79 -CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks
    9.80 -CFLAGS += -fno-asynchronous-unwind-tables
    9.81 -LDFLAGS += -m elf_x86_64
    9.82 -TARGET_ARCH_DIR = x86
    9.83 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH)
    9.84 -EXTRA_SRC += arch/$(EXTRA_INC)
    9.85 -endif
    9.86 +# This is used for architecture specific links.
    9.87 +# This can be overwritten from arch specific rules.
    9.88 +ARCH_LINKS =
    9.89 +
    9.90 +# For possible special header directories.
    9.91 +# This can be overwritten from arch specific rules.
    9.92 +EXTRA_INC =
    9.93  
    9.94 -ifeq ($(TARGET_ARCH),ia64)
    9.95 -CFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -mconstant-gp
    9.96 -ASFLAGS += -x assembler-with-cpp -Wall
    9.97 -ASFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -fomit-frame-pointer
    9.98 -ASFLAGS += -fno-builtin -fno-common -fno-strict-aliasing -mconstant-gp
    9.99 -ARCH_LINKS = IA64_LINKS		# Special link on ia64 needed
   9.100 -define arch_links
   9.101 -[ -e include/ia64/asm-xsi-offsets.h ] || ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/ia64/asm-xsi-offsets.h
   9.102 -endef
   9.103 -endif
   9.104 +# Special build dependencies.
   9.105 +# Build all after touching this/these file(s) (see minios.mk)
   9.106 +SPEC_DEPENDS = minios.mk
   9.107 +
   9.108 +# Include the architecture family's special makerules.
   9.109 +# This must be before include minios.mk!
   9.110 +include $(TARGET_ARCH_DIR)/arch.mk
   9.111 +
   9.112 +# Include common mini-os makerules.
   9.113 +include minios.mk
   9.114  
   9.115 -ifeq ($(debug),y)
   9.116 -CFLAGS += -g
   9.117 -else
   9.118 -CFLAGS += -O3
   9.119 -endif
   9.120 +# Define some default flags for linking.
   9.121 +LDLIBS := 
   9.122 +LDFLAGS := 
   9.123 +LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
   9.124 +LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
   9.125  
   9.126 -# Add the special header directories to the include paths.
   9.127 -extra_incl := $(foreach dir,$(EXTRA_INC),-Iinclude/$(dir))
   9.128 -override CPPFLAGS := -Iinclude $(CPPFLAGS) -Iinclude/$(TARGET_ARCH_DIR)	$(extra_incl)
   9.129 +# Prefix for global API names. All other symbols are localised before
   9.130 +# linking with EXTRA_OBJS.
   9.131 +GLOBAL_PREFIX := xenos_
   9.132 +EXTRA_OBJS =
   9.133  
   9.134  TARGET := mini-os
   9.135  
   9.136 -HEAD := $(TARGET_ARCH).o
   9.137 +# Subdirectories common to mini-os
   9.138 +SUBDIRS := lib xenbus console
   9.139 +
   9.140 +# The common mini-os objects to build.
   9.141  OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
   9.142  OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
   9.143  OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
   9.144  OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
   9.145 -OBJS += $(patsubst %.S,%.o,$(wildcard arch/$(TARGET_ARCH_DIR)/*.S))
   9.146 -OBJS += $(patsubst %.c,%.o,$(wildcard arch/$(TARGET_ARCH_DIR)/*.c))
   9.147 -# For special wanted source directories.
   9.148 -extra_objs := $(foreach dir,$(EXTRA_SRC),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
   9.149 -OBJS += $(extra_objs)
   9.150 -extra_objs := $(foreach dir,$(EXTRA_SRC),$(patsubst %.S,%.o,$(wildcard $(dir)/*.S)))
   9.151 -OBJS += $(extra_objs)
   9.152  
   9.153 -HDRS := $(wildcard include/*.h)
   9.154 -HDRS += $(wildcard include/xen/*.h)
   9.155 -HDRS += $(wildcard include/$(TARGET_ARCH_DIR)/*.h)
   9.156 -# For special wanted header directories.
   9.157 -extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
   9.158 -HDRS += $(extra_heads)
   9.159  
   9.160  .PHONY: default
   9.161  default: $(TARGET)
   9.162  
   9.163 -# Create special architecture specific links.
   9.164 +# Create special architecture specific links. The function arch_links
   9.165 +# has to be defined in arch.mk (see include above).
   9.166  ifneq ($(ARCH_LINKS),)
   9.167  $(ARCH_LINKS):
   9.168  	$(arch_links)
   9.169 @@ -110,26 +92,29 @@ endif
   9.170  links:	$(ARCH_LINKS)
   9.171  	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
   9.172  
   9.173 -libminios.a: links $(OBJS) $(HEAD)
   9.174 -	$(AR) r libminios.a $(HEAD) $(OBJS)
   9.175 +.PHONY: arch_lib
   9.176 +arch_lib:
   9.177 +	$(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
   9.178 +
   9.179 +$(TARGET): links $(OBJS) arch_lib
   9.180 +	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o
   9.181 +	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
   9.182 +	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
   9.183 +	gzip -f -9 -c $@ >$@.gz
   9.184  
   9.185 -$(TARGET): libminios.a $(HEAD)
   9.186 -	$(LD) $(LDFLAGS) $(HEAD) $(LDLIBS) -o $@.elf
   9.187 -	gzip -f -9 -c $@.elf >$@.gz
   9.188 +.PHONY: clean arch_clean
   9.189 +
   9.190 +arch_clean:
   9.191 +	$(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1;
   9.192  
   9.193 -.PHONY: clean
   9.194 -clean:
   9.195 -	find . -type f -name '*.o' | xargs rm -f
   9.196 +clean:	arch_clean
   9.197 +	for dir in $(SUBDIRS); do \
   9.198 +		rm -f $$dir/*.o; \
   9.199 +	done
   9.200  	rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
   9.201 -	rm -f libminios.a
   9.202  	find . -type l | xargs rm -f
   9.203  	rm -f tags TAGS
   9.204  
   9.205 -%.o: %.c $(HDRS) Makefile
   9.206 -	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
   9.207 -
   9.208 -%.o: %.S $(HDRS) Makefile
   9.209 -	$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
   9.210  
   9.211  define all_sources
   9.212       ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
   9.213 @@ -143,3 +128,4 @@ cscope:
   9.214  .PHONY: tags
   9.215  tags:
   9.216  	$(all_sources) | xargs ctags
   9.217 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/extras/mini-os/arch/x86/Makefile	Thu Jan 18 15:18:07 2007 +0000
    10.3 @@ -0,0 +1,29 @@
    10.4 +#
    10.5 +# x86 architecture specific makefiles.
    10.6 +# It's is used for x86_32, x86_32y and x86_64
    10.7 +#
    10.8 +
    10.9 +# Rebuild all after touching this/these extra file(s) (see mini-os.mk)
   10.10 +SPEC_DEP = arch.mk
   10.11 +
   10.12 +# include arch.mk has to be before mini-os.mk!
   10.13 +include arch.mk
   10.14 +include ../../minios.mk
   10.15 +
   10.16 +# Sources here are all *.c *.S without $(TARGET_ARCH).S
   10.17 +# This is handled in $(HEAD_ARCH_OBJ)
   10.18 +ARCH_SRCS := $(wildcard *.c)
   10.19 +
   10.20 +# The objects built from the sources.
   10.21 +ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS))
   10.22 +
   10.23 +all: $(ARCH_LIB)
   10.24 +
   10.25 +# $(HEAD_ARCH_OBJ) is only build here, needed on linking
   10.26 +# in ../../Makefile.
   10.27 +$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
   10.28 +	$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
   10.29 +
   10.30 +clean:
   10.31 +	rm -f $(ARCH_LIB) $(ARCH_OBJS)
   10.32 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/extras/mini-os/arch/x86/arch.mk	Thu Jan 18 15:18:07 2007 +0000
    11.3 @@ -0,0 +1,28 @@
    11.4 +#
    11.5 +# Architecture special makerules for x86 family
    11.6 +# (including x86_32, x86_32y and x86_64).
    11.7 +#
    11.8 +
    11.9 +ifeq ($(TARGET_ARCH),x86_32)
   11.10 +ARCH_CFLAGS  := -m32 -march=i686
   11.11 +ARCH_LDFLAGS := -m elf_i386
   11.12 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
   11.13 +EXTRA_SRC += arch/$(EXTRA_INC)
   11.14 +endif
   11.15 +
   11.16 +ifeq ($(TARGET_ARCH)$(pae),x86_32y)
   11.17 +ARCH_CFLAGS  := -DCONFIG_X86_PAE=1
   11.18 +ARCH_ASFLAGS := -DCONFIG_X86_PAE=1
   11.19 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
   11.20 +EXTRA_SRC += arch/$(EXTRA_INC)
   11.21 +endif
   11.22 +
   11.23 +ifeq ($(TARGET_ARCH),x86_64)
   11.24 +ARCH_CFLAGS := -m64 -mno-red-zone -fpic -fno-reorder-blocks
   11.25 +ARCH_CFLAGS := -fno-asynchronous-unwind-tables
   11.26 +ARCH_LDFLAGS := -m elf_x86_64
   11.27 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
   11.28 +EXTRA_SRC += arch/$(EXTRA_INC)
   11.29 +endif
   11.30 +
   11.31 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/extras/mini-os/arch/x86/minios-x86_32.lds	Thu Jan 18 15:18:07 2007 +0000
    12.3 @@ -0,0 +1,45 @@
    12.4 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    12.5 +OUTPUT_ARCH(i386)
    12.6 +ENTRY(_start)
    12.7 +SECTIONS
    12.8 +{
    12.9 +  . = 0x0;
   12.10 +  _text = .;			/* Text and read-only data */
   12.11 +  .text : {
   12.12 +	*(.text)
   12.13 +	*(.gnu.warning)
   12.14 +	} = 0x9090
   12.15 +
   12.16 +  _etext = .;			/* End of text section */
   12.17 +
   12.18 +  .rodata : { *(.rodata) *(.rodata.*) }
   12.19 +
   12.20 +  .data : {			/* Data */
   12.21 +	*(.data)
   12.22 +	CONSTRUCTORS
   12.23 +	}
   12.24 +
   12.25 +  _edata = .;			/* End of data section */
   12.26 +
   12.27 +  __bss_start = .;		/* BSS */
   12.28 +  .bss : {
   12.29 +	*(.bss)
   12.30 +	}
   12.31 +  _end = . ;
   12.32 +
   12.33 +  /* Sections to be discarded */
   12.34 +  /DISCARD/ : {
   12.35 +	*(.text.exit)
   12.36 +	*(.data.exit)
   12.37 +	*(.exitcall.exit)
   12.38 +	}
   12.39 +
   12.40 +  /* Stabs debugging sections.  */
   12.41 +  .stab 0 : { *(.stab) }
   12.42 +  .stabstr 0 : { *(.stabstr) }
   12.43 +  .stab.excl 0 : { *(.stab.excl) }
   12.44 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   12.45 +  .stab.index 0 : { *(.stab.index) }
   12.46 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   12.47 +  .comment 0 : { *(.comment) }
   12.48 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/extras/mini-os/arch/x86/minios-x86_64.lds	Thu Jan 18 15:18:07 2007 +0000
    13.3 @@ -0,0 +1,54 @@
    13.4 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
    13.5 +OUTPUT_ARCH(i386:x86-64)
    13.6 +ENTRY(_start)
    13.7 +SECTIONS
    13.8 +{
    13.9 +  . = 0x0;
   13.10 +  _text = .;			/* Text and read-only data */
   13.11 +  .text : {
   13.12 +	*(.text)
   13.13 +	*(.gnu.warning)
   13.14 +	} = 0x9090
   13.15 +
   13.16 +  _etext = .;			/* End of text section */
   13.17 +
   13.18 +  .rodata : { *(.rodata) *(.rodata.*) }
   13.19 +
   13.20 +  .data : {			/* Data */
   13.21 +	*(.data)
   13.22 +	CONSTRUCTORS
   13.23 +	}
   13.24 +
   13.25 +  _edata = .;			/* End of data section */
   13.26 +
   13.27 +  . = ALIGN(8192);		/* init_task */
   13.28 +  .data.init_task : { *(.data.init_task) }
   13.29 +
   13.30 +  . = ALIGN(4096);
   13.31 +  .data.page_aligned : { *(.data.idt) }
   13.32 +
   13.33 +  . = ALIGN(32);
   13.34 +  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   13.35 +
   13.36 +  __bss_start = .;		/* BSS */
   13.37 +  .bss : {
   13.38 +	*(.bss)
   13.39 +	}
   13.40 +  _end = . ;
   13.41 +
   13.42 +  /* Sections to be discarded */
   13.43 +  /DISCARD/ : {
   13.44 +	*(.text.exit)
   13.45 +	*(.data.exit)
   13.46 +	*(.exitcall.exit)
   13.47 +	}
   13.48 +
   13.49 +  /* Stabs debugging sections.  */
   13.50 +  .stab 0 : { *(.stab) }
   13.51 +  .stabstr 0 : { *(.stabstr) }
   13.52 +  .stab.excl 0 : { *(.stab.excl) }
   13.53 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   13.54 +  .stab.index 0 : { *(.stab.index) }
   13.55 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   13.56 +  .comment 0 : { *(.comment) }
   13.57 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/extras/mini-os/arch/x86/x86_32.S	Thu Jan 18 15:18:07 2007 +0000
    14.3 @@ -0,0 +1,287 @@
    14.4 +#include <os.h>
    14.5 +#include <xen/arch-x86_32.h>
    14.6 +
    14.7 +.section __xen_guest
    14.8 +	.ascii	"GUEST_OS=Mini-OS"
    14.9 +	.ascii	",XEN_VER=xen-3.0"
   14.10 +	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
   14.11 +	.ascii	",ELF_PADDR_OFFSET=0x0"
   14.12 +	.ascii	",HYPERCALL_PAGE=0x2"
   14.13 +#ifdef CONFIG_X86_PAE
   14.14 +	.ascii	",PAE=yes"
   14.15 +#else
   14.16 +	.ascii	",PAE=no"
   14.17 +#endif
   14.18 +	.ascii	",LOADER=generic"
   14.19 +	.byte	0
   14.20 +.text
   14.21 +
   14.22 +.globl _start, shared_info, hypercall_page
   14.23 +                        
   14.24 +_start:
   14.25 +        cld
   14.26 +        lss stack_start,%esp
   14.27 +        push %esi 
   14.28 +        call start_kernel
   14.29 +
   14.30 +stack_start:
   14.31 +	.long stack+8192, __KERNEL_SS
   14.32 +
   14.33 +        /* Unpleasant -- the PTE that maps this page is actually overwritten */
   14.34 +        /* to map the real shared-info page! :-)                             */
   14.35 +        .org 0x1000
   14.36 +shared_info:
   14.37 +        .org 0x2000
   14.38 +
   14.39 +hypercall_page:
   14.40 +        .org 0x3000
   14.41 +
   14.42 +ES		= 0x20
   14.43 +ORIG_EAX	= 0x24
   14.44 +EIP		= 0x28
   14.45 +CS		= 0x2C
   14.46 +
   14.47 +#define ENTRY(X) .globl X ; X :
   14.48 +
   14.49 +#define SAVE_ALL \
   14.50 +	cld; \
   14.51 +	pushl %es; \
   14.52 +	pushl %ds; \
   14.53 +	pushl %eax; \
   14.54 +	pushl %ebp; \
   14.55 +	pushl %edi; \
   14.56 +	pushl %esi; \
   14.57 +	pushl %edx; \
   14.58 +	pushl %ecx; \
   14.59 +	pushl %ebx; \
   14.60 +	movl $(__KERNEL_DS),%edx; \
   14.61 +	movl %edx,%ds; \
   14.62 +	movl %edx,%es;
   14.63 +
   14.64 +#define RESTORE_ALL	\
   14.65 +	popl %ebx;	\
   14.66 +	popl %ecx;	\
   14.67 +	popl %edx;	\
   14.68 +	popl %esi;	\
   14.69 +	popl %edi;	\
   14.70 +	popl %ebp;	\
   14.71 +	popl %eax;	\
   14.72 +	popl %ds;	\
   14.73 +	popl %es;	\
   14.74 +	addl $4,%esp;	\
   14.75 +	iret;		\
   14.76 +
   14.77 +ENTRY(divide_error)
   14.78 +	pushl $0		# no error code
   14.79 +	pushl $do_divide_error
   14.80 +do_exception:
   14.81 +    pushl %ds
   14.82 +	pushl %eax
   14.83 +	xorl %eax, %eax
   14.84 +	pushl %ebp
   14.85 +	pushl %edi
   14.86 +	pushl %esi
   14.87 +	pushl %edx
   14.88 +	decl %eax			# eax = -1
   14.89 +	pushl %ecx
   14.90 +	pushl %ebx
   14.91 +	cld
   14.92 +	movl %es, %ecx
   14.93 +	movl ES(%esp), %edi		# get the function address
   14.94 +	movl ORIG_EAX(%esp), %edx	# get the error code
   14.95 +	movl %eax, ORIG_EAX(%esp)
   14.96 +	movl %ecx, ES(%esp)
   14.97 +	movl $(__KERNEL_DS), %ecx
   14.98 +	movl %ecx, %ds
   14.99 +	movl %ecx, %es
  14.100 +	movl %esp,%eax			# pt_regs pointer
  14.101 +    pushl %edx
  14.102 +    pushl %eax
  14.103 +	call *%edi
  14.104 +    jmp ret_from_exception
  14.105 +    
  14.106 +ret_from_exception:
  14.107 +        movb CS(%esp),%cl
  14.108 +	test $2,%cl          # slow return to ring 2 or 3
  14.109 +	jne  safesti
  14.110 +        RESTORE_ALL
  14.111 +
  14.112 +# A note on the "critical region" in our callback handler.
  14.113 +# We want to avoid stacking callback handlers due to events occurring
  14.114 +# during handling of the last event. To do this, we keep events disabled
  14.115 +# until weve done all processing. HOWEVER, we must enable events before
  14.116 +# popping the stack frame (cant be done atomically) and so it would still
  14.117 +# be possible to get enough handler activations to overflow the stack.
  14.118 +# Although unlikely, bugs of that kind are hard to track down, so wed
  14.119 +# like to avoid the possibility.
  14.120 +# So, on entry to the handler we detect whether we interrupted an
  14.121 +# existing activation in its critical region -- if so, we pop the current
  14.122 +# activation and restart the handler using the previous one.
  14.123 +ENTRY(hypervisor_callback)
  14.124 +        pushl %eax
  14.125 +        SAVE_ALL
  14.126 +        movl EIP(%esp),%eax
  14.127 +        cmpl $scrit,%eax
  14.128 +        jb   11f
  14.129 +        cmpl $ecrit,%eax
  14.130 +        jb   critical_region_fixup
  14.131 +11:     push %esp
  14.132 +        call do_hypervisor_callback
  14.133 +        add  $4,%esp
  14.134 +        movl HYPERVISOR_shared_info,%esi
  14.135 +        xorl %eax,%eax
  14.136 +        movb CS(%esp),%cl
  14.137 +    	test $2,%cl          # slow return to ring 2 or 3
  14.138 +        jne  safesti
  14.139 +safesti:movb $0,1(%esi)     # reenable event callbacks
  14.140 +scrit:  /**** START OF CRITICAL REGION ****/
  14.141 +        testb $0xFF,(%esi)
  14.142 +        jnz  14f              # process more events if necessary...
  14.143 +        RESTORE_ALL
  14.144 +14:     movb $1,1(%esi)
  14.145 +        jmp  11b
  14.146 +ecrit:  /**** END OF CRITICAL REGION ****/
  14.147 +# [How we do the fixup]. We want to merge the current stack frame with the
  14.148 +# just-interrupted frame. How we do this depends on where in the critical
  14.149 +# region the interrupted handler was executing, and so how many saved
  14.150 +# registers are in each frame. We do this quickly using the lookup table
  14.151 +# 'critical_fixup_table'. For each byte offset in the critical region, it
  14.152 +# provides the number of bytes which have already been popped from the
  14.153 +# interrupted stack frame. 
  14.154 +critical_region_fixup:
  14.155 +        addl $critical_fixup_table-scrit,%eax
  14.156 +        movzbl (%eax),%eax    # %eax contains num bytes popped
  14.157 +        mov  %esp,%esi
  14.158 +        add  %eax,%esi        # %esi points at end of src region
  14.159 +        mov  %esp,%edi
  14.160 +        add  $0x34,%edi       # %edi points at end of dst region
  14.161 +        mov  %eax,%ecx
  14.162 +        shr  $2,%ecx          # convert words to bytes
  14.163 +        je   16f              # skip loop if nothing to copy
  14.164 +15:     subl $4,%esi          # pre-decrementing copy loop
  14.165 +        subl $4,%edi
  14.166 +        movl (%esi),%eax
  14.167 +        movl %eax,(%edi)
  14.168 +        loop 15b
  14.169 +16:     movl %edi,%esp        # final %edi is top of merged stack
  14.170 +        jmp  11b
  14.171 +         
  14.172 +critical_fixup_table:        
  14.173 +        .byte 0x00,0x00,0x00                  # testb $0xff,(%esi)
  14.174 +        .byte 0x00,0x00                       # jne  14f
  14.175 +        .byte 0x00                            # pop  %ebx
  14.176 +        .byte 0x04                            # pop  %ecx
  14.177 +        .byte 0x08                            # pop  %edx
  14.178 +        .byte 0x0c                            # pop  %esi
  14.179 +        .byte 0x10                            # pop  %edi
  14.180 +        .byte 0x14                            # pop  %ebp
  14.181 +        .byte 0x18                            # pop  %eax
  14.182 +        .byte 0x1c                            # pop  %ds
  14.183 +        .byte 0x20                            # pop  %es
  14.184 +        .byte 0x24,0x24,0x24                  # add  $4,%esp
  14.185 +        .byte 0x28                            # iret
  14.186 +        .byte 0x00,0x00,0x00,0x00             # movb $1,1(%esi)
  14.187 +        .byte 0x00,0x00                       # jmp  11b
  14.188 +       
  14.189 +# Hypervisor uses this for application faults while it executes.
  14.190 +ENTRY(failsafe_callback)
  14.191 +      pop  %ds
  14.192 +      pop  %es
  14.193 +      pop  %fs
  14.194 +      pop  %gs
  14.195 +      iret
  14.196 +                
  14.197 +ENTRY(coprocessor_error)
  14.198 +	pushl $0
  14.199 +	pushl $do_coprocessor_error
  14.200 +	jmp do_exception
  14.201 +
  14.202 +ENTRY(simd_coprocessor_error)
  14.203 +	pushl $0
  14.204 +	pushl $do_simd_coprocessor_error
  14.205 +	jmp do_exception
  14.206 +
  14.207 +ENTRY(device_not_available)
  14.208 +        iret
  14.209 +
  14.210 +ENTRY(debug)
  14.211 +	pushl $0
  14.212 +	pushl $do_debug
  14.213 +	jmp do_exception
  14.214 +
  14.215 +ENTRY(int3)
  14.216 +	pushl $0
  14.217 +	pushl $do_int3
  14.218 +	jmp do_exception
  14.219 +
  14.220 +ENTRY(overflow)
  14.221 +	pushl $0
  14.222 +	pushl $do_overflow
  14.223 +	jmp do_exception
  14.224 +
  14.225 +ENTRY(bounds)
  14.226 +	pushl $0
  14.227 +	pushl $do_bounds
  14.228 +	jmp do_exception
  14.229 +
  14.230 +ENTRY(invalid_op)
  14.231 +	pushl $0
  14.232 +	pushl $do_invalid_op
  14.233 +	jmp do_exception
  14.234 +
  14.235 +
  14.236 +ENTRY(coprocessor_segment_overrun)
  14.237 +	pushl $0
  14.238 +	pushl $do_coprocessor_segment_overrun
  14.239 +	jmp do_exception
  14.240 +
  14.241 +
  14.242 +ENTRY(invalid_TSS)
  14.243 +	pushl $do_invalid_TSS
  14.244 +	jmp do_exception
  14.245 +
  14.246 +
  14.247 +ENTRY(segment_not_present)
  14.248 +	pushl $do_segment_not_present
  14.249 +	jmp do_exception
  14.250 +
  14.251 +
  14.252 +ENTRY(stack_segment)
  14.253 +	pushl $do_stack_segment
  14.254 +	jmp do_exception
  14.255 +
  14.256 +
  14.257 +ENTRY(general_protection)
  14.258 +	pushl $do_general_protection
  14.259 +	jmp do_exception
  14.260 +
  14.261 +
  14.262 +ENTRY(alignment_check)
  14.263 +	pushl $do_alignment_check
  14.264 +	jmp do_exception
  14.265 +
  14.266 +
  14.267 +ENTRY(page_fault)
  14.268 +    pushl $do_page_fault
  14.269 +    jmp do_exception
  14.270 +    
  14.271 +ENTRY(machine_check)
  14.272 +	pushl $0
  14.273 +	pushl $do_machine_check
  14.274 +	jmp do_exception
  14.275 +
  14.276 +
  14.277 +ENTRY(spurious_interrupt_bug)
  14.278 +	pushl $0
  14.279 +	pushl $do_spurious_interrupt_bug
  14.280 +	jmp do_exception
  14.281 +
  14.282 +
  14.283 +
  14.284 +ENTRY(thread_starter)
  14.285 +    popl %eax
  14.286 +    popl %ebx
  14.287 +    pushl %eax
  14.288 +    call *%ebx
  14.289 +    call exit_thread 
  14.290 +    
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/extras/mini-os/arch/x86/x86_64.S	Thu Jan 18 15:18:07 2007 +0000
    15.3 @@ -0,0 +1,385 @@
    15.4 +#include <os.h>
    15.5 +#include <xen/features.h>
    15.6 +
    15.7 +.section __xen_guest
    15.8 +	.ascii	"GUEST_OS=Mini-OS"
    15.9 +	.ascii	",XEN_VER=xen-3.0"
   15.10 +	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
   15.11 +	.ascii	",ELF_PADDR_OFFSET=0x0"
   15.12 +	.ascii	",HYPERCALL_PAGE=0x2"
   15.13 +	.ascii	",LOADER=generic"
   15.14 +	.byte	0
   15.15 +.text
   15.16 +
   15.17 +#define ENTRY(X) .globl X ; X :
   15.18 +.globl _start, shared_info, hypercall_page
   15.19 +
   15.20 +
   15.21 +_start:
   15.22 +        cld
   15.23 +        movq stack_start(%rip),%rsp
   15.24 +        movq %rsi,%rdi
   15.25 +        call start_kernel
   15.26 +
   15.27 +stack_start:
   15.28 +        .quad stack+8192
   15.29 +
   15.30 +        /* Unpleasant -- the PTE that maps this page is actually overwritten */
   15.31 +        /* to map the real shared-info page! :-)                             */
   15.32 +        .org 0x1000
   15.33 +shared_info:
   15.34 +        .org 0x2000
   15.35 +
   15.36 +hypercall_page:
   15.37 +        .org 0x3000
   15.38 +
   15.39 +
   15.40 +/* Offsets into shared_info_t. */                
   15.41 +#define evtchn_upcall_pending		/* 0 */
   15.42 +#define evtchn_upcall_mask		1
   15.43 +
   15.44 +NMI_MASK = 0x80000000
   15.45 +
   15.46 +#define RDI 112
   15.47 +#define ORIG_RAX 120       /* + error_code */ 
   15.48 +#define EFLAGS 144
   15.49 +
   15.50 +#define REST_SKIP 6*8			
   15.51 +.macro SAVE_REST
   15.52 +	subq $REST_SKIP,%rsp
   15.53 +#	CFI_ADJUST_CFA_OFFSET	REST_SKIP
   15.54 +	movq %rbx,5*8(%rsp) 
   15.55 +#	CFI_REL_OFFSET	rbx,5*8
   15.56 +	movq %rbp,4*8(%rsp) 
   15.57 +#	CFI_REL_OFFSET	rbp,4*8
   15.58 +	movq %r12,3*8(%rsp) 
   15.59 +#	CFI_REL_OFFSET	r12,3*8
   15.60 +	movq %r13,2*8(%rsp) 
   15.61 +#	CFI_REL_OFFSET	r13,2*8
   15.62 +	movq %r14,1*8(%rsp) 
   15.63 +#	CFI_REL_OFFSET	r14,1*8
   15.64 +	movq %r15,(%rsp) 
   15.65 +#	CFI_REL_OFFSET	r15,0*8
   15.66 +.endm		
   15.67 +
   15.68 +
   15.69 +.macro RESTORE_REST
   15.70 +	movq (%rsp),%r15
   15.71 +#	CFI_RESTORE r15
   15.72 +	movq 1*8(%rsp),%r14
   15.73 +#	CFI_RESTORE r14
   15.74 +	movq 2*8(%rsp),%r13
   15.75 +#	CFI_RESTORE r13
   15.76 +	movq 3*8(%rsp),%r12
   15.77 +#	CFI_RESTORE r12
   15.78 +	movq 4*8(%rsp),%rbp
   15.79 +#	CFI_RESTORE rbp
   15.80 +	movq 5*8(%rsp),%rbx
   15.81 +#	CFI_RESTORE rbx
   15.82 +	addq $REST_SKIP,%rsp
   15.83 +#	CFI_ADJUST_CFA_OFFSET	-(REST_SKIP)
   15.84 +.endm
   15.85 +
   15.86 +
   15.87 +#define ARG_SKIP 9*8
   15.88 +.macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0
   15.89 +	.if \skipr11
   15.90 +	.else
   15.91 +	movq (%rsp),%r11
   15.92 +#	CFI_RESTORE r11
   15.93 +	.endif
   15.94 +	.if \skipr8910
   15.95 +	.else
   15.96 +	movq 1*8(%rsp),%r10
   15.97 +#	CFI_RESTORE r10
   15.98 +	movq 2*8(%rsp),%r9
   15.99 +#	CFI_RESTORE r9
  15.100 +	movq 3*8(%rsp),%r8
  15.101 +#	CFI_RESTORE r8
  15.102 +	.endif
  15.103 +	.if \skiprax
  15.104 +	.else
  15.105 +	movq 4*8(%rsp),%rax
  15.106 +#	CFI_RESTORE rax
  15.107 +	.endif
  15.108 +	.if \skiprcx
  15.109 +	.else
  15.110 +	movq 5*8(%rsp),%rcx
  15.111 +#	CFI_RESTORE rcx
  15.112 +	.endif
  15.113 +	.if \skiprdx
  15.114 +	.else
  15.115 +	movq 6*8(%rsp),%rdx
  15.116 +#	CFI_RESTORE rdx
  15.117 +	.endif
  15.118 +	movq 7*8(%rsp),%rsi
  15.119 +#	CFI_RESTORE rsi
  15.120 +	movq 8*8(%rsp),%rdi
  15.121 +#	CFI_RESTORE rdi
  15.122 +	.if ARG_SKIP+\addskip > 0
  15.123 +	addq $ARG_SKIP+\addskip,%rsp
  15.124 +#	CFI_ADJUST_CFA_OFFSET	-(ARG_SKIP+\addskip)
  15.125 +	.endif
  15.126 +.endm	
  15.127 +
  15.128 +
  15.129 +.macro HYPERVISOR_IRET flag
  15.130 +#    testb $3,1*8(%rsp)    /* Don't need to do that in Mini-os, as */
  15.131 +#	jnz   2f               /* there is no userspace? */
  15.132 +	testl $NMI_MASK,2*8(%rsp)
  15.133 +	jnz   2f
  15.134 +
  15.135 +	testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
  15.136 +	jnz   1f
  15.137 +
  15.138 +	/* Direct iret to kernel space. Correct CS and SS. */
  15.139 +	orb   $3,1*8(%rsp)
  15.140 +	orb   $3,4*8(%rsp)
  15.141 +1:	iretq
  15.142 +
  15.143 +2:	/* Slow iret via hypervisor. */
  15.144 +	andl  $~NMI_MASK, 16(%rsp)
  15.145 +	pushq $\flag
  15.146 +	jmp  hypercall_page + (__HYPERVISOR_iret * 32)
  15.147 +.endm
  15.148 +
  15.149 +/*
  15.150 + * Exception entry point. This expects an error code/orig_rax on the stack
  15.151 + * and the exception handler in %rax.	
  15.152 + */ 		  				
  15.153 +ENTRY(error_entry)
  15.154 +#	_frame RDI
  15.155 +	/* rdi slot contains rax, oldrax contains error code */
  15.156 +	cld	
  15.157 +	subq  $14*8,%rsp
  15.158 +#	CFI_ADJUST_CFA_OFFSET	(14*8)
  15.159 +	movq %rsi,13*8(%rsp)
  15.160 +#	CFI_REL_OFFSET	rsi,RSI
  15.161 +	movq 14*8(%rsp),%rsi	/* load rax from rdi slot */
  15.162 +	movq %rdx,12*8(%rsp)
  15.163 +#	CFI_REL_OFFSET	rdx,RDX
  15.164 +	movq %rcx,11*8(%rsp)
  15.165 +#	CFI_REL_OFFSET	rcx,RCX
  15.166 +	movq %rsi,10*8(%rsp)	/* store rax */ 
  15.167 +#	CFI_REL_OFFSET	rax,RAX
  15.168 +	movq %r8, 9*8(%rsp)
  15.169 +#	CFI_REL_OFFSET	r8,R8
  15.170 +	movq %r9, 8*8(%rsp)
  15.171 +#	CFI_REL_OFFSET	r9,R9
  15.172 +	movq %r10,7*8(%rsp)
  15.173 +#	CFI_REL_OFFSET	r10,R10
  15.174 +	movq %r11,6*8(%rsp)
  15.175 +#	CFI_REL_OFFSET	r11,R11
  15.176 +	movq %rbx,5*8(%rsp) 
  15.177 +#	CFI_REL_OFFSET	rbx,RBX
  15.178 +	movq %rbp,4*8(%rsp) 
  15.179 +#	CFI_REL_OFFSET	rbp,RBP
  15.180 +	movq %r12,3*8(%rsp) 
  15.181 +#	CFI_REL_OFFSET	r12,R12
  15.182 +	movq %r13,2*8(%rsp) 
  15.183 +#	CFI_REL_OFFSET	r13,R13
  15.184 +	movq %r14,1*8(%rsp) 
  15.185 +#	CFI_REL_OFFSET	r14,R14
  15.186 +	movq %r15,(%rsp) 
  15.187 +#	CFI_REL_OFFSET	r15,R15
  15.188 +#if 0        
  15.189 +	cmpl $__KERNEL_CS,CS(%rsp)
  15.190 +	je  error_kernelspace
  15.191 +#endif        
  15.192 +error_call_handler:
  15.193 +	movq %rdi, RDI(%rsp)            
  15.194 +	movq %rsp,%rdi
  15.195 +	movq ORIG_RAX(%rsp),%rsi	# get error code 
  15.196 +	movq $-1,ORIG_RAX(%rsp)
  15.197 +	call *%rax
  15.198 +
  15.199 +.macro zeroentry sym
  15.200 +#	INTR_FRAME
  15.201 +    movq (%rsp),%rcx
  15.202 +    movq 8(%rsp),%r11
  15.203 +    addq $0x10,%rsp /* skip rcx and r11 */
  15.204 +	pushq $0	/* push error code/oldrax */ 
  15.205 +#	CFI_ADJUST_CFA_OFFSET 8
  15.206 +	pushq %rax	/* push real oldrax to the rdi slot */ 
  15.207 +#	CFI_ADJUST_CFA_OFFSET 8
  15.208 +	leaq  \sym(%rip),%rax
  15.209 +	jmp error_entry
  15.210 +#	CFI_ENDPROC
  15.211 +.endm	
  15.212 +
  15.213 +.macro errorentry sym
  15.214 +#	XCPT_FRAME
  15.215 +        movq (%rsp),%rcx
  15.216 +        movq 8(%rsp),%r11
  15.217 +        addq $0x10,%rsp /* rsp points to the error code */
  15.218 +	pushq %rax
  15.219 +#	CFI_ADJUST_CFA_OFFSET 8
  15.220 +	leaq  \sym(%rip),%rax
  15.221 +	jmp error_entry
  15.222 +#	CFI_ENDPROC
  15.223 +.endm
  15.224 +
  15.225 +#define XEN_GET_VCPU_INFO(reg)	movq HYPERVISOR_shared_info,reg
  15.226 +#define XEN_PUT_VCPU_INFO(reg)
  15.227 +#define XEN_PUT_VCPU_INFO_fixup
  15.228 +#define XEN_LOCKED_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
  15.229 +#define XEN_LOCKED_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
  15.230 +#define XEN_TEST_PENDING(reg)	testb $0xFF,evtchn_upcall_pending(reg)
  15.231 +
  15.232 +#define XEN_BLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  15.233 +                    			XEN_LOCKED_BLOCK_EVENTS(reg)	; \
  15.234 +    				            XEN_PUT_VCPU_INFO(reg)
  15.235 +
  15.236 +#define XEN_UNBLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  15.237 +                				XEN_LOCKED_UNBLOCK_EVENTS(reg)	; \
  15.238 +    			            	XEN_PUT_VCPU_INFO(reg)
  15.239 +
  15.240 +
  15.241 +
  15.242 +ENTRY(hypervisor_callback)
  15.243 +    zeroentry hypervisor_callback2
  15.244 +
  15.245 +ENTRY(hypervisor_callback2)
  15.246 +        movq %rdi, %rsp 
  15.247 +11:     movq %gs:8,%rax
  15.248 +        incl %gs:0
  15.249 +        cmovzq %rax,%rsp
  15.250 +        pushq %rdi
  15.251 +        call do_hypervisor_callback 
  15.252 +        popq %rsp
  15.253 +        decl %gs:0
  15.254 +        jmp error_exit
  15.255 +
  15.256 +#        ALIGN
  15.257 +restore_all_enable_events:  
  15.258 +	XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
  15.259 +
  15.260 +scrit:	/**** START OF CRITICAL REGION ****/
  15.261 +	XEN_TEST_PENDING(%rsi)
  15.262 +	jnz  14f			# process more events if necessary...
  15.263 +	XEN_PUT_VCPU_INFO(%rsi)
  15.264 +        RESTORE_ARGS 0,8,0
  15.265 +        HYPERVISOR_IRET 0
  15.266 +        
  15.267 +14:	XEN_LOCKED_BLOCK_EVENTS(%rsi)
  15.268 +	XEN_PUT_VCPU_INFO(%rsi)
  15.269 +	SAVE_REST
  15.270 +        movq %rsp,%rdi                  # set the argument again
  15.271 +	jmp  11b
  15.272 +ecrit:  /**** END OF CRITICAL REGION ****/
  15.273 +
  15.274 +
  15.275 +retint_kernel:
  15.276 +retint_restore_args:
  15.277 +	movl EFLAGS-REST_SKIP(%rsp), %eax
  15.278 +	shr $9, %eax			# EAX[0] == IRET_EFLAGS.IF
  15.279 +	XEN_GET_VCPU_INFO(%rsi)
  15.280 +	andb evtchn_upcall_mask(%rsi),%al
  15.281 +	andb $1,%al			# EAX[0] == IRET_EFLAGS.IF & event_mask
  15.282 +	jnz restore_all_enable_events	#        != 0 => enable event delivery
  15.283 +	XEN_PUT_VCPU_INFO(%rsi)
  15.284 +		
  15.285 +	RESTORE_ARGS 0,8,0
  15.286 +	HYPERVISOR_IRET 0
  15.287 +
  15.288 +
  15.289 +error_exit:		
  15.290 +	RESTORE_REST
  15.291 +/*	cli */
  15.292 +	XEN_BLOCK_EVENTS(%rsi)		
  15.293 +	jmp retint_kernel
  15.294 +
  15.295 +
  15.296 +
  15.297 +ENTRY(failsafe_callback)
  15.298 +        popq  %rcx
  15.299 +        popq  %r11
  15.300 +        iretq
  15.301 +
  15.302 +
  15.303 +ENTRY(coprocessor_error)
  15.304 +        zeroentry do_coprocessor_error
  15.305 +
  15.306 +
  15.307 +ENTRY(simd_coprocessor_error)
  15.308 +        zeroentry do_simd_coprocessor_error
  15.309 +
  15.310 +
  15.311 +ENTRY(device_not_available)
  15.312 +        zeroentry do_device_not_available
  15.313 +
  15.314 +
  15.315 +ENTRY(debug)
  15.316 +#       INTR_FRAME
  15.317 +#       CFI_ADJUST_CFA_OFFSET 8 */
  15.318 +        zeroentry do_debug
  15.319 +#       CFI_ENDPROC
  15.320 +
  15.321 +
  15.322 +ENTRY(int3)
  15.323 +#       INTR_FRAME
  15.324 +#       CFI_ADJUST_CFA_OFFSET 8 */
  15.325 +        zeroentry do_int3
  15.326 +#       CFI_ENDPROC
  15.327 +
  15.328 +ENTRY(overflow)
  15.329 +        zeroentry do_overflow
  15.330 +
  15.331 +
  15.332 +ENTRY(bounds)
  15.333 +        zeroentry do_bounds
  15.334 +    
  15.335 +    
  15.336 +ENTRY(invalid_op)
  15.337 +        zeroentry do_invalid_op
  15.338 +
  15.339 +
  15.340 +ENTRY(coprocessor_segment_overrun)
  15.341 +        zeroentry do_coprocessor_segment_overrun
  15.342 +
  15.343 +
  15.344 +ENTRY(invalid_TSS)
  15.345 +        errorentry do_invalid_TSS
  15.346 +
  15.347 +
  15.348 +ENTRY(segment_not_present)
  15.349 +        errorentry do_segment_not_present
  15.350 +
  15.351 +
  15.352 +/* runs on exception stack */
  15.353 +ENTRY(stack_segment)
  15.354 +#       XCPT_FRAME
  15.355 +        errorentry do_stack_segment
  15.356 +#       CFI_ENDPROC
  15.357 +                    
  15.358 +
  15.359 +ENTRY(general_protection)
  15.360 +        errorentry do_general_protection
  15.361 +
  15.362 +
  15.363 +ENTRY(alignment_check)
  15.364 +        errorentry do_alignment_check
  15.365 +
  15.366 +
  15.367 +ENTRY(divide_error)
  15.368 +        zeroentry do_divide_error
  15.369 +
  15.370 +
  15.371 +ENTRY(spurious_interrupt_bug)
  15.372 +        zeroentry do_spurious_interrupt_bug
  15.373 +            
  15.374 +
  15.375 +ENTRY(page_fault)
  15.376 +        errorentry do_page_fault
  15.377 +
  15.378 +
  15.379 +
  15.380 +
  15.381 +
  15.382 +ENTRY(thread_starter)
  15.383 +        popq %rdi
  15.384 +        popq %rbx
  15.385 +        call *%rbx
  15.386 +        call exit_thread 
  15.387 +        
  15.388 +
    16.1 --- a/extras/mini-os/gnttab.c	Thu Jan 18 09:54:33 2007 +0000
    16.2 +++ b/extras/mini-os/gnttab.c	Thu Jan 18 15:18:07 2007 +0000
    16.3 @@ -23,39 +23,32 @@
    16.4  
    16.5  #define NR_GRANT_FRAMES 4
    16.6  #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    16.7 -#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
    16.8  
    16.9  static grant_entry_t *gnttab_table;
   16.10  static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
   16.11 -static grant_ref_t gnttab_free_head;
   16.12 +
   16.13 +static void
   16.14 +put_free_entry(grant_ref_t ref)
   16.15 +{
   16.16 +    gnttab_list[ref] = gnttab_list[0];
   16.17 +    gnttab_list[0]  = ref;
   16.18 +
   16.19 +}
   16.20  
   16.21  static grant_ref_t
   16.22 -get_free_entries(int count)
   16.23 +get_free_entry(void)
   16.24  {
   16.25 -    grant_ref_t ref;
   16.26 -    grant_ref_t head;
   16.27 -
   16.28 -    ref = head = gnttab_free_head;
   16.29 -    while (count-- > 1)
   16.30 -	head = gnttab_list[head];
   16.31 -    gnttab_free_head = gnttab_list[head];
   16.32 -    gnttab_list[head] = GNTTAB_LIST_END;
   16.33 +    unsigned int ref = gnttab_list[0];
   16.34 +    gnttab_list[0] = gnttab_list[ref];
   16.35      return ref;
   16.36  }
   16.37  
   16.38 -static void
   16.39 -put_free_entry(grant_ref_t gref)
   16.40 -{
   16.41 -    gnttab_list[gref] = gnttab_free_head;
   16.42 -    gnttab_free_head = gref;
   16.43 -}
   16.44 -
   16.45  grant_ref_t
   16.46  gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
   16.47  {
   16.48      grant_ref_t ref;
   16.49  
   16.50 -    ref = get_free_entries(1);
   16.51 +    ref = get_free_entry();
   16.52      gnttab_table[ref].frame = frame;
   16.53      gnttab_table[ref].domid = domid;
   16.54      wmb();
   16.55 @@ -70,7 +63,7 @@ gnttab_grant_transfer(domid_t domid, uns
   16.56  {
   16.57      grant_ref_t ref;
   16.58  
   16.59 -    ref = get_free_entries(1);
   16.60 +    ref = get_free_entry();
   16.61      gnttab_table[ref].frame = pfn;
   16.62      gnttab_table[ref].domid = domid;
   16.63      wmb();
   16.64 @@ -157,8 +150,7 @@ init_gnttab(void)
   16.65      int i;
   16.66  
   16.67      for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
   16.68 -	gnttab_list[i] = i + 1;
   16.69 -    gnttab_free_head = NR_RESERVED_ENTRIES;
   16.70 +        put_free_entry(i);
   16.71  
   16.72      setup.dom = DOMID_SELF;
   16.73      setup.nr_frames = NR_GRANT_FRAMES;
    17.1 --- a/extras/mini-os/include/hypervisor.h	Thu Jan 18 09:54:33 2007 +0000
    17.2 +++ b/extras/mini-os/include/hypervisor.h	Thu Jan 18 15:18:07 2007 +0000
    17.3 @@ -15,7 +15,6 @@
    17.4  
    17.5  #include <types.h>
    17.6  #include <xen/xen.h>
    17.7 -#include <xen/dom0_ops.h>
    17.8  #if defined(__i386__)
    17.9  #include <hypercall-x86_32.h>
   17.10  #elif defined(__x86_64__)
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/extras/mini-os/include/netfront.h	Thu Jan 18 15:18:07 2007 +0000
    18.3 @@ -0,0 +1,2 @@
    18.4 +void init_netfront(void*);
    18.5 +void netfront_xmit(unsigned char* data,int len);
    19.1 --- a/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h	Thu Jan 18 09:54:33 2007 +0000
    19.2 +++ b/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h	Thu Jan 18 15:18:07 2007 +0000
    19.3 @@ -182,14 +182,6 @@ HYPERVISOR_set_timer_op(
    19.4  }
    19.5  
    19.6  static inline int
    19.7 -HYPERVISOR_dom0_op(
    19.8 -	dom0_op_t *dom0_op)
    19.9 -{
   19.10 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   19.11 -	return _hypercall1(int, dom0_op, dom0_op);
   19.12 -}
   19.13 -
   19.14 -static inline int
   19.15  HYPERVISOR_set_debugreg(
   19.16  	int reg, unsigned long value)
   19.17  {
    20.1 --- a/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h	Thu Jan 18 09:54:33 2007 +0000
    20.2 +++ b/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h	Thu Jan 18 15:18:07 2007 +0000
    20.3 @@ -184,14 +184,6 @@ HYPERVISOR_set_timer_op(
    20.4  }
    20.5  
    20.6  static inline int
    20.7 -HYPERVISOR_dom0_op(
    20.8 -	dom0_op_t *dom0_op)
    20.9 -{
   20.10 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   20.11 -	return _hypercall1(int, dom0_op, dom0_op);
   20.12 -}
   20.13 -
   20.14 -static inline int
   20.15  HYPERVISOR_set_debugreg(
   20.16  	int reg, unsigned long value)
   20.17  {
    21.1 --- a/extras/mini-os/include/xenbus.h	Thu Jan 18 09:54:33 2007 +0000
    21.2 +++ b/extras/mini-os/include/xenbus.h	Thu Jan 18 15:18:07 2007 +0000
    21.3 @@ -12,6 +12,9 @@ void init_xenbus(void);
    21.4     set to a malloc'd copy of the value. */
    21.5  char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
    21.6  
    21.7 +char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
    21.8 +char* xenbus_wait_for_value(const char*,const char*);
    21.9 +
   21.10  /* Associates a value with a path.  Returns a malloc'd error string on
   21.11     failure. */
   21.12  char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
    22.1 --- a/extras/mini-os/kernel.c	Thu Jan 18 09:54:33 2007 +0000
    22.2 +++ b/extras/mini-os/kernel.c	Thu Jan 18 15:18:07 2007 +0000
    22.3 @@ -37,6 +37,7 @@
    22.4  #include <sched.h>
    22.5  #include <xenbus.h>
    22.6  #include <gnttab.h>
    22.7 +#include <netfront.h>
    22.8  #include <xen/features.h>
    22.9  #include <xen/version.h>
   22.10  
   22.11 @@ -61,13 +62,13 @@ void setup_xen_features(void)
   22.12  
   22.13  void test_xenbus(void);
   22.14  
   22.15 -void xenbus_tester(void *p)
   22.16 +static void xenbus_tester(void *p)
   22.17  {
   22.18      printk("Xenbus tests disabled, because of a Xend bug.\n");
   22.19      /* test_xenbus(); */
   22.20  }
   22.21  
   22.22 -void periodic_thread(void *p)
   22.23 +static void periodic_thread(void *p)
   22.24  {
   22.25      struct timeval tv;
   22.26      printk("Periodic thread started.\n");
   22.27 @@ -79,12 +80,18 @@ void periodic_thread(void *p)
   22.28      }
   22.29  }
   22.30  
   22.31 +static void netfront_thread(void *p)
   22.32 +{
   22.33 +    init_netfront(&start_info);
   22.34 +}
   22.35 +
   22.36  /* This should be overridden by the application we are linked against. */
   22.37  __attribute__((weak)) int app_main(start_info_t *si)
   22.38  {
   22.39      printk("Dummy main: start_info=%p\n", si);
   22.40      create_thread("xenbus_tester", xenbus_tester, si);
   22.41      create_thread("periodic_thread", periodic_thread, si);
   22.42 +    create_thread("netfront", netfront_thread, si);
   22.43      return 0;
   22.44  }
   22.45  
    23.1 --- a/extras/mini-os/minios-x86_32.lds	Thu Jan 18 09:54:33 2007 +0000
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,45 +0,0 @@
    23.4 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    23.5 -OUTPUT_ARCH(i386)
    23.6 -ENTRY(_start)
    23.7 -SECTIONS
    23.8 -{
    23.9 -  . = 0x0;
   23.10 -  _text = .;			/* Text and read-only data */
   23.11 -  .text : {
   23.12 -	*(.text)
   23.13 -	*(.gnu.warning)
   23.14 -	} = 0x9090
   23.15 -
   23.16 -  _etext = .;			/* End of text section */
   23.17 -
   23.18 -  .rodata : { *(.rodata) *(.rodata.*) }
   23.19 -
   23.20 -  .data : {			/* Data */
   23.21 -	*(.data)
   23.22 -	CONSTRUCTORS
   23.23 -	}
   23.24 -
   23.25 -  _edata = .;			/* End of data section */
   23.26 -
   23.27 -  __bss_start = .;		/* BSS */
   23.28 -  .bss : {
   23.29 -	*(.bss)
   23.30 -	}
   23.31 -  _end = . ;
   23.32 -
   23.33 -  /* Sections to be discarded */
   23.34 -  /DISCARD/ : {
   23.35 -	*(.text.exit)
   23.36 -	*(.data.exit)
   23.37 -	*(.exitcall.exit)
   23.38 -	}
   23.39 -
   23.40 -  /* Stabs debugging sections.  */
   23.41 -  .stab 0 : { *(.stab) }
   23.42 -  .stabstr 0 : { *(.stabstr) }
   23.43 -  .stab.excl 0 : { *(.stab.excl) }
   23.44 -  .stab.exclstr 0 : { *(.stab.exclstr) }
   23.45 -  .stab.index 0 : { *(.stab.index) }
   23.46 -  .stab.indexstr 0 : { *(.stab.indexstr) }
   23.47 -  .comment 0 : { *(.comment) }
   23.48 -}
    24.1 --- a/extras/mini-os/minios-x86_64.lds	Thu Jan 18 09:54:33 2007 +0000
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,54 +0,0 @@
    24.4 -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
    24.5 -OUTPUT_ARCH(i386:x86-64)
    24.6 -ENTRY(_start)
    24.7 -SECTIONS
    24.8 -{
    24.9 -  . = 0x0;
   24.10 -  _text = .;			/* Text and read-only data */
   24.11 -  .text : {
   24.12 -	*(.text)
   24.13 -	*(.gnu.warning)
   24.14 -	} = 0x9090
   24.15 -
   24.16 -  _etext = .;			/* End of text section */
   24.17 -
   24.18 -  .rodata : { *(.rodata) *(.rodata.*) }
   24.19 -
   24.20 -  .data : {			/* Data */
   24.21 -	*(.data)
   24.22 -	CONSTRUCTORS
   24.23 -	}
   24.24 -
   24.25 -  _edata = .;			/* End of data section */
   24.26 -
   24.27 -  . = ALIGN(8192);		/* init_task */
   24.28 -  .data.init_task : { *(.data.init_task) }
   24.29 -
   24.30 -  . = ALIGN(4096);
   24.31 -  .data.page_aligned : { *(.data.idt) }
   24.32 -
   24.33 -  . = ALIGN(32);
   24.34 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   24.35 -
   24.36 -  __bss_start = .;		/* BSS */
   24.37 -  .bss : {
   24.38 -	*(.bss)
   24.39 -	}
   24.40 -  _end = . ;
   24.41 -
   24.42 -  /* Sections to be discarded */
   24.43 -  /DISCARD/ : {
   24.44 -	*(.text.exit)
   24.45 -	*(.data.exit)
   24.46 -	*(.exitcall.exit)
   24.47 -	}
   24.48 -
   24.49 -  /* Stabs debugging sections.  */
   24.50 -  .stab 0 : { *(.stab) }
   24.51 -  .stabstr 0 : { *(.stabstr) }
   24.52 -  .stab.excl 0 : { *(.stab.excl) }
   24.53 -  .stab.exclstr 0 : { *(.stab.exclstr) }
   24.54 -  .stab.index 0 : { *(.stab.index) }
   24.55 -  .stab.indexstr 0 : { *(.stab.indexstr) }
   24.56 -  .comment 0 : { *(.comment) }
   24.57 -}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/extras/mini-os/minios.mk	Thu Jan 18 15:18:07 2007 +0000
    25.3 @@ -0,0 +1,62 @@
    25.4 +#
    25.5 +# The file contains the common make rules for building mini-os.
    25.6 +#
    25.7 +
    25.8 +debug = y
    25.9 +
   25.10 +# Define some default flags.
   25.11 +# NB. '-Wcast-qual' is nasty, so I omitted it.
   25.12 +DEF_CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
   25.13 +DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
   25.14 +DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
   25.15 +
   25.16 +DEF_ASFLAGS = -D__ASSEMBLY__
   25.17 +
   25.18 +ifeq ($(debug),y)
   25.19 +DEF_CFLAGS += -g
   25.20 +else
   25.21 +DEF_CFLAGS += -O3
   25.22 +endif
   25.23 +
   25.24 +# Build the CFLAGS and ASFLAGS for compiling and assembling.
   25.25 +# DEF_... flags are the common mini-os flags,
   25.26 +# ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
   25.27 +CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
   25.28 +ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
   25.29 +
   25.30 +# The path pointing to the architecture specific header files.
   25.31 +ARCH_SPEC_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
   25.32 +
   25.33 +# Find all header files for checking dependencies.
   25.34 +HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h)
   25.35 +HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h)
   25.36 +HDRS += $(wildcard $(ARCH_SPEC_INC)/*.h)
   25.37 +# For special wanted header directories.
   25.38 +extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
   25.39 +HDRS += $(extra_heads)
   25.40 +
   25.41 +# Add the special header directories to the include paths.
   25.42 +extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
   25.43 +override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_SPEC_INC)	$(extra_incl)
   25.44 +
   25.45 +# The name of the architecture specific library.
   25.46 +# This is on x86_32: libx86_32.a
   25.47 +# $(ARCH_LIB) has to built in the architecture specific directory.
   25.48 +ARCH_LIB_NAME = $(TARGET_ARCH)
   25.49 +ARCH_LIB := lib$(ARCH_LIB_NAME).a
   25.50 +
   25.51 +# This object contains the entrypoint for startup from Xen.
   25.52 +# $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
   25.53 +HEAD_ARCH_OBJ := $(TARGET_ARCH).o
   25.54 +HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
   25.55 +
   25.56 +
   25.57 +%.o: %.c $(HDRS) Makefile $(SPEC_DEPENDS)
   25.58 +	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
   25.59 +
   25.60 +%.o: %.S $(HDRS) Makefile $(SPEC_DEPENDS)
   25.61 +	$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
   25.62 +
   25.63 +
   25.64 +
   25.65 +
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/extras/mini-os/netfront.c	Thu Jan 18 15:18:07 2007 +0000
    26.3 @@ -0,0 +1,455 @@
    26.4 +/* Minimal network driver for Mini-OS. 
    26.5 + * Copyright (c) 2006-2007 Jacob Gorm Hansen, University of Copenhagen.
    26.6 + * Based on netfront.c from Xen Linux.
    26.7 + *
    26.8 + * Does not handle fragments or extras.
    26.9 + */
   26.10 +
   26.11 +#include <os.h>
   26.12 +#include <xenbus.h>
   26.13 +#include <events.h>
   26.14 +#include <errno.h>
   26.15 +#include <xen/io/netif.h>
   26.16 +#include <gnttab.h>
   26.17 +#include <xmalloc.h>
   26.18 +#include <time.h>
   26.19 +
   26.20 +void init_rx_buffers(void);
   26.21 +
   26.22 +struct net_info {
   26.23 +    struct netif_tx_front_ring tx;
   26.24 +    struct netif_rx_front_ring rx;
   26.25 +    int tx_ring_ref;
   26.26 +    int rx_ring_ref;
   26.27 +    unsigned int evtchn, local_port;
   26.28 +
   26.29 +} net_info;
   26.30 +
   26.31 +
   26.32 +char* xenbus_printf(xenbus_transaction_t xbt,
   26.33 +        char* node,char* path,
   26.34 +        char* fmt,unsigned int arg)
   26.35 +{
   26.36 +    char fullpath[256];
   26.37 +    char val[256];
   26.38 +
   26.39 +    sprintf(fullpath,"%s/%s",node,path);
   26.40 +    sprintf(val,fmt,arg);
   26.41 +    xenbus_write(xbt,fullpath,val);
   26.42 +
   26.43 +    return NULL;
   26.44 +}
   26.45 +
   26.46 +
   26.47 +#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
   26.48 +#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
   26.49 +#define GRANT_INVALID_REF 0
   26.50 +
   26.51 +
   26.52 +unsigned short rx_freelist[NET_RX_RING_SIZE];
   26.53 +unsigned short tx_freelist[NET_TX_RING_SIZE];
   26.54 +
   26.55 +struct net_buffer {
   26.56 +    void* page;
   26.57 +    int gref;
   26.58 +};
   26.59 +struct net_buffer rx_buffers[NET_RX_RING_SIZE];
   26.60 +struct net_buffer tx_buffers[NET_TX_RING_SIZE];
   26.61 +
   26.62 +static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
   26.63 +{
   26.64 +    freelist[id] = freelist[0];
   26.65 +    freelist[0]  = id;
   26.66 +}
   26.67 +
   26.68 +static inline unsigned short get_id_from_freelist(unsigned short* freelist)
   26.69 +{
   26.70 +    unsigned int id = freelist[0];
   26.71 +    freelist[0] = freelist[id];
   26.72 +    return id;
   26.73 +}
   26.74 +
   26.75 +__attribute__((weak)) void netif_rx(unsigned char* data,int len)
   26.76 +{
   26.77 +    printk("%d bytes incoming at %p\n",len,data);
   26.78 +}
   26.79 +
   26.80 +__attribute__((weak)) void net_app_main(void*si,unsigned char*mac) {}
   26.81 +
   26.82 +static inline int xennet_rxidx(RING_IDX idx)
   26.83 +{
   26.84 +    return idx & (NET_RX_RING_SIZE - 1);
   26.85 +}
   26.86 +
   26.87 +void network_rx(void)
   26.88 +{
   26.89 +    struct net_info *np = &net_info;
   26.90 +    RING_IDX rp,cons;
   26.91 +    struct netif_rx_response *rx;
   26.92 +
   26.93 +
   26.94 +moretodo:
   26.95 +    rp = np->rx.sring->rsp_prod;
   26.96 +    rmb(); /* Ensure we see queued responses up to 'rp'. */
   26.97 +    cons = np->rx.rsp_cons;
   26.98 +
   26.99 +    int nr_consumed=0;
  26.100 +    while ((cons != rp))
  26.101 +    {
  26.102 +        struct net_buffer* buf;
  26.103 +        unsigned char* page;
  26.104 +
  26.105 +        rx = RING_GET_RESPONSE(&np->rx, cons);
  26.106 +
  26.107 +        if (rx->flags & NETRXF_extra_info)
  26.108 +        {
  26.109 +            printk("+++++++++++++++++++++ we have extras!\n");
  26.110 +            continue;
  26.111 +        }
  26.112 +
  26.113 +
  26.114 +        if (rx->status == NETIF_RSP_NULL) continue;
  26.115 +
  26.116 +        int id = rx->id;
  26.117 +
  26.118 +        buf = &rx_buffers[id];
  26.119 +        page = (unsigned char*)buf->page;
  26.120 +        gnttab_end_access(buf->gref);
  26.121 +
  26.122 +        if(rx->status>0)
  26.123 +        {
  26.124 +            netif_rx(page+rx->offset,rx->status);
  26.125 +        }
  26.126 +
  26.127 +        add_id_to_freelist(id,rx_freelist);
  26.128 +
  26.129 +        nr_consumed++;
  26.130 +
  26.131 +        ++cons;
  26.132 +    }
  26.133 +    np->rx.rsp_cons=rp;
  26.134 +
  26.135 +    int more;
  26.136 +    RING_FINAL_CHECK_FOR_RESPONSES(&np->rx,more);
  26.137 +    if(more) goto moretodo;
  26.138 +
  26.139 +    RING_IDX req_prod = np->rx.req_prod_pvt;
  26.140 +
  26.141 +    int i;
  26.142 +    netif_rx_request_t *req;
  26.143 +
  26.144 +    for(i=0; i<nr_consumed; i++)
  26.145 +    {
  26.146 +        int id = xennet_rxidx(req_prod + i);
  26.147 +        req = RING_GET_REQUEST(&np->rx, req_prod + i);
  26.148 +        struct net_buffer* buf = &rx_buffers[id];
  26.149 +        void* page = buf->page;
  26.150 +
  26.151 +        buf->gref = req->gref = 
  26.152 +            gnttab_grant_access(0,virt_to_mfn(page),0);
  26.153 +
  26.154 +        req->id = id;
  26.155 +    }
  26.156 +
  26.157 +    wmb();
  26.158 +
  26.159 +    np->rx.req_prod_pvt = req_prod + i;
  26.160 +    
  26.161 +    int notify;
  26.162 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
  26.163 +    if (notify)
  26.164 +        notify_remote_via_evtchn(np->evtchn);
  26.165 +
  26.166 +}
  26.167 +
  26.168 +void network_tx_buf_gc(void)
  26.169 +{
  26.170 +
  26.171 +
  26.172 +    RING_IDX cons, prod;
  26.173 +    unsigned short id;
  26.174 +    struct net_info *np = &net_info;
  26.175 +
  26.176 +    do {
  26.177 +        prod = np->tx.sring->rsp_prod;
  26.178 +        rmb(); /* Ensure we see responses up to 'rp'. */
  26.179 +
  26.180 +        for (cons = np->tx.rsp_cons; cons != prod; cons++) 
  26.181 +        {
  26.182 +            struct netif_tx_response *txrsp;
  26.183 +
  26.184 +            txrsp = RING_GET_RESPONSE(&np->tx, cons);
  26.185 +            if (txrsp->status == NETIF_RSP_NULL)
  26.186 +                continue;
  26.187 +
  26.188 +            id  = txrsp->id;
  26.189 +            struct net_buffer* buf = &tx_buffers[id];
  26.190 +            gnttab_end_access(buf->gref);
  26.191 +            buf->gref=GRANT_INVALID_REF;
  26.192 +
  26.193 +            add_id_to_freelist(id,tx_freelist);
  26.194 +        }
  26.195 +
  26.196 +        np->tx.rsp_cons = prod;
  26.197 +
  26.198 +        /*
  26.199 +         * Set a new event, then check for race with update of tx_cons.
  26.200 +         * Note that it is essential to schedule a callback, no matter
  26.201 +         * how few tx_buffers are pending. Even if there is space in the
  26.202 +         * transmit ring, higher layers may be blocked because too much
  26.203 +         * data is outstanding: in such cases notification from Xen is
  26.204 +         * likely to be the only kick that we'll get.
  26.205 +         */
  26.206 +        np->tx.sring->rsp_event =
  26.207 +            prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
  26.208 +        mb();
  26.209 +    } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
  26.210 +
  26.211 +
  26.212 +}
  26.213 +
  26.214 +void netfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
  26.215 +{
  26.216 +    int flags;
  26.217 +
  26.218 +    local_irq_save(flags);
  26.219 +
  26.220 +    network_tx_buf_gc();
  26.221 +    network_rx();
  26.222 +
  26.223 +    local_irq_restore(flags);
  26.224 +}
  26.225 +
  26.226 +char* backend;
  26.227 +
  26.228 +void init_netfront(void* si)
  26.229 +{
  26.230 +    xenbus_transaction_t xbt;
  26.231 +    struct net_info* info = &net_info;
  26.232 +    char* err;
  26.233 +    char* message=NULL;
  26.234 +    char nodename[] = "device/vif/0";
  26.235 +    struct netif_tx_sring *txs;
  26.236 +    struct netif_rx_sring *rxs;
  26.237 +    int retry=0;
  26.238 +    int i;
  26.239 +    char* mac;
  26.240 +    char* msg;
  26.241 +
  26.242 +    printk("************************ NETFRONT **********\n\n\n");
  26.243 +
  26.244 +    for(i=0;i<NET_TX_RING_SIZE;i++)
  26.245 +    {
  26.246 +        add_id_to_freelist(i,tx_freelist);
  26.247 +        tx_buffers[i].page = (char*)alloc_page();
  26.248 +    }
  26.249 +
  26.250 +    for(i=0;i<NET_RX_RING_SIZE;i++)
  26.251 +    {
  26.252 +        add_id_to_freelist(i,rx_freelist);
  26.253 +        rx_buffers[i].page = (char*)alloc_page();
  26.254 +    }
  26.255 +
  26.256 +    txs = (struct netif_tx_sring*) alloc_page();
  26.257 +    rxs = (struct netif_rx_sring *) alloc_page();
  26.258 +    memset(txs,0,PAGE_SIZE);
  26.259 +    memset(rxs,0,PAGE_SIZE);
  26.260 +
  26.261 +
  26.262 +    SHARED_RING_INIT(txs);
  26.263 +    SHARED_RING_INIT(rxs);
  26.264 +    FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
  26.265 +    FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
  26.266 +
  26.267 +    info->tx_ring_ref = gnttab_grant_access(0,virt_to_mfn(txs),0);
  26.268 +    info->rx_ring_ref = gnttab_grant_access(0,virt_to_mfn(rxs),0);
  26.269 +
  26.270 +    evtchn_alloc_unbound_t op;
  26.271 +    op.dom = DOMID_SELF;
  26.272 +    op.remote_dom = 0;
  26.273 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
  26.274 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
  26.275 +    info->local_port = bind_evtchn(op.port, netfront_handler, NULL);
  26.276 +    info->evtchn=op.port;
  26.277 +
  26.278 +again:
  26.279 +    err = xenbus_transaction_start(&xbt);
  26.280 +    if (err) {
  26.281 +        printk("starting transaction\n");
  26.282 +    }
  26.283 +
  26.284 +    err = xenbus_printf(xbt, nodename, "tx-ring-ref","%u",
  26.285 +                info->tx_ring_ref);
  26.286 +    if (err) {
  26.287 +        message = "writing tx ring-ref";
  26.288 +        goto abort_transaction;
  26.289 +    }
  26.290 +    err = xenbus_printf(xbt, nodename, "rx-ring-ref","%u",
  26.291 +                info->rx_ring_ref);
  26.292 +    if (err) {
  26.293 +        message = "writing rx ring-ref";
  26.294 +        goto abort_transaction;
  26.295 +    }
  26.296 +    err = xenbus_printf(xbt, nodename,
  26.297 +                "event-channel", "%u", info->evtchn);
  26.298 +    if (err) {
  26.299 +        message = "writing event-channel";
  26.300 +        goto abort_transaction;
  26.301 +    }
  26.302 +
  26.303 +    err = xenbus_printf(xbt, nodename, "request-rx-copy", "%u", 1);
  26.304 +
  26.305 +    if (err) {
  26.306 +        message = "writing request-rx-copy";
  26.307 +        goto abort_transaction;
  26.308 +    }
  26.309 +
  26.310 +    err = xenbus_printf(xbt, nodename, "state", "%u",
  26.311 +            4); /* connected */
  26.312 +
  26.313 +
  26.314 +    err = xenbus_transaction_end(xbt, 0, &retry);
  26.315 +    if (retry) {
  26.316 +            goto again;
  26.317 +        printk("completing transaction\n");
  26.318 +    }
  26.319 +
  26.320 +    goto done;
  26.321 +
  26.322 +abort_transaction:
  26.323 +    xenbus_transaction_end(xbt, 1, &retry);
  26.324 +
  26.325 +done:
  26.326 +
  26.327 +    msg = xenbus_read(XBT_NIL, "device/vif/0/backend", &backend);
  26.328 +    msg = xenbus_read(XBT_NIL, "device/vif/0/mac", &mac);
  26.329 +
  26.330 +    printk("backend at %s\n",backend);
  26.331 +    printk("mac is %s\n",mac);
  26.332 +
  26.333 +    char *res;
  26.334 +    char path[256];
  26.335 +    sprintf(path,"%s/state",backend);
  26.336 +
  26.337 +    xenbus_watch_path(XBT_NIL, path);
  26.338 +
  26.339 +    xenbus_wait_for_value(path,"4");
  26.340 +
  26.341 +    //free(backend);
  26.342 +    free(res);
  26.343 +
  26.344 +    printk("**************************\n");
  26.345 +
  26.346 +    init_rx_buffers();
  26.347 +
  26.348 +    unsigned char rawmac[6];
  26.349 +    sscanf(mac,"%x:%x:%x:%x:%x:%x",
  26.350 +            &rawmac[0],
  26.351 +            &rawmac[1],
  26.352 +            &rawmac[2],
  26.353 +            &rawmac[3],
  26.354 +            &rawmac[4],
  26.355 +            &rawmac[5]);
  26.356 +
  26.357 +    net_app_main(si,rawmac);
  26.358 +}
  26.359 +
  26.360 +void shutdown_netfront(void)
  26.361 +{
  26.362 +    //xenbus_transaction_t xbt;
  26.363 +    char* err;
  26.364 +    char nodename[] = "device/vif/0";
  26.365 +
  26.366 +    char path[256];
  26.367 +
  26.368 +    printk("close network: backend at %s\n",backend);
  26.369 +
  26.370 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); /* closing */
  26.371 +    sprintf(path,"%s/state",backend);
  26.372 +
  26.373 +    xenbus_wait_for_value(path,"6");
  26.374 +
  26.375 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
  26.376 +
  26.377 +    xenbus_wait_for_value(path,"2");
  26.378 +
  26.379 +    unbind_all_ports();
  26.380 +
  26.381 +}
  26.382 +
  26.383 +
  26.384 +void init_rx_buffers(void)
  26.385 +{
  26.386 +    struct net_info* np = &net_info;
  26.387 +    int i, requeue_idx;
  26.388 +    netif_rx_request_t *req;
  26.389 +    int notify;
  26.390 +
  26.391 +    np->rx.req_prod_pvt = requeue_idx;
  26.392 +
  26.393 +
  26.394 +    /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
  26.395 +    for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) 
  26.396 +    {
  26.397 +        struct net_buffer* buf = &rx_buffers[requeue_idx];
  26.398 +        req = RING_GET_REQUEST(&np->rx, requeue_idx);
  26.399 +
  26.400 +        buf->gref = req->gref = 
  26.401 +            gnttab_grant_access(0,virt_to_mfn(buf->page),0);
  26.402 +
  26.403 +        req->id = requeue_idx;
  26.404 +
  26.405 +        requeue_idx++;
  26.406 +    }
  26.407 +
  26.408 +    np->rx.req_prod_pvt = requeue_idx;
  26.409 +
  26.410 +
  26.411 +
  26.412 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
  26.413 +
  26.414 +    if(notify) 
  26.415 +        notify_remote_via_evtchn(np->evtchn);
  26.416 +
  26.417 +    np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
  26.418 +
  26.419 +
  26.420 +}
  26.421 +
  26.422 +
  26.423 +void netfront_xmit(unsigned char* data,int len)
  26.424 +{
  26.425 +    int flags;
  26.426 +    local_irq_save(flags);
  26.427 +
  26.428 +    struct net_info* info = &net_info;
  26.429 +    struct netif_tx_request *tx;
  26.430 +    RING_IDX i = info->tx.req_prod_pvt;
  26.431 +    int notify;
  26.432 +    int id = get_id_from_freelist(tx_freelist);
  26.433 +    struct net_buffer* buf = &tx_buffers[id];
  26.434 +    void* page = buf->page;
  26.435 +
  26.436 +    tx = RING_GET_REQUEST(&info->tx, i);
  26.437 +
  26.438 +    memcpy(page,data,len);
  26.439 +
  26.440 +    buf->gref = 
  26.441 +        tx->gref = gnttab_grant_access(0,virt_to_mfn(page),0);
  26.442 +
  26.443 +    tx->offset=0;
  26.444 +    tx->size = len;
  26.445 +    tx->flags=0;
  26.446 +    tx->id = id;
  26.447 +    info->tx.req_prod_pvt = i + 1;
  26.448 +
  26.449 +    wmb();
  26.450 +
  26.451 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->tx, notify);
  26.452 +
  26.453 +    if(notify) notify_remote_via_evtchn(info->evtchn);
  26.454 +
  26.455 +    network_tx_buf_gc();
  26.456 +
  26.457 +    local_irq_restore(flags);
  26.458 +}
    27.1 --- a/extras/mini-os/x86_32.S	Thu Jan 18 09:54:33 2007 +0000
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,287 +0,0 @@
    27.4 -#include <os.h>
    27.5 -#include <xen/arch-x86_32.h>
    27.6 -
    27.7 -.section __xen_guest
    27.8 -	.ascii	"GUEST_OS=Mini-OS"
    27.9 -	.ascii	",XEN_VER=xen-3.0"
   27.10 -	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
   27.11 -	.ascii	",ELF_PADDR_OFFSET=0x0"
   27.12 -	.ascii	",HYPERCALL_PAGE=0x2"
   27.13 -#ifdef CONFIG_X86_PAE
   27.14 -	.ascii	",PAE=yes"
   27.15 -#else
   27.16 -	.ascii	",PAE=no"
   27.17 -#endif
   27.18 -	.ascii	",LOADER=generic"
   27.19 -	.byte	0
   27.20 -.text
   27.21 -
   27.22 -.globl _start, shared_info, hypercall_page
   27.23 -                        
   27.24 -_start:
   27.25 -        cld
   27.26 -        lss stack_start,%esp
   27.27 -        push %esi 
   27.28 -        call start_kernel
   27.29 -
   27.30 -stack_start:
   27.31 -	.long stack+8192, __KERNEL_SS
   27.32 -
   27.33 -        /* Unpleasant -- the PTE that maps this page is actually overwritten */
   27.34 -        /* to map the real shared-info page! :-)                             */
   27.35 -        .org 0x1000
   27.36 -shared_info:
   27.37 -        .org 0x2000
   27.38 -
   27.39 -hypercall_page:
   27.40 -        .org 0x3000
   27.41 -
   27.42 -ES		= 0x20
   27.43 -ORIG_EAX	= 0x24
   27.44 -EIP		= 0x28
   27.45 -CS		= 0x2C
   27.46 -
   27.47 -#define ENTRY(X) .globl X ; X :
   27.48 -
   27.49 -#define SAVE_ALL \
   27.50 -	cld; \
   27.51 -	pushl %es; \
   27.52 -	pushl %ds; \
   27.53 -	pushl %eax; \
   27.54 -	pushl %ebp; \
   27.55 -	pushl %edi; \
   27.56 -	pushl %esi; \
   27.57 -	pushl %edx; \
   27.58 -	pushl %ecx; \
   27.59 -	pushl %ebx; \
   27.60 -	movl $(__KERNEL_DS),%edx; \
   27.61 -	movl %edx,%ds; \
   27.62 -	movl %edx,%es;
   27.63 -
   27.64 -#define RESTORE_ALL	\
   27.65 -	popl %ebx;	\
   27.66 -	popl %ecx;	\
   27.67 -	popl %edx;	\
   27.68 -	popl %esi;	\
   27.69 -	popl %edi;	\
   27.70 -	popl %ebp;	\
   27.71 -	popl %eax;	\
   27.72 -	popl %ds;	\
   27.73 -	popl %es;	\
   27.74 -	addl $4,%esp;	\
   27.75 -	iret;		\
   27.76 -
   27.77 -ENTRY(divide_error)
   27.78 -	pushl $0		# no error code
   27.79 -	pushl $do_divide_error
   27.80 -do_exception:
   27.81 -    pushl %ds
   27.82 -	pushl %eax
   27.83 -	xorl %eax, %eax
   27.84 -	pushl %ebp
   27.85 -	pushl %edi
   27.86 -	pushl %esi
   27.87 -	pushl %edx
   27.88 -	decl %eax			# eax = -1
   27.89 -	pushl %ecx
   27.90 -	pushl %ebx
   27.91 -	cld
   27.92 -	movl %es, %ecx
   27.93 -	movl ES(%esp), %edi		# get the function address
   27.94 -	movl ORIG_EAX(%esp), %edx	# get the error code
   27.95 -	movl %eax, ORIG_EAX(%esp)
   27.96 -	movl %ecx, ES(%esp)
   27.97 -	movl $(__KERNEL_DS), %ecx
   27.98 -	movl %ecx, %ds
   27.99 -	movl %ecx, %es
  27.100 -	movl %esp,%eax			# pt_regs pointer
  27.101 -    pushl %edx
  27.102 -    pushl %eax
  27.103 -	call *%edi
  27.104 -    jmp ret_from_exception
  27.105 -    
  27.106 -ret_from_exception:
  27.107 -        movb CS(%esp),%cl
  27.108 -	test $2,%cl          # slow return to ring 2 or 3
  27.109 -	jne  safesti
  27.110 -        RESTORE_ALL
  27.111 -
  27.112 -# A note on the "critical region" in our callback handler.
  27.113 -# We want to avoid stacking callback handlers due to events occurring
  27.114 -# during handling of the last event. To do this, we keep events disabled
  27.115 -# until weve done all processing. HOWEVER, we must enable events before
  27.116 -# popping the stack frame (cant be done atomically) and so it would still
  27.117 -# be possible to get enough handler activations to overflow the stack.
  27.118 -# Although unlikely, bugs of that kind are hard to track down, so wed
  27.119 -# like to avoid the possibility.
  27.120 -# So, on entry to the handler we detect whether we interrupted an
  27.121 -# existing activation in its critical region -- if so, we pop the current
  27.122 -# activation and restart the handler using the previous one.
  27.123 -ENTRY(hypervisor_callback)
  27.124 -        pushl %eax
  27.125 -        SAVE_ALL
  27.126 -        movl EIP(%esp),%eax
  27.127 -        cmpl $scrit,%eax
  27.128 -        jb   11f
  27.129 -        cmpl $ecrit,%eax
  27.130 -        jb   critical_region_fixup
  27.131 -11:     push %esp
  27.132 -        call do_hypervisor_callback
  27.133 -        add  $4,%esp
  27.134 -        movl HYPERVISOR_shared_info,%esi
  27.135 -        xorl %eax,%eax
  27.136 -        movb CS(%esp),%cl
  27.137 -    	test $2,%cl          # slow return to ring 2 or 3
  27.138 -        jne  safesti
  27.139 -safesti:movb $0,1(%esi)     # reenable event callbacks
  27.140 -scrit:  /**** START OF CRITICAL REGION ****/
  27.141 -        testb $0xFF,(%esi)
  27.142 -        jnz  14f              # process more events if necessary...
  27.143 -        RESTORE_ALL
  27.144 -14:     movb $1,1(%esi)
  27.145 -        jmp  11b
  27.146 -ecrit:  /**** END OF CRITICAL REGION ****/
  27.147 -# [How we do the fixup]. We want to merge the current stack frame with the
  27.148 -# just-interrupted frame. How we do this depends on where in the critical
  27.149 -# region the interrupted handler was executing, and so how many saved
  27.150 -# registers are in each frame. We do this quickly using the lookup table
  27.151 -# 'critical_fixup_table'. For each byte offset in the critical region, it
  27.152 -# provides the number of bytes which have already been popped from the
  27.153 -# interrupted stack frame. 
  27.154 -critical_region_fixup:
  27.155 -        addl $critical_fixup_table-scrit,%eax
  27.156 -        movzbl (%eax),%eax    # %eax contains num bytes popped
  27.157 -        mov  %esp,%esi
  27.158 -        add  %eax,%esi        # %esi points at end of src region
  27.159 -        mov  %esp,%edi
  27.160 -        add  $0x34,%edi       # %edi points at end of dst region
  27.161 -        mov  %eax,%ecx
  27.162 -        shr  $2,%ecx          # convert words to bytes
  27.163 -        je   16f              # skip loop if nothing to copy
  27.164 -15:     subl $4,%esi          # pre-decrementing copy loop
  27.165 -        subl $4,%edi
  27.166 -        movl (%esi),%eax
  27.167 -        movl %eax,(%edi)
  27.168 -        loop 15b
  27.169 -16:     movl %edi,%esp        # final %edi is top of merged stack
  27.170 -        jmp  11b
  27.171 -         
  27.172 -critical_fixup_table:        
  27.173 -        .byte 0x00,0x00,0x00                  # testb $0xff,(%esi)
  27.174 -        .byte 0x00,0x00                       # jne  14f
  27.175 -        .byte 0x00                            # pop  %ebx
  27.176 -        .byte 0x04                            # pop  %ecx
  27.177 -        .byte 0x08                            # pop  %edx
  27.178 -        .byte 0x0c                            # pop  %esi
  27.179 -        .byte 0x10                            # pop  %edi
  27.180 -        .byte 0x14                            # pop  %ebp
  27.181 -        .byte 0x18                            # pop  %eax
  27.182 -        .byte 0x1c                            # pop  %ds
  27.183 -        .byte 0x20                            # pop  %es
  27.184 -        .byte 0x24,0x24,0x24                  # add  $4,%esp
  27.185 -        .byte 0x28                            # iret
  27.186 -        .byte 0x00,0x00,0x00,0x00             # movb $1,1(%esi)
  27.187 -        .byte 0x00,0x00                       # jmp  11b
  27.188 -       
  27.189 -# Hypervisor uses this for application faults while it executes.
  27.190 -ENTRY(failsafe_callback)
  27.191 -      pop  %ds
  27.192 -      pop  %es
  27.193 -      pop  %fs
  27.194 -      pop  %gs
  27.195 -      iret
  27.196 -                
  27.197 -ENTRY(coprocessor_error)
  27.198 -	pushl $0
  27.199 -	pushl $do_coprocessor_error
  27.200 -	jmp do_exception
  27.201 -
  27.202 -ENTRY(simd_coprocessor_error)
  27.203 -	pushl $0
  27.204 -	pushl $do_simd_coprocessor_error
  27.205 -	jmp do_exception
  27.206 -
  27.207 -ENTRY(device_not_available)
  27.208 -        iret
  27.209 -
  27.210 -ENTRY(debug)
  27.211 -	pushl $0
  27.212 -	pushl $do_debug
  27.213 -	jmp do_exception
  27.214 -
  27.215 -ENTRY(int3)
  27.216 -	pushl $0
  27.217 -	pushl $do_int3
  27.218 -	jmp do_exception
  27.219 -
  27.220 -ENTRY(overflow)
  27.221 -	pushl $0
  27.222 -	pushl $do_overflow
  27.223 -	jmp do_exception
  27.224 -
  27.225 -ENTRY(bounds)
  27.226 -	pushl $0
  27.227 -	pushl $do_bounds
  27.228 -	jmp do_exception
  27.229 -
  27.230 -ENTRY(invalid_op)
  27.231 -	pushl $0
  27.232 -	pushl $do_invalid_op
  27.233 -	jmp do_exception
  27.234 -
  27.235 -
  27.236 -ENTRY(coprocessor_segment_overrun)
  27.237 -	pushl $0
  27.238 -	pushl $do_coprocessor_segment_overrun
  27.239 -	jmp do_exception
  27.240 -
  27.241 -
  27.242 -ENTRY(invalid_TSS)
  27.243 -	pushl $do_invalid_TSS
  27.244 -	jmp do_exception
  27.245 -
  27.246 -
  27.247 -ENTRY(segment_not_present)
  27.248 -	pushl $do_segment_not_present
  27.249 -	jmp do_exception
  27.250 -
  27.251 -
  27.252 -ENTRY(stack_segment)
  27.253 -	pushl $do_stack_segment
  27.254 -	jmp do_exception
  27.255 -
  27.256 -
  27.257 -ENTRY(general_protection)
  27.258 -	pushl $do_general_protection
  27.259 -	jmp do_exception
  27.260 -
  27.261 -
  27.262 -ENTRY(alignment_check)
  27.263 -	pushl $do_alignment_check
  27.264 -	jmp do_exception
  27.265 -
  27.266 -
  27.267 -ENTRY(page_fault)
  27.268 -    pushl $do_page_fault
  27.269 -    jmp do_exception
  27.270 -    
  27.271 -ENTRY(machine_check)
  27.272 -	pushl $0
  27.273 -	pushl $do_machine_check
  27.274 -	jmp do_exception
  27.275 -
  27.276 -
  27.277 -ENTRY(spurious_interrupt_bug)
  27.278 -	pushl $0
  27.279 -	pushl $do_spurious_interrupt_bug
  27.280 -	jmp do_exception
  27.281 -
  27.282 -
  27.283 -
  27.284 -ENTRY(thread_starter)
  27.285 -    popl %eax
  27.286 -    popl %ebx
  27.287 -    pushl %eax
  27.288 -    call *%ebx
  27.289 -    call exit_thread 
  27.290 -    
    28.1 --- a/extras/mini-os/x86_64.S	Thu Jan 18 09:54:33 2007 +0000
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,385 +0,0 @@
    28.4 -#include <os.h>
    28.5 -#include <xen/features.h>
    28.6 -
    28.7 -.section __xen_guest
    28.8 -	.ascii	"GUEST_OS=Mini-OS"
    28.9 -	.ascii	",XEN_VER=xen-3.0"
   28.10 -	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
   28.11 -	.ascii	",ELF_PADDR_OFFSET=0x0"
   28.12 -	.ascii	",HYPERCALL_PAGE=0x2"
   28.13 -	.ascii	",LOADER=generic"
   28.14 -	.byte	0
   28.15 -.text
   28.16 -
   28.17 -#define ENTRY(X) .globl X ; X :
   28.18 -.globl _start, shared_info, hypercall_page
   28.19 -
   28.20 -
   28.21 -_start:
   28.22 -        cld
   28.23 -        movq stack_start(%rip),%rsp
   28.24 -        movq %rsi,%rdi
   28.25 -        call start_kernel
   28.26 -
   28.27 -stack_start:
   28.28 -        .quad stack+8192
   28.29 -
   28.30 -        /* Unpleasant -- the PTE that maps this page is actually overwritten */
   28.31 -        /* to map the real shared-info page! :-)                             */
   28.32 -        .org 0x1000
   28.33 -shared_info:
   28.34 -        .org 0x2000
   28.35 -
   28.36 -hypercall_page:
   28.37 -        .org 0x3000
   28.38 -
   28.39 -
   28.40 -/* Offsets into shared_info_t. */                
   28.41 -#define evtchn_upcall_pending		/* 0 */
   28.42 -#define evtchn_upcall_mask		1
   28.43 -
   28.44 -NMI_MASK = 0x80000000
   28.45 -
   28.46 -#define RDI 112
   28.47 -#define ORIG_RAX 120       /* + error_code */ 
   28.48 -#define EFLAGS 144
   28.49 -
   28.50 -#define REST_SKIP 6*8			
   28.51 -.macro SAVE_REST
   28.52 -	subq $REST_SKIP,%rsp
   28.53 -#	CFI_ADJUST_CFA_OFFSET	REST_SKIP
   28.54 -	movq %rbx,5*8(%rsp) 
   28.55 -#	CFI_REL_OFFSET	rbx,5*8
   28.56 -	movq %rbp,4*8(%rsp) 
   28.57 -#	CFI_REL_OFFSET	rbp,4*8
   28.58 -	movq %r12,3*8(%rsp) 
   28.59 -#	CFI_REL_OFFSET	r12,3*8
   28.60 -	movq %r13,2*8(%rsp) 
   28.61 -#	CFI_REL_OFFSET	r13,2*8
   28.62 -	movq %r14,1*8(%rsp) 
   28.63 -#	CFI_REL_OFFSET	r14,1*8
   28.64 -	movq %r15,(%rsp) 
   28.65 -#	CFI_REL_OFFSET	r15,0*8
   28.66 -.endm		
   28.67 -
   28.68 -
   28.69 -.macro RESTORE_REST
   28.70 -	movq (%rsp),%r15
   28.71 -#	CFI_RESTORE r15
   28.72 -	movq 1*8(%rsp),%r14
   28.73 -#	CFI_RESTORE r14
   28.74 -	movq 2*8(%rsp),%r13
   28.75 -#	CFI_RESTORE r13
   28.76 -	movq 3*8(%rsp),%r12
   28.77 -#	CFI_RESTORE r12
   28.78 -	movq 4*8(%rsp),%rbp
   28.79 -#	CFI_RESTORE rbp
   28.80 -	movq 5*8(%rsp),%rbx
   28.81 -#	CFI_RESTORE rbx
   28.82 -	addq $REST_SKIP,%rsp
   28.83 -#	CFI_ADJUST_CFA_OFFSET	-(REST_SKIP)
   28.84 -.endm
   28.85 -
   28.86 -
   28.87 -#define ARG_SKIP 9*8
   28.88 -.macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0
   28.89 -	.if \skipr11
   28.90 -	.else
   28.91 -	movq (%rsp),%r11
   28.92 -#	CFI_RESTORE r11
   28.93 -	.endif
   28.94 -	.if \skipr8910
   28.95 -	.else
   28.96 -	movq 1*8(%rsp),%r10
   28.97 -#	CFI_RESTORE r10
   28.98 -	movq 2*8(%rsp),%r9
   28.99 -#	CFI_RESTORE r9
  28.100 -	movq 3*8(%rsp),%r8
  28.101 -#	CFI_RESTORE r8
  28.102 -	.endif
  28.103 -	.if \skiprax
  28.104 -	.else
  28.105 -	movq 4*8(%rsp),%rax
  28.106 -#	CFI_RESTORE rax
  28.107 -	.endif
  28.108 -	.if \skiprcx
  28.109 -	.else
  28.110 -	movq 5*8(%rsp),%rcx
  28.111 -#	CFI_RESTORE rcx
  28.112 -	.endif
  28.113 -	.if \skiprdx
  28.114 -	.else
  28.115 -	movq 6*8(%rsp),%rdx
  28.116 -#	CFI_RESTORE rdx
  28.117 -	.endif
  28.118 -	movq 7*8(%rsp),%rsi
  28.119 -#	CFI_RESTORE rsi
  28.120 -	movq 8*8(%rsp),%rdi
  28.121 -#	CFI_RESTORE rdi
  28.122 -	.if ARG_SKIP+\addskip > 0
  28.123 -	addq $ARG_SKIP+\addskip,%rsp
  28.124 -#	CFI_ADJUST_CFA_OFFSET	-(ARG_SKIP+\addskip)
  28.125 -	.endif
  28.126 -.endm	
  28.127 -
  28.128 -
  28.129 -.macro HYPERVISOR_IRET flag
  28.130 -#    testb $3,1*8(%rsp)    /* Don't need to do that in Mini-os, as */
  28.131 -#	jnz   2f               /* there is no userspace? */
  28.132 -	testl $NMI_MASK,2*8(%rsp)
  28.133 -	jnz   2f
  28.134 -
  28.135 -	testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
  28.136 -	jnz   1f
  28.137 -
  28.138 -	/* Direct iret to kernel space. Correct CS and SS. */
  28.139 -	orb   $3,1*8(%rsp)
  28.140 -	orb   $3,4*8(%rsp)
  28.141 -1:	iretq
  28.142 -
  28.143 -2:	/* Slow iret via hypervisor. */
  28.144 -	andl  $~NMI_MASK, 16(%rsp)
  28.145 -	pushq $\flag
  28.146 -	jmp  hypercall_page + (__HYPERVISOR_iret * 32)
  28.147 -.endm
  28.148 -
  28.149 -/*
  28.150 - * Exception entry point. This expects an error code/orig_rax on the stack
  28.151 - * and the exception handler in %rax.	
  28.152 - */ 		  				
  28.153 -ENTRY(error_entry)
  28.154 -#	_frame RDI
  28.155 -	/* rdi slot contains rax, oldrax contains error code */
  28.156 -	cld	
  28.157 -	subq  $14*8,%rsp
  28.158 -#	CFI_ADJUST_CFA_OFFSET	(14*8)
  28.159 -	movq %rsi,13*8(%rsp)
  28.160 -#	CFI_REL_OFFSET	rsi,RSI
  28.161 -	movq 14*8(%rsp),%rsi	/* load rax from rdi slot */
  28.162 -	movq %rdx,12*8(%rsp)
  28.163 -#	CFI_REL_OFFSET	rdx,RDX
  28.164 -	movq %rcx,11*8(%rsp)
  28.165 -#	CFI_REL_OFFSET	rcx,RCX
  28.166 -	movq %rsi,10*8(%rsp)	/* store rax */ 
  28.167 -#	CFI_REL_OFFSET	rax,RAX
  28.168 -	movq %r8, 9*8(%rsp)
  28.169 -#	CFI_REL_OFFSET	r8,R8
  28.170 -	movq %r9, 8*8(%rsp)
  28.171 -#	CFI_REL_OFFSET	r9,R9
  28.172 -	movq %r10,7*8(%rsp)
  28.173 -#	CFI_REL_OFFSET	r10,R10
  28.174 -	movq %r11,6*8(%rsp)
  28.175 -#	CFI_REL_OFFSET	r11,R11
  28.176 -	movq %rbx,5*8(%rsp) 
  28.177 -#	CFI_REL_OFFSET	rbx,RBX
  28.178 -	movq %rbp,4*8(%rsp) 
  28.179 -#	CFI_REL_OFFSET	rbp,RBP
  28.180 -	movq %r12,3*8(%rsp) 
  28.181 -#	CFI_REL_OFFSET	r12,R12
  28.182 -	movq %r13,2*8(%rsp) 
  28.183 -#	CFI_REL_OFFSET	r13,R13
  28.184 -	movq %r14,1*8(%rsp) 
  28.185 -#	CFI_REL_OFFSET	r14,R14
  28.186 -	movq %r15,(%rsp) 
  28.187 -#	CFI_REL_OFFSET	r15,R15
  28.188 -#if 0        
  28.189 -	cmpl $__KERNEL_CS,CS(%rsp)
  28.190 -	je  error_kernelspace
  28.191 -#endif        
  28.192 -error_call_handler:
  28.193 -	movq %rdi, RDI(%rsp)            
  28.194 -	movq %rsp,%rdi
  28.195 -	movq ORIG_RAX(%rsp),%rsi	# get error code 
  28.196 -	movq $-1,ORIG_RAX(%rsp)
  28.197 -	call *%rax
  28.198 -
  28.199 -.macro zeroentry sym
  28.200 -#	INTR_FRAME
  28.201 -    movq (%rsp),%rcx
  28.202 -    movq 8(%rsp),%r11
  28.203 -    addq $0x10,%rsp /* skip rcx and r11 */
  28.204 -	pushq $0	/* push error code/oldrax */ 
  28.205 -#	CFI_ADJUST_CFA_OFFSET 8
  28.206 -	pushq %rax	/* push real oldrax to the rdi slot */ 
  28.207 -#	CFI_ADJUST_CFA_OFFSET 8
  28.208 -	leaq  \sym(%rip),%rax
  28.209 -	jmp error_entry
  28.210 -#	CFI_ENDPROC
  28.211 -.endm	
  28.212 -
  28.213 -.macro errorentry sym
  28.214 -#	XCPT_FRAME
  28.215 -        movq (%rsp),%rcx
  28.216 -        movq 8(%rsp),%r11
  28.217 -        addq $0x10,%rsp /* rsp points to the error code */
  28.218 -	pushq %rax
  28.219 -#	CFI_ADJUST_CFA_OFFSET 8
  28.220 -	leaq  \sym(%rip),%rax
  28.221 -	jmp error_entry
  28.222 -#	CFI_ENDPROC
  28.223 -.endm
  28.224 -
  28.225 -#define XEN_GET_VCPU_INFO(reg)	movq HYPERVISOR_shared_info,reg
  28.226 -#define XEN_PUT_VCPU_INFO(reg)
  28.227 -#define XEN_PUT_VCPU_INFO_fixup
  28.228 -#define XEN_LOCKED_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
  28.229 -#define XEN_LOCKED_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
  28.230 -#define XEN_TEST_PENDING(reg)	testb $0xFF,evtchn_upcall_pending(reg)
  28.231 -
  28.232 -#define XEN_BLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  28.233 -                    			XEN_LOCKED_BLOCK_EVENTS(reg)	; \
  28.234 -    				            XEN_PUT_VCPU_INFO(reg)
  28.235 -
  28.236 -#define XEN_UNBLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  28.237 -                				XEN_LOCKED_UNBLOCK_EVENTS(reg)	; \
  28.238 -    			            	XEN_PUT_VCPU_INFO(reg)
  28.239 -
  28.240 -
  28.241 -
  28.242 -ENTRY(hypervisor_callback)
  28.243 -    zeroentry hypervisor_callback2
  28.244 -
  28.245 -ENTRY(hypervisor_callback2)
  28.246 -        movq %rdi, %rsp 
  28.247 -11:     movq %gs:8,%rax
  28.248 -        incl %gs:0
  28.249 -        cmovzq %rax,%rsp
  28.250 -        pushq %rdi
  28.251 -        call do_hypervisor_callback 
  28.252 -        popq %rsp
  28.253 -        decl %gs:0
  28.254 -        jmp error_exit
  28.255 -
  28.256 -#        ALIGN
  28.257 -restore_all_enable_events:  
  28.258 -	XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
  28.259 -
  28.260 -scrit:	/**** START OF CRITICAL REGION ****/
  28.261 -	XEN_TEST_PENDING(%rsi)
  28.262 -	jnz  14f			# process more events if necessary...
  28.263 -	XEN_PUT_VCPU_INFO(%rsi)
  28.264 -        RESTORE_ARGS 0,8,0
  28.265 -        HYPERVISOR_IRET 0
  28.266 -        
  28.267 -14:	XEN_LOCKED_BLOCK_EVENTS(%rsi)
  28.268 -	XEN_PUT_VCPU_INFO(%rsi)
  28.269 -	SAVE_REST
  28.270 -        movq %rsp,%rdi                  # set the argument again
  28.271 -	jmp  11b
  28.272 -ecrit:  /**** END OF CRITICAL REGION ****/
  28.273 -
  28.274 -
  28.275 -retint_kernel:
  28.276 -retint_restore_args:
  28.277 -	movl EFLAGS-REST_SKIP(%rsp), %eax
  28.278 -	shr $9, %eax			# EAX[0] == IRET_EFLAGS.IF
  28.279 -	XEN_GET_VCPU_INFO(%rsi)
  28.280 -	andb evtchn_upcall_mask(%rsi),%al
  28.281 -	andb $1,%al			# EAX[0] == IRET_EFLAGS.IF & event_mask
  28.282 -	jnz restore_all_enable_events	#        != 0 => enable event delivery
  28.283 -	XEN_PUT_VCPU_INFO(%rsi)
  28.284 -		
  28.285 -	RESTORE_ARGS 0,8,0
  28.286 -	HYPERVISOR_IRET 0
  28.287 -
  28.288 -
  28.289 -error_exit:		
  28.290 -	RESTORE_REST
  28.291 -/*	cli */
  28.292 -	XEN_BLOCK_EVENTS(%rsi)		
  28.293 -	jmp retint_kernel
  28.294 -
  28.295 -
  28.296 -
  28.297 -ENTRY(failsafe_callback)
  28.298 -        popq  %rcx
  28.299 -        popq  %r11
  28.300 -        iretq
  28.301 -
  28.302 -
  28.303 -ENTRY(coprocessor_error)
  28.304 -        zeroentry do_coprocessor_error
  28.305 -
  28.306 -
  28.307 -ENTRY(simd_coprocessor_error)
  28.308 -        zeroentry do_simd_coprocessor_error
  28.309 -
  28.310 -
  28.311 -ENTRY(device_not_available)
  28.312 -        zeroentry do_device_not_available
  28.313 -
  28.314 -
  28.315 -ENTRY(debug)
  28.316 -#       INTR_FRAME
  28.317 -#       CFI_ADJUST_CFA_OFFSET 8 */
  28.318 -        zeroentry do_debug
  28.319 -#       CFI_ENDPROC
  28.320 -
  28.321 -
  28.322 -ENTRY(int3)
  28.323 -#       INTR_FRAME
  28.324 -#       CFI_ADJUST_CFA_OFFSET 8 */
  28.325 -        zeroentry do_int3
  28.326 -#       CFI_ENDPROC
  28.327 -
  28.328 -ENTRY(overflow)
  28.329 -        zeroentry do_overflow
  28.330 -
  28.331 -
  28.332 -ENTRY(bounds)
  28.333 -        zeroentry do_bounds
  28.334 -    
  28.335 -    
  28.336 -ENTRY(invalid_op)
  28.337 -        zeroentry do_invalid_op
  28.338 -
  28.339 -
  28.340 -ENTRY(coprocessor_segment_overrun)
  28.341 -        zeroentry do_coprocessor_segment_overrun
  28.342 -
  28.343 -
  28.344 -ENTRY(invalid_TSS)
  28.345 -        errorentry do_invalid_TSS
  28.346 -
  28.347 -
  28.348 -ENTRY(segment_not_present)
  28.349 -        errorentry do_segment_not_present
  28.350 -
  28.351 -
  28.352 -/* runs on exception stack */
  28.353 -ENTRY(stack_segment)
  28.354 -#       XCPT_FRAME
  28.355 -        errorentry do_stack_segment
  28.356 -#       CFI_ENDPROC
  28.357 -                    
  28.358 -
  28.359 -ENTRY(general_protection)
  28.360 -        errorentry do_general_protection
  28.361 -
  28.362 -
  28.363 -ENTRY(alignment_check)
  28.364 -        errorentry do_alignment_check
  28.365 -
  28.366 -
  28.367 -ENTRY(divide_error)
  28.368 -        zeroentry do_divide_error
  28.369 -
  28.370 -
  28.371 -ENTRY(spurious_interrupt_bug)
  28.372 -        zeroentry do_spurious_interrupt_bug
  28.373 -            
  28.374 -
  28.375 -ENTRY(page_fault)
  28.376 -        errorentry do_page_fault
  28.377 -
  28.378 -
  28.379 -
  28.380 -
  28.381 -
  28.382 -ENTRY(thread_starter)
  28.383 -        popq %rdi
  28.384 -        popq %rbx
  28.385 -        call *%rbx
  28.386 -        call exit_thread 
  28.387 -        
  28.388 -
    29.1 --- a/extras/mini-os/xenbus/xenbus.c	Thu Jan 18 09:54:33 2007 +0000
    29.2 +++ b/extras/mini-os/xenbus/xenbus.c	Thu Jan 18 15:18:07 2007 +0000
    29.3 @@ -45,9 +45,9 @@
    29.4  #define DEBUG(_f, _a...)    ((void)0)
    29.5  #endif
    29.6  
    29.7 -
    29.8  static struct xenstore_domain_interface *xenstore_buf;
    29.9  static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
   29.10 +static DECLARE_WAIT_QUEUE_HEAD(watch_queue);
   29.11  struct xenbus_req_info 
   29.12  {
   29.13      int in_use:1;
   29.14 @@ -72,6 +72,34 @@ static void memcpy_from_ring(const void 
   29.15      memcpy(dest + c1, ring, c2);
   29.16  }
   29.17  
   29.18 +static inline void wait_for_watch(void)
   29.19 +{
   29.20 +    DEFINE_WAIT(w);
   29.21 +    add_waiter(w,watch_queue);
   29.22 +    schedule();
   29.23 +    wake(current);
   29.24 +}
   29.25 +
   29.26 +char* xenbus_wait_for_value(const char* path,const char* value)
   29.27 +{
   29.28 +    for(;;)
   29.29 +    {
   29.30 +        char *res, *msg;
   29.31 +        int r;
   29.32 +
   29.33 +        msg = xenbus_read(XBT_NIL, path, &res);
   29.34 +        if(msg) return msg;
   29.35 +
   29.36 +        r = strcmp(value,res);
   29.37 +        free(res);
   29.38 +
   29.39 +        if(r==0) break;
   29.40 +        else wait_for_watch();
   29.41 +    }
   29.42 +    return NULL;
   29.43 +}
   29.44 +
   29.45 +
   29.46  static void xenbus_thread_func(void *ign)
   29.47  {
   29.48      struct xsd_sockmsg msg;
   29.49 @@ -101,13 +129,35 @@ static void xenbus_thread_func(void *ign
   29.50                  break;
   29.51  
   29.52              DEBUG("Message is good.\n");
   29.53 -            req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
   29.54 -            memcpy_from_ring(xenstore_buf->rsp,
   29.55 +
   29.56 +            if(msg.type == XS_WATCH_EVENT)
   29.57 +            {
   29.58 +                char* payload = (char*)malloc(sizeof(msg) + msg.len);
   29.59 +                char *path,*token;
   29.60 +
   29.61 +                memcpy_from_ring(xenstore_buf->rsp,
   29.62 +                    payload,
   29.63 +                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
   29.64 +                    msg.len + sizeof(msg));
   29.65 +
   29.66 +                path = payload + sizeof(msg);
   29.67 +                token = path + strlen(path) + 1;
   29.68 +
   29.69 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   29.70 +                free(payload);
   29.71 +                wake_up(&watch_queue);
   29.72 +            }
   29.73 +
   29.74 +            else
   29.75 +            {
   29.76 +                req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
   29.77 +                memcpy_from_ring(xenstore_buf->rsp,
   29.78                      req_info[msg.req_id].reply,
   29.79                      MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
   29.80                      msg.len + sizeof(msg));
   29.81 -            wake_up(&req_info[msg.req_id].waitq);
   29.82 -            xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   29.83 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   29.84 +                wake_up(&req_info[msg.req_id].waitq);
   29.85 +            }
   29.86          }
   29.87      }
   29.88  }
   29.89 @@ -381,12 +431,32 @@ char *xenbus_write(xenbus_transaction_t 
   29.90      struct xsd_sockmsg *rep;
   29.91      rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
   29.92      char *msg = errmsg(rep);
   29.93 -    if (msg)
   29.94 -	return msg;
   29.95 +    if (msg) return msg;
   29.96      free(rep);
   29.97      return NULL;
   29.98  }
   29.99  
  29.100 +char* xenbus_watch_path( xenbus_transaction_t xbt, const char *path)
  29.101 +{
  29.102 +	/* in the future one could have multiple watch queues, and use
  29.103 +	 * the token for demuxing. For now the token is 0. */
  29.104 +
  29.105 +    struct xsd_sockmsg *rep;
  29.106 +
  29.107 +    struct write_req req[] = { 
  29.108 +        {path, strlen(path) + 1},
  29.109 +        {"0",2 },
  29.110 +    };
  29.111 +
  29.112 +    rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req));
  29.113 +
  29.114 +    char *msg = errmsg(rep);
  29.115 +    if (msg) return msg;
  29.116 +    free(rep);
  29.117 +
  29.118 +    return NULL;
  29.119 +}
  29.120 +
  29.121  char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
  29.122  {
  29.123      struct write_req req[] = { {path, strlen(path) + 1} };
    30.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Thu Jan 18 09:54:33 2007 +0000
    30.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Thu Jan 18 15:18:07 2007 +0000
    30.3 @@ -629,7 +629,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
    30.4  
    30.5  config HIGHPTE
    30.6  	bool "Allocate 3rd-level pagetables from highmem"
    30.7 -	depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN
    30.8 +	depends on HIGHMEM4G || HIGHMEM64G
    30.9  	help
   30.10  	  The VM uses one page table entry for each page of physical memory.
   30.11  	  For systems with a lot of RAM, this can be wasteful of precious
    31.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Thu Jan 18 09:54:33 2007 +0000
    31.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Thu Jan 18 15:18:07 2007 +0000
    31.3 @@ -89,7 +89,7 @@ static ssize_t microcode_write (struct f
    31.4  {
    31.5  	ssize_t ret;
    31.6  
    31.7 -	if (len < DEFAULT_UCODE_TOTALSIZE) {
    31.8 +	if (len < MC_HEADER_SIZE) {
    31.9  		printk(KERN_ERR "microcode: not enough data\n"); 
   31.10  		return -EINVAL;
   31.11  	}
    32.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c	Thu Jan 18 09:54:33 2007 +0000
    32.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c	Thu Jan 18 15:18:07 2007 +0000
    32.3 @@ -114,13 +114,7 @@ dma_unmap_sg(struct device *hwdev, struc
    32.4  }
    32.5  EXPORT_SYMBOL(dma_unmap_sg);
    32.6  
    32.7 -/*
    32.8 - * XXX This file is also used by xenLinux/ia64. 
    32.9 - * "defined(__i386__) || defined (__x86_64__)" means "!defined(__ia64__)".
   32.10 - * This #if work around should be removed once this file is merbed back into
   32.11 - * i386' pci-dma or is moved to drivers/xen/core.
   32.12 - */
   32.13 -#if defined(__i386__) || defined(__x86_64__)
   32.14 +#ifdef CONFIG_HIGHMEM
   32.15  dma_addr_t
   32.16  dma_map_page(struct device *dev, struct page *page, unsigned long offset,
   32.17  	     size_t size, enum dma_data_direction direction)
   32.18 @@ -150,7 +144,7 @@ dma_unmap_page(struct device *dev, dma_a
   32.19  		swiotlb_unmap_page(dev, dma_address, size, direction);
   32.20  }
   32.21  EXPORT_SYMBOL(dma_unmap_page);
   32.22 -#endif /* defined(__i386__) || defined(__x86_64__) */
   32.23 +#endif /* CONFIG_HIGHMEM */
   32.24  
   32.25  int
   32.26  dma_mapping_error(dma_addr_t dma_addr)
   32.27 @@ -181,6 +175,8 @@ void *dma_alloc_coherent(struct device *
   32.28  	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
   32.29  	unsigned int order = get_order(size);
   32.30  	unsigned long vstart;
   32.31 +	u64 mask;
   32.32 +
   32.33  	/* ignore region specifiers */
   32.34  	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
   32.35  
   32.36 @@ -203,9 +199,14 @@ void *dma_alloc_coherent(struct device *
   32.37  	vstart = __get_free_pages(gfp, order);
   32.38  	ret = (void *)vstart;
   32.39  
   32.40 +	if (dev != NULL && dev->coherent_dma_mask)
   32.41 +		mask = dev->coherent_dma_mask;
   32.42 +	else
   32.43 +		mask = 0xffffffff;
   32.44 +
   32.45  	if (ret != NULL) {
   32.46  		if (xen_create_contiguous_region(vstart, order,
   32.47 -						 dma_bits) != 0) {
   32.48 +						 fls64(mask)) != 0) {
   32.49  			free_pages(vstart, order);
   32.50  			return NULL;
   32.51  		}
    33.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Thu Jan 18 09:54:33 2007 +0000
    33.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Thu Jan 18 15:18:07 2007 +0000
    33.3 @@ -47,9 +47,6 @@ EXPORT_SYMBOL(swiotlb);
    33.4   */
    33.5  #define IO_TLB_SHIFT 11
    33.6  
    33.7 -/* Width of DMA addresses. 30 bits is a b44 limitation. */
    33.8 -#define DEFAULT_DMA_BITS 30
    33.9 -
   33.10  static int swiotlb_force;
   33.11  static char *iotlb_virt_start;
   33.12  static unsigned long iotlb_nslabs;
   33.13 @@ -98,11 +95,12 @@ static struct phys_addr {
   33.14   */
   33.15  static DEFINE_SPINLOCK(io_tlb_lock);
   33.16  
   33.17 -unsigned int dma_bits = DEFAULT_DMA_BITS;
   33.18 +static unsigned int dma_bits;
   33.19 +static unsigned int __initdata max_dma_bits = 32;
   33.20  static int __init
   33.21  setup_dma_bits(char *str)
   33.22  {
   33.23 -	dma_bits = simple_strtoul(str, NULL, 0);
   33.24 +	max_dma_bits = simple_strtoul(str, NULL, 0);
   33.25  	return 0;
   33.26  }
   33.27  __setup("dma_bits=", setup_dma_bits);
   33.28 @@ -143,6 +141,7 @@ void
   33.29  swiotlb_init_with_default_size (size_t default_size)
   33.30  {
   33.31  	unsigned long i, bytes;
   33.32 +	int rc;
   33.33  
   33.34  	if (!iotlb_nslabs) {
   33.35  		iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
   33.36 @@ -159,16 +158,33 @@ swiotlb_init_with_default_size (size_t d
   33.37  	 */
   33.38  	iotlb_virt_start = alloc_bootmem_low_pages(bytes);
   33.39  	if (!iotlb_virt_start)
   33.40 -		panic("Cannot allocate SWIOTLB buffer!\n"
   33.41 -		      "Use dom0_mem Xen boot parameter to reserve\n"
   33.42 -		      "some DMA memory (e.g., dom0_mem=-128M).\n");
   33.43 +		panic("Cannot allocate SWIOTLB buffer!\n");
   33.44  
   33.45 +	dma_bits = get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT) + PAGE_SHIFT;
   33.46  	for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
   33.47 -		int rc = xen_create_contiguous_region(
   33.48 -			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
   33.49 -			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
   33.50 -			dma_bits);
   33.51 -		BUG_ON(rc);
   33.52 +		do {
   33.53 +			rc = xen_create_contiguous_region(
   33.54 +				(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
   33.55 +				get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
   33.56 +				dma_bits);
   33.57 +		} while (rc && dma_bits++ < max_dma_bits);
   33.58 +		if (rc) {
   33.59 +			if (i == 0)
   33.60 +				panic("No suitable physical memory available for SWIOTLB buffer!\n"
   33.61 +				      "Use dom0_mem Xen boot parameter to reserve\n"
   33.62 +				      "some DMA memory (e.g., dom0_mem=-128M).\n");
   33.63 +			iotlb_nslabs = i;
   33.64 +			i <<= IO_TLB_SHIFT;
   33.65 +			free_bootmem(__pa(iotlb_virt_start + i), bytes - i);
   33.66 +			bytes = i;
   33.67 +			for (dma_bits = 0; i > 0; i -= IO_TLB_SEGSIZE << IO_TLB_SHIFT) {
   33.68 +				unsigned int bits = fls64(virt_to_bus(iotlb_virt_start + i - 1));
   33.69 +
   33.70 +				if (bits > dma_bits)
   33.71 +					dma_bits = bits;
   33.72 +			}
   33.73 +			break;
   33.74 +		}
   33.75  	}
   33.76  
   33.77  	/*
   33.78 @@ -186,17 +202,27 @@ swiotlb_init_with_default_size (size_t d
   33.79  	 * Get the overflow emergency buffer
   33.80  	 */
   33.81  	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
   33.82 +	if (!io_tlb_overflow_buffer)
   33.83 +		panic("Cannot allocate SWIOTLB overflow buffer!\n");
   33.84 +
   33.85 +	do {
   33.86 +		rc = xen_create_contiguous_region(
   33.87 +			(unsigned long)io_tlb_overflow_buffer,
   33.88 +			get_order(io_tlb_overflow),
   33.89 +			dma_bits);
   33.90 +	} while (rc && dma_bits++ < max_dma_bits);
   33.91 +	if (rc)
   33.92 +		panic("No suitable physical memory available for SWIOTLB overflow buffer!\n");
   33.93  
   33.94  	iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
   33.95  	iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
   33.96  
   33.97  	printk(KERN_INFO "Software IO TLB enabled: \n"
   33.98  	       " Aperture:     %lu megabytes\n"
   33.99 -	       " Kernel range: 0x%016lx - 0x%016lx\n"
  33.100 +	       " Kernel range: %p - %p\n"
  33.101  	       " Address size: %u bits\n",
  33.102  	       bytes >> 20,
  33.103 -	       (unsigned long)iotlb_virt_start,
  33.104 -	       (unsigned long)iotlb_virt_start + bytes,
  33.105 +	       iotlb_virt_start, iotlb_virt_start + bytes,
  33.106  	       dma_bits);
  33.107  }
  33.108  
  33.109 @@ -238,9 +264,12 @@ static void
  33.110  		char *dev, *host, *kmp;
  33.111  		len = size;
  33.112  		while (len != 0) {
  33.113 +			unsigned long flags;
  33.114 +
  33.115  			if (((bytes = len) + buffer.offset) > PAGE_SIZE)
  33.116  				bytes = PAGE_SIZE - buffer.offset;
  33.117 -			kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
  33.118 +			local_irq_save(flags); /* protects KM_BOUNCE_READ */
  33.119 +			kmp  = kmap_atomic(buffer.page, KM_BOUNCE_READ);
  33.120  			dev  = dma_addr + size - len;
  33.121  			host = kmp + buffer.offset;
  33.122  			if (dir == DMA_FROM_DEVICE) {
  33.123 @@ -248,7 +277,8 @@ static void
  33.124  					/* inaccessible */;
  33.125  			} else
  33.126  				memcpy(dev, host, bytes);
  33.127 -			kunmap_atomic(kmp, KM_SWIOTLB);
  33.128 +			kunmap_atomic(kmp, KM_BOUNCE_READ);
  33.129 +			local_irq_restore(flags);
  33.130  			len -= bytes;
  33.131  			buffer.page++;
  33.132  			buffer.offset = 0;
  33.133 @@ -617,6 +647,8 @@ swiotlb_sync_sg_for_device(struct device
  33.134  				    sg->dma_length, dir);
  33.135  }
  33.136  
  33.137 +#ifdef CONFIG_HIGHMEM
  33.138 +
  33.139  dma_addr_t
  33.140  swiotlb_map_page(struct device *hwdev, struct page *page,
  33.141  		 unsigned long offset, size_t size,
  33.142 @@ -650,6 +682,8 @@ swiotlb_unmap_page(struct device *hwdev,
  33.143  		unmap_single(hwdev, bus_to_virt(dma_address), size, direction);
  33.144  }
  33.145  
  33.146 +#endif
  33.147 +
  33.148  int
  33.149  swiotlb_dma_mapping_error(dma_addr_t dma_addr)
  33.150  {
  33.151 @@ -677,7 +711,5 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_cp
  33.152  EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  33.153  EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
  33.154  EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
  33.155 -EXPORT_SYMBOL(swiotlb_map_page);
  33.156 -EXPORT_SYMBOL(swiotlb_unmap_page);
  33.157  EXPORT_SYMBOL(swiotlb_dma_mapping_error);
  33.158  EXPORT_SYMBOL(swiotlb_dma_supported);
    34.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Thu Jan 18 09:54:33 2007 +0000
    34.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Thu Jan 18 15:18:07 2007 +0000
    34.3 @@ -262,16 +262,19 @@ static void dump_fault_path(unsigned lon
    34.4  	p += (address >> 30) * 2;
    34.5  	printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
    34.6  	if (p[0] & 1) {
    34.7 -		mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
    34.8 +		mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
    34.9  		page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   34.10  		p  = (unsigned long *)__va(page);
   34.11  		address &= 0x3fffffff;
   34.12  		p += (address >> 21) * 2;
   34.13  		printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", 
   34.14  		       page, p[1], p[0]);
   34.15 -#ifndef CONFIG_HIGHPTE
   34.16 +		mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
   34.17 +#ifdef CONFIG_HIGHPTE
   34.18 +		if (mfn_to_pfn(mfn) >= highstart_pfn)
   34.19 +			return;
   34.20 +#endif
   34.21  		if (p[0] & 1) {
   34.22 -			mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
   34.23  			page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   34.24  			p  = (unsigned long *) __va(page);
   34.25  			address &= 0x001fffff;
   34.26 @@ -279,7 +282,6 @@ static void dump_fault_path(unsigned lon
   34.27  			printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n",
   34.28  			       page, p[1], p[0]);
   34.29  		}
   34.30 -#endif
   34.31  	}
   34.32  }
   34.33  #else
   34.34 @@ -294,11 +296,14 @@ static void dump_fault_path(unsigned lon
   34.35  		       machine_to_phys(page));
   34.36  	/*
   34.37  	 * We must not directly access the pte in the highpte
   34.38 -	 * case, the page table might be allocated in highmem.
   34.39 +	 * case if the page table is located in highmem.
   34.40  	 * And lets rather not kmap-atomic the pte, just in case
   34.41  	 * it's allocated already.
   34.42  	 */
   34.43 -#ifndef CONFIG_HIGHPTE
   34.44 +#ifdef CONFIG_HIGHPTE
   34.45 +	if ((page >> PAGE_SHIFT) >= highstart_pfn)
   34.46 +		return;
   34.47 +#endif
   34.48  	if ((page & 1) && oops_may_print()) {
   34.49  		page &= PAGE_MASK;
   34.50  		address &= 0x003ff000;
   34.51 @@ -307,7 +312,6 @@ static void dump_fault_path(unsigned lon
   34.52  		printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page,
   34.53  		       machine_to_phys(page));
   34.54  	}
   34.55 -#endif
   34.56  }
   34.57  #endif
   34.58  
    35.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Thu Jan 18 09:54:33 2007 +0000
    35.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Thu Jan 18 15:18:07 2007 +0000
    35.3 @@ -129,5 +129,6 @@ struct page *kmap_atomic_to_page(void *p
    35.4  EXPORT_SYMBOL(kmap);
    35.5  EXPORT_SYMBOL(kunmap);
    35.6  EXPORT_SYMBOL(kmap_atomic);
    35.7 +EXPORT_SYMBOL(kmap_atomic_pte);
    35.8  EXPORT_SYMBOL(kunmap_atomic);
    35.9  EXPORT_SYMBOL(kmap_atomic_to_page);
    36.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Thu Jan 18 09:54:33 2007 +0000
    36.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Thu Jan 18 15:18:07 2007 +0000
    36.3 @@ -239,23 +239,41 @@ struct page *pte_alloc_one(struct mm_str
    36.4  
    36.5  #ifdef CONFIG_HIGHPTE
    36.6  	pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
    36.7 +	if (pte && PageHighMem(pte)) {
    36.8 +		struct mmuext_op op;
    36.9 +
   36.10 +		kmap_flush_unused();
   36.11 +		op.cmd = MMUEXT_PIN_L1_TABLE;
   36.12 +		op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte));
   36.13 +		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   36.14 +	}
   36.15  #else
   36.16  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
   36.17 +#endif
   36.18  	if (pte) {
   36.19  		SetPageForeign(pte, pte_free);
   36.20  		init_page_count(pte);
   36.21  	}
   36.22 -#endif
   36.23  	return pte;
   36.24  }
   36.25  
   36.26  void pte_free(struct page *pte)
   36.27  {
   36.28 -	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
   36.29 +	unsigned long pfn = page_to_pfn(pte);
   36.30 +
   36.31 +	if (!PageHighMem(pte)) {
   36.32 +		unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
   36.33  
   36.34 -	if (!pte_write(*virt_to_ptep(va)))
   36.35 -		BUG_ON(HYPERVISOR_update_va_mapping(
   36.36 -			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
   36.37 +		if (!pte_write(*virt_to_ptep(va)))
   36.38 +			BUG_ON(HYPERVISOR_update_va_mapping(
   36.39 +			       va, pfn_pte(pfn, PAGE_KERNEL), 0));
   36.40 +	} else {
   36.41 +		struct mmuext_op op;
   36.42 +
   36.43 +		op.cmd = MMUEXT_UNPIN_TABLE;
   36.44 +		op.arg1.mfn = pfn_to_mfn(pfn);
   36.45 +		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   36.46 +	}
   36.47  
   36.48  	ClearPageForeign(pte);
   36.49  	init_page_count(pte);
    37.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Thu Jan 18 09:54:33 2007 +0000
    37.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Thu Jan 18 15:18:07 2007 +0000
    37.3 @@ -163,6 +163,18 @@ void _arch_exit_mmap(struct mm_struct *m
    37.4          mm_unpin(mm);
    37.5  }
    37.6  
    37.7 +struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
    37.8 +{
    37.9 +	struct page *pte;
   37.10 +
   37.11 +	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
   37.12 +	if (pte) {
   37.13 +		SetPageForeign(pte, pte_free);
   37.14 +		init_page_count(pte);
   37.15 +	}
   37.16 +	return pte;
   37.17 +}
   37.18 +
   37.19  void pte_free(struct page *pte)
   37.20  {
   37.21  	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
   37.22 @@ -170,6 +182,10 @@ void pte_free(struct page *pte)
   37.23  	if (!pte_write(*virt_to_ptep(va)))
   37.24  		BUG_ON(HYPERVISOR_update_va_mapping(
   37.25  			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
   37.26 +
   37.27 +	ClearPageForeign(pte);
   37.28 +	init_page_count(pte);
   37.29 +
   37.30  	__free_page(pte);
   37.31  }
   37.32  #endif	/* CONFIG_XEN */
    38.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Jan 18 09:54:33 2007 +0000
    38.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Jan 18 15:18:07 2007 +0000
    38.3 @@ -42,9 +42,30 @@ static int connect_ring(struct backend_i
    38.4  static void backend_changed(struct xenbus_watch *, const char **,
    38.5  			    unsigned int);
    38.6  
    38.7 +static int blkback_name(blkif_t *blkif, char *buf)
    38.8 +{
    38.9 +	char *devpath, *devname;
   38.10 +	struct xenbus_device *dev = blkif->be->dev;
   38.11 +
   38.12 +	devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
   38.13 +	if (IS_ERR(devpath)) 
   38.14 +		return PTR_ERR(devpath);
   38.15 +	
   38.16 +	if ((devname = strstr(devpath, "/dev/")) != NULL)
   38.17 +		devname += strlen("/dev/");
   38.18 +	else
   38.19 +		devname  = devpath;
   38.20 +
   38.21 +	snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname);
   38.22 +	kfree(devpath);
   38.23 +	
   38.24 +	return 0;
   38.25 +}
   38.26 +
   38.27  static void update_blkif_status(blkif_t *blkif)
   38.28  { 
   38.29  	int err;
   38.30 +	char name[TASK_COMM_LEN];
   38.31  
   38.32  	/* Not ready to connect? */
   38.33  	if (!blkif->irq || !blkif->vbd.bdev)
   38.34 @@ -59,10 +80,13 @@ static void update_blkif_status(blkif_t 
   38.35  	if (blkif->be->dev->state != XenbusStateConnected)
   38.36  		return;
   38.37  
   38.38 -	blkif->xenblkd = kthread_run(blkif_schedule, blkif,
   38.39 -				     "xvd %d %02x:%02x",
   38.40 -				     blkif->domid,
   38.41 -				     blkif->be->major, blkif->be->minor);
   38.42 +	err = blkback_name(blkif, name);
   38.43 +	if (err) {
   38.44 +		xenbus_dev_error(blkif->be->dev, err, "get blkback dev name");
   38.45 +		return;
   38.46 +	}
   38.47 +
   38.48 +	blkif->xenblkd = kthread_run(blkif_schedule, blkif, name);
   38.49  	if (IS_ERR(blkif->xenblkd)) {
   38.50  		err = PTR_ERR(blkif->xenblkd);
   38.51  		blkif->xenblkd = NULL;
    39.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Thu Jan 18 09:54:33 2007 +0000
    39.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Thu Jan 18 15:18:07 2007 +0000
    39.3 @@ -92,9 +92,30 @@ static long get_id(const char *str)
    39.4          return simple_strtol(num, NULL, 10);
    39.5  }				
    39.6  
    39.7 +static int blktap_name(blkif_t *blkif, char *buf)
    39.8 +{
    39.9 +	char *devpath, *devname;
   39.10 +	struct xenbus_device *dev = blkif->be->dev;
   39.11 +
   39.12 +	devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
   39.13 +	if (IS_ERR(devpath)) 
   39.14 +		return PTR_ERR(devpath);
   39.15 +	
   39.16 +	if ((devname = strstr(devpath, "/dev/")) != NULL)
   39.17 +		devname += strlen("/dev/");
   39.18 +	else
   39.19 +		devname  = devpath;
   39.20 +
   39.21 +	snprintf(buf, TASK_COMM_LEN, "blktap.%d.%s", blkif->domid, devname);
   39.22 +	kfree(devpath);
   39.23 +	
   39.24 +	return 0;
   39.25 +}
   39.26 +
   39.27  static void tap_update_blkif_status(blkif_t *blkif)
   39.28  { 
   39.29  	int err;
   39.30 +	char name[TASK_COMM_LEN];
   39.31  
   39.32  	/* Not ready to connect? */
   39.33  	if(!blkif->irq || !blkif->sectors) {
   39.34 @@ -110,10 +131,13 @@ static void tap_update_blkif_status(blki
   39.35  	if (blkif->be->dev->state != XenbusStateConnected)
   39.36  		return;
   39.37  
   39.38 -	blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif,
   39.39 -				     "xvd %d",
   39.40 -				     blkif->domid);
   39.41 +	err = blktap_name(blkif, name);
   39.42 +	if (err) {
   39.43 +		xenbus_dev_error(blkif->be->dev, err, "get blktap dev name");
   39.44 +		return;
   39.45 +	}
   39.46  
   39.47 +	blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
   39.48  	if (IS_ERR(blkif->xenblkd)) {
   39.49  		err = PTR_ERR(blkif->xenblkd);
   39.50  		blkif->xenblkd = NULL;
    40.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c	Thu Jan 18 09:54:33 2007 +0000
    40.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c	Thu Jan 18 15:18:07 2007 +0000
    40.3 @@ -98,8 +98,8 @@ void xen_machine_kexec_setup_resources(v
    40.4   err:
    40.5  	/*
    40.6  	 * It isn't possible to free xen_phys_cpus this early in the
    40.7 -	 * boot. Since failure at this stage is unexpected and the
    40.8 -	 * amount is small we leak the memory.
    40.9 +	 * boot. Failure at this stage is unexpected and the amount of
   40.10 +	 * memory is small therefore we tolerate the potential leak.
   40.11           */
   40.12  	xen_max_nr_phys_cpus = 0;
   40.13  	return;
    41.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h	Thu Jan 18 09:54:33 2007 +0000
    41.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h	Thu Jan 18 15:18:07 2007 +0000
    41.3 @@ -53,6 +53,7 @@ extern int dma_map_sg(struct device *hwd
    41.4  extern void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg,
    41.5  			 int nents, enum dma_data_direction direction);
    41.6  
    41.7 +#ifdef CONFIG_HIGHMEM
    41.8  extern dma_addr_t
    41.9  dma_map_page(struct device *dev, struct page *page, unsigned long offset,
   41.10  	     size_t size, enum dma_data_direction direction);
   41.11 @@ -60,6 +61,11 @@ dma_map_page(struct device *dev, struct 
   41.12  extern void
   41.13  dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
   41.14  	       enum dma_data_direction direction);
   41.15 +#else
   41.16 +#define dma_map_page(dev, page, offset, size, dir) \
   41.17 +	dma_map_single(dev, page_address(page) + (offset), (size), (dir))
   41.18 +#define dma_unmap_page dma_unmap_single
   41.19 +#endif
   41.20  
   41.21  extern void
   41.22  dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
    42.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h	Thu Jan 18 09:54:33 2007 +0000
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,31 +0,0 @@
    42.4 -#ifndef _ASM_KMAP_TYPES_H
    42.5 -#define _ASM_KMAP_TYPES_H
    42.6 -
    42.7 -
    42.8 -#ifdef CONFIG_DEBUG_HIGHMEM
    42.9 -# define D(n) __KM_FENCE_##n ,
   42.10 -#else
   42.11 -# define D(n)
   42.12 -#endif
   42.13 -
   42.14 -enum km_type {
   42.15 -D(0)	KM_BOUNCE_READ,
   42.16 -D(1)	KM_SKB_SUNRPC_DATA,
   42.17 -D(2)	KM_SKB_DATA_SOFTIRQ,
   42.18 -D(3)	KM_USER0,
   42.19 -D(4)	KM_USER1,
   42.20 -D(5)	KM_BIO_SRC_IRQ,
   42.21 -D(6)	KM_BIO_DST_IRQ,
   42.22 -D(7)	KM_PTE0,
   42.23 -D(8)	KM_PTE1,
   42.24 -D(9)	KM_IRQ0,
   42.25 -D(10)	KM_IRQ1,
   42.26 -D(11)	KM_SOFTIRQ0,
   42.27 -D(12)	KM_SOFTIRQ1,
   42.28 -D(13)	KM_SWIOTLB,
   42.29 -D(14)	KM_TYPE_NR
   42.30 -};
   42.31 -
   42.32 -#undef D
   42.33 -
   42.34 -#endif
    43.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Thu Jan 18 09:54:33 2007 +0000
    43.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Thu Jan 18 15:18:07 2007 +0000
    43.3 @@ -41,7 +41,7 @@ extern struct page *pte_alloc_one(struct
    43.4  static inline void pte_free_kernel(pte_t *pte)
    43.5  {
    43.6  	free_page((unsigned long)pte);
    43.7 -	make_page_writable(pte, XENFEAT_writable_page_tables);
    43.8 +	make_lowmem_page_writable(pte, XENFEAT_writable_page_tables);
    43.9  }
   43.10  
   43.11  extern void pte_free(struct page *pte);
    44.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h	Thu Jan 18 09:54:33 2007 +0000
    44.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h	Thu Jan 18 15:18:07 2007 +0000
    44.3 @@ -26,16 +26,16 @@ extern int swiotlb_map_sg(struct device 
    44.4  extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
    44.5  			 int nents, int direction);
    44.6  extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
    44.7 +#ifdef CONFIG_HIGHMEM
    44.8  extern dma_addr_t swiotlb_map_page(struct device *hwdev, struct page *page,
    44.9                                     unsigned long offset, size_t size,
   44.10                                     enum dma_data_direction direction);
   44.11  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
   44.12                                 size_t size, enum dma_data_direction direction);
   44.13 +#endif
   44.14  extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
   44.15  extern void swiotlb_init(void);
   44.16  
   44.17 -extern unsigned int dma_bits;
   44.18 -
   44.19  #ifdef CONFIG_SWIOTLB
   44.20  extern int swiotlb;
   44.21  #else
    45.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h	Thu Jan 18 09:54:33 2007 +0000
    45.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h	Thu Jan 18 15:18:07 2007 +0000
    45.3 @@ -64,42 +64,35 @@ static inline void pgd_populate(struct m
    45.4  	}
    45.5  }
    45.6  
    45.7 -static inline void pmd_free(pmd_t *pmd)
    45.8 -{
    45.9 -	pte_t *ptep = virt_to_ptep(pmd);
   45.10 -
   45.11 -	if (!pte_write(*ptep)) {
   45.12 -		BUG_ON(HYPERVISOR_update_va_mapping(
   45.13 -			(unsigned long)pmd,
   45.14 -			pfn_pte(virt_to_phys(pmd)>>PAGE_SHIFT, PAGE_KERNEL),
   45.15 -			0));
   45.16 -	}
   45.17 -	free_page((unsigned long)pmd);
   45.18 -}
   45.19 +extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
   45.20 +extern void pte_free(struct page *pte);
   45.21  
   45.22  static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
   45.23  {
   45.24 -        pmd_t *pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   45.25 -        return pmd;
   45.26 +	struct page *pg;
   45.27 +
   45.28 +	pg = pte_alloc_one(mm, addr);
   45.29 +	return pg ? page_address(pg) : NULL;
   45.30 +}
   45.31 +
   45.32 +static inline void pmd_free(pmd_t *pmd)
   45.33 +{
   45.34 +	BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
   45.35 +	pte_free(virt_to_page(pmd));
   45.36  }
   45.37  
   45.38  static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
   45.39  {
   45.40 -        pud_t *pud = (pud_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   45.41 -        return pud;
   45.42 +	struct page *pg;
   45.43 +
   45.44 +	pg = pte_alloc_one(mm, addr);
   45.45 +	return pg ? page_address(pg) : NULL;
   45.46  }
   45.47  
   45.48  static inline void pud_free(pud_t *pud)
   45.49  {
   45.50 -	pte_t *ptep = virt_to_ptep(pud);
   45.51 -
   45.52 -	if (!pte_write(*ptep)) {
   45.53 -		BUG_ON(HYPERVISOR_update_va_mapping(
   45.54 -			(unsigned long)pud,
   45.55 -			pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, PAGE_KERNEL),
   45.56 -			0));
   45.57 -	}
   45.58 -	free_page((unsigned long)pud);
   45.59 +	BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
   45.60 +	pte_free(virt_to_page(pud));
   45.61  }
   45.62  
   45.63  static inline void pgd_list_add(pgd_t *pgd)
   45.64 @@ -130,10 +123,10 @@ static inline void pgd_list_del(pgd_t *p
   45.65  
   45.66  static inline pgd_t *pgd_alloc(struct mm_struct *mm)
   45.67  {
   45.68 -        /*
   45.69 -         * We allocate two contiguous pages for kernel and user.
   45.70 -         */
   45.71 -        unsigned boundary;
   45.72 +	/*
   45.73 +	 * We allocate two contiguous pages for kernel and user.
   45.74 +	 */
   45.75 +	unsigned boundary;
   45.76  	pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1);
   45.77  	if (!pgd)
   45.78  		return NULL;
   45.79 @@ -150,11 +143,11 @@ static inline pgd_t *pgd_alloc(struct mm
   45.80  	       (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
   45.81  
   45.82  	memset(__user_pgd(pgd), 0, PAGE_SIZE); /* clean up user pgd */
   45.83 -        /*
   45.84 -         * Set level3_user_pgt for vsyscall area
   45.85 -         */
   45.86 +	/*
   45.87 +	 * Set level3_user_pgt for vsyscall area
   45.88 +	 */
   45.89  	set_pgd(__user_pgd(pgd) + pgd_index(VSYSCALL_START), 
   45.90 -                mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
   45.91 +		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
   45.92  	return pgd;
   45.93  }
   45.94  
   45.95 @@ -187,39 +180,25 @@ static inline void pgd_free(pgd_t *pgd)
   45.96  
   45.97  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
   45.98  {
   45.99 -        pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
  45.100 -        if (pte)
  45.101 +	pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
  45.102 +	if (pte)
  45.103  		make_page_readonly(pte, XENFEAT_writable_page_tables);
  45.104  
  45.105  	return pte;
  45.106  }
  45.107  
  45.108 -static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  45.109 -{
  45.110 -	struct page *pte;
  45.111 -
  45.112 -	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
  45.113 -	return pte;
  45.114 -}
  45.115 -
  45.116  /* Should really implement gc for free page table pages. This could be
  45.117     done with a reference count in struct page. */
  45.118  
  45.119  static inline void pte_free_kernel(pte_t *pte)
  45.120  {
  45.121  	BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
  45.122 -        make_page_writable(pte, XENFEAT_writable_page_tables);
  45.123 +	make_page_writable(pte, XENFEAT_writable_page_tables);
  45.124  	free_page((unsigned long)pte); 
  45.125  }
  45.126  
  45.127 -extern void pte_free(struct page *pte);
  45.128 -
  45.129 -//#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) 
  45.130 -//#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  45.131 -//#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  45.132 -
  45.133 -#define __pte_free_tlb(tlb,x)   pte_free((x))
  45.134 -#define __pmd_free_tlb(tlb,x)   pmd_free((x))
  45.135 -#define __pud_free_tlb(tlb,x)   pud_free((x))
  45.136 +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
  45.137 +#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  45.138 +#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  45.139  
  45.140  #endif /* _X86_64_PGALLOC_H */
    46.1 --- a/linux-2.6-xen-sparse/kernel/kexec.c	Thu Jan 18 09:54:33 2007 +0000
    46.2 +++ b/linux-2.6-xen-sparse/kernel/kexec.c	Thu Jan 18 15:18:07 2007 +0000
    46.3 @@ -1012,9 +1012,11 @@ asmlinkage long sys_kexec_load(unsigned 
    46.4  			goto out;
    46.5  	}
    46.6  #ifdef CONFIG_XEN
    46.7 -	result = xen_machine_kexec_load(image);
    46.8 -	if (result)
    46.9 -		goto out;
   46.10 +	if (image) {
   46.11 +		result = xen_machine_kexec_load(image);
   46.12 +		if (result)
   46.13 +			goto out;
   46.14 +	}
   46.15  #endif
   46.16  	/* Install the new kernel, and  Uninstall the old */
   46.17  	image = xchg(dest_image, image);
    47.1 --- a/patches/linux-2.6.18/ipv6-no-autoconf.patch	Thu Jan 18 09:54:33 2007 +0000
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,19 +0,0 @@
    47.4 -diff -pruN ../orig-linux-2.6.18/net/ipv6/addrconf.c ./net/ipv6/addrconf.c
    47.5 ---- ../orig-linux-2.6.18/net/ipv6/addrconf.c	2006-09-20 04:42:06.000000000 +0100
    47.6 -+++ ./net/ipv6/addrconf.c	2007-01-12 16:08:07.000000000 +0000
    47.7 -@@ -2514,6 +2514,7 @@ static void addrconf_dad_start(struct in
    47.8 - 	spin_lock_bh(&ifp->lock);
    47.9 - 
   47.10 - 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
   47.11 -+	    !(dev->flags&IFF_MULTICAST) ||
   47.12 - 	    !(ifp->flags&IFA_F_TENTATIVE)) {
   47.13 - 		ifp->flags &= ~IFA_F_TENTATIVE;
   47.14 - 		spin_unlock_bh(&ifp->lock);
   47.15 -@@ -2598,6 +2599,7 @@ static void addrconf_dad_completed(struc
   47.16 - 	if (ifp->idev->cnf.forwarding == 0 &&
   47.17 - 	    ifp->idev->cnf.rtr_solicits > 0 &&
   47.18 - 	    (dev->flags&IFF_LOOPBACK) == 0 &&
   47.19 -+	    (dev->flags & IFF_MULTICAST) &&
   47.20 - 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
   47.21 - 		struct in6_addr all_routers;
   47.22 - 
    48.1 --- a/patches/linux-2.6.18/series	Thu Jan 18 09:54:33 2007 +0000
    48.2 +++ b/patches/linux-2.6.18/series	Thu Jan 18 15:18:07 2007 +0000
    48.3 @@ -5,7 +5,6 @@ linux-2.6.19-rc1-kexec-move_segment_code
    48.4  blktap-aio-16_03_06.patch
    48.5  fix-ide-cd-pio-mode.patch
    48.6  i386-mach-io-check-nmi.patch
    48.7 -ipv6-no-autoconf.patch
    48.8  net-csum.patch
    48.9  net-gso-5-rcv-mss.patch
   48.10  net-gso-6-linear-segmentation.patch
    49.1 --- a/tools/check/check_udev	Thu Jan 18 09:54:33 2007 +0000
    49.2 +++ b/tools/check/check_udev	Thu Jan 18 15:18:07 2007 +0000
    49.3 @@ -11,7 +11,7 @@ OpenBSD|NetBSD|FreeBSD)
    49.4  Linux)
    49.5  	TOOL="udevinfo"
    49.6  	UDEV_VERSION="0"
    49.7 -	test -x "$(which ${TOOL})" && \
    49.8 +	test -x "$(which ${TOOL} 2>/dev/null)" && \
    49.9  		UDEV_VERSION=$(${TOOL} -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
   49.10  	if test "${UDEV_VERSION}" -ge 059; then
   49.11  		RC=0
   49.12 @@ -28,7 +28,7 @@ esac
   49.13  
   49.14  if test ${RC} -ne 0; then
   49.15  	echo
   49.16 -	echo ' *** Check for ${TOOL} FAILED'
   49.17 +	echo " *** Check for ${TOOL} FAILED"
   49.18  fi
   49.19  
   49.20  exit ${RC}
    50.1 --- a/tools/examples/vtpm-common.sh	Thu Jan 18 09:54:33 2007 +0000
    50.2 +++ b/tools/examples/vtpm-common.sh	Thu Jan 18 15:18:07 2007 +0000
    50.3 @@ -24,7 +24,9 @@ VTPMDB="/etc/xen/vtpm.db"
    50.4  
    50.5  #In the vtpm-impl file some commands should be defined:
    50.6  #      vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
    50.7 -if [ -r "$dir/vtpm-impl" ]; then
    50.8 +if [ -r "$dir/vtpm-impl.alt" ]; then
    50.9 +	. "$dir/vtpm-impl.alt"
   50.10 +elif [ -r "$dir/vtpm-impl" ]; then
   50.11  	. "$dir/vtpm-impl"
   50.12  else
   50.13  	function vtpm_create () {
    51.1 --- a/tools/examples/xen-network-common.sh	Thu Jan 18 09:54:33 2007 +0000
    51.2 +++ b/tools/examples/xen-network-common.sh	Thu Jan 18 15:18:07 2007 +0000
    51.3 @@ -117,7 +117,12 @@ create_bridge () {
    51.4          ip link set ${bridge} arp off
    51.5          ip link set ${bridge} multicast off
    51.6      fi
    51.7 +
    51.8 +    # A small MTU disables IPv6 (and therefore IPv6 addrconf).
    51.9 +    mtu=$(ip link show ${bridge} | sed -n 's/.* mtu \([0-9]\+\).*/\1/p')
   51.10 +    ip link set ${bridge} mtu 68
   51.11      ip link set ${bridge} up
   51.12 +    ip link set ${bridge} mtu ${mtu:-1500}
   51.13  }
   51.14  
   51.15  # Usage: add_to_bridge bridge dev
    52.1 --- a/tools/examples/xmexample1	Thu Jan 18 09:54:33 2007 +0000
    52.2 +++ b/tools/examples/xmexample1	Thu Jan 18 15:18:07 2007 +0000
    52.3 @@ -66,6 +66,40 @@ vif = [ '' ]
    52.4  disk = [ 'phy:hda1,hda1,w' ]
    52.5  
    52.6  #----------------------------------------------------------------------------
    52.7 +# Define frame buffer device.
    52.8 +#
    52.9 +# By default, no frame buffer device is configured.
   52.10 +#
   52.11 +# To create one using the SDL backend and sensible defaults:
   52.12 +#
   52.13 +# vfb = [ 'type=sdl' ]
   52.14 +#
   52.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   52.16 +# can override that:
   52.17 +#
   52.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   52.19 +#
   52.20 +# To create one using the VNC backend and sensible defaults:
   52.21 +#
   52.22 +# vfb = [ 'type=vnc' ]
   52.23 +#
   52.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   52.25 +# the domain ID.  You can override both address and N:
   52.26 +#
   52.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=1' ]
   52.28 +#
   52.29 +# Or you can bind the first unused port above 5900:
   52.30 +#
   52.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   52.32 +#
   52.33 +# You can override the password:
   52.34 +#
   52.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   52.36 +#
   52.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   52.38 +# configured in xend-config.sxp.
   52.39 +
   52.40 +#----------------------------------------------------------------------------
   52.41  # Define to which TPM instance the user domain should communicate.
   52.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   52.43  # where INSTANCE indicates the instance number of the TPM the VM
    53.1 --- a/tools/examples/xmexample2	Thu Jan 18 09:54:33 2007 +0000
    53.2 +++ b/tools/examples/xmexample2	Thu Jan 18 15:18:07 2007 +0000
    53.3 @@ -102,6 +102,40 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
    53.4           'phy:sda6,sda6,r' ]
    53.5  
    53.6  #----------------------------------------------------------------------------
    53.7 +# Define frame buffer device.
    53.8 +#
    53.9 +# By default, no frame buffer device is configured.
   53.10 +#
   53.11 +# To create one using the SDL backend and sensible defaults:
   53.12 +#
   53.13 +# vfb = [ 'type=sdl' ]
   53.14 +#
   53.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   53.16 +# can override that:
   53.17 +#
   53.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   53.19 +#
   53.20 +# To create one using the VNC backend and sensible defaults:
   53.21 +#
   53.22 +# vfb = [ 'type=vnc' ]
   53.23 +#
   53.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   53.25 +# the domain ID.  You can override both address and N:
   53.26 +#
   53.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
   53.28 +#
   53.29 +# Or you can bind the first unused port above 5900:
   53.30 +#
   53.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   53.32 +#
   53.33 +# You can override the password:
   53.34 +#
   53.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   53.36 +#
   53.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   53.38 +# configured in xend-config.sxp.
   53.39 +
   53.40 +#----------------------------------------------------------------------------
   53.41  # Define to which TPM instance the user domain should communicate.
   53.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   53.43  # where INSTANCE indicates the instance number of the TPM the VM
    54.1 --- a/tools/examples/xmexample3	Thu Jan 18 09:54:33 2007 +0000
    54.2 +++ b/tools/examples/xmexample3	Thu Jan 18 15:18:07 2007 +0000
    54.3 @@ -87,6 +87,40 @@ vif = [ 'ip=192.168.%d.1/24' % (vmid)]
    54.4  disk = [ 'phy:hda%d,hda1,w' % (vmid)]
    54.5  
    54.6  #----------------------------------------------------------------------------
    54.7 +# Define frame buffer device.
    54.8 +#
    54.9 +# By default, no frame buffer device is configured.
   54.10 +#
   54.11 +# To create one using the SDL backend and sensible defaults:
   54.12 +#
   54.13 +# vfb = [ 'type=sdl' ]
   54.14 +#
   54.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   54.16 +# can override that:
   54.17 +#
   54.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   54.19 +#
   54.20 +# To create one using the VNC backend and sensible defaults:
   54.21 +#
   54.22 +# vfb = [ 'type=vnc' ]
   54.23 +#
   54.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   54.25 +# the domain ID.  You can override both address and N:
   54.26 +#
   54.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
   54.28 +#
   54.29 +# Or you can bind the first unused port above 5900:
   54.30 +#
   54.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   54.32 +#
   54.33 +# You can override the password:
   54.34 +#
   54.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   54.36 +#
   54.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   54.38 +# configured in xend-config.sxp.
   54.39 +
   54.40 +#----------------------------------------------------------------------------
   54.41  # Define to which TPM instance the user domain should communicate.
   54.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   54.43  # where INSTANCE indicates the instance number of the TPM the VM
    55.1 --- a/tools/libfsimage/common/fsimage.c	Thu Jan 18 09:54:33 2007 +0000
    55.2 +++ b/tools/libfsimage/common/fsimage.c	Thu Jan 18 15:18:07 2007 +0000
    55.3 @@ -74,7 +74,7 @@ void fsi_close_fsimage(fsi_t *fsi)
    55.4  	pthread_mutex_lock(&fsi_lock);
    55.5          fsi->f_plugin->fp_ops->fpo_umount(fsi);
    55.6          (void) close(fsi->f_fd);
    55.7 -	fsip_fs_free(fsi);
    55.8 +	free(fsi);
    55.9  	pthread_mutex_unlock(&fsi_lock);
   55.10  }
   55.11  
    56.1 --- a/tools/libfsimage/common/fsimage_grub.c	Thu Jan 18 09:54:33 2007 +0000
    56.2 +++ b/tools/libfsimage/common/fsimage_grub.c	Thu Jan 18 15:18:07 2007 +0000
    56.3 @@ -193,6 +193,7 @@ fsig_mount(fsi_t *fsi, const char *path)
    56.4  static int
    56.5  fsig_umount(fsi_t *fsi)
    56.6  {
    56.7 +	free(fsi->f_data);
    56.8  	return (0);
    56.9  }
   56.10  
   56.11 @@ -250,6 +251,7 @@ fsig_read(fsi_file_t *ffi, void *buf, si
   56.12  static int
   56.13  fsig_close(fsi_file_t *ffi)
   56.14  {
   56.15 +	free(ffi->ff_data);
   56.16  	fsip_file_free(ffi);
   56.17  	return (0);
   56.18  }
    57.1 --- a/tools/libfsimage/common/fsimage_plugin.c	Thu Jan 18 09:54:33 2007 +0000
    57.2 +++ b/tools/libfsimage/common/fsimage_plugin.c	Thu Jan 18 15:18:07 2007 +0000
    57.3 @@ -40,13 +40,6 @@ fsip_fs_set_data(fsi_t *fsi, void *data)
    57.4  	fsi->f_data = data;
    57.5  }
    57.6  
    57.7 -void
    57.8 -fsip_fs_free(fsi_t *fsi)
    57.9 -{
   57.10 -	free(fsi->f_data);
   57.11 -	free(fsi);
   57.12 -}
   57.13 -
   57.14  fsi_file_t *
   57.15  fsip_file_alloc(fsi_t *fsi, void *data)
   57.16  {
   57.17 @@ -64,7 +57,6 @@ fsip_file_alloc(fsi_t *fsi, void *data)
   57.18  void
   57.19  fsip_file_free(fsi_file_t *ffi)
   57.20  {
   57.21 -	free(ffi->ff_data);
   57.22  	free(ffi);
   57.23  }
   57.24  
    58.1 --- a/tools/libfsimage/common/fsimage_plugin.h	Thu Jan 18 09:54:33 2007 +0000
    58.2 +++ b/tools/libfsimage/common/fsimage_plugin.h	Thu Jan 18 15:18:07 2007 +0000
    58.3 @@ -50,11 +50,10 @@ typedef fsi_plugin_ops_t *
    58.4      (*fsi_plugin_init_t)(int, fsi_plugin_t *, const char **);
    58.5  
    58.6  void fsip_fs_set_data(fsi_t *, void *);
    58.7 -void fsip_fs_free(fsi_t *);
    58.8  fsi_file_t *fsip_file_alloc(fsi_t *, void *);
    58.9  void fsip_file_free(fsi_file_t *);
   58.10 -fsi_t * fsip_fs(fsi_file_t *ffi);
   58.11 -uint64_t fsip_fs_offset(fsi_t *fsi);
   58.12 +fsi_t *fsip_fs(fsi_file_t *);
   58.13 +uint64_t fsip_fs_offset(fsi_t *);
   58.14  void *fsip_fs_data(fsi_t *);
   58.15  void *fsip_file_data(fsi_file_t *);
   58.16  
    59.1 --- a/tools/libfsimage/common/mapfile-GNU	Thu Jan 18 09:54:33 2007 +0000
    59.2 +++ b/tools/libfsimage/common/mapfile-GNU	Thu Jan 18 15:18:07 2007 +0000
    59.3 @@ -1,5 +1,5 @@
    59.4  VERSION {
    59.5 -	libfsimage.so.1.1 {
    59.6 +	libfsimage.so.1.0 {
    59.7  		global:
    59.8  			fsi_open_fsimage;
    59.9  			fsi_close_fsimage;
   59.10 @@ -10,7 +10,6 @@ VERSION {
   59.11  			fsi_pread_file;
   59.12  	
   59.13  			fsip_fs_set_data;
   59.14 -			fsip_fs_free;
   59.15  			fsip_file_alloc;
   59.16  			fsip_file_free;
   59.17  			fsip_fs;
    60.1 --- a/tools/libfsimage/common/mapfile-SunOS	Thu Jan 18 09:54:33 2007 +0000
    60.2 +++ b/tools/libfsimage/common/mapfile-SunOS	Thu Jan 18 15:18:07 2007 +0000
    60.3 @@ -1,4 +1,4 @@
    60.4 -libfsimage.so.1.1 {
    60.5 +libfsimage.so.1.0 {
    60.6  	global:
    60.7  		fsi_open_fsimage;
    60.8  		fsi_close_fsimage;
    60.9 @@ -9,7 +9,6 @@ libfsimage.so.1.1 {
   60.10  		fsi_pread_file;
   60.11  
   60.12  		fsip_fs_set_data;
   60.13 -		fsip_fs_free;
   60.14  		fsip_file_alloc;
   60.15  		fsip_file_free;
   60.16  		fsip_fs;
    61.1 --- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c	Thu Jan 18 09:54:33 2007 +0000
    61.2 +++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c	Thu Jan 18 15:18:07 2007 +0000
    61.3 @@ -58,9 +58,11 @@ ext2lib_umount(fsi_t *fsi)
    61.4  {
    61.5  	ext2_filsys *fs = fsip_fs_data(fsi);
    61.6  	if (ext2fs_close(*fs) != 0) {
    61.7 +		free(fs);
    61.8  		errno = EINVAL;
    61.9  		return (-1);
   61.10  	}
   61.11 +	free(fs);
   61.12  	return (0);
   61.13  }
   61.14  
    62.1 --- a/tools/libxc/xc_hvm_build.c	Thu Jan 18 09:54:33 2007 +0000
    62.2 +++ b/tools/libxc/xc_hvm_build.c	Thu Jan 18 15:18:07 2007 +0000
    62.3 @@ -233,8 +233,7 @@ static int setup_guest(int xc_handle,
    62.4               SCRATCH_PFN)) == NULL) )
    62.5          goto error_out;
    62.6      memset(shared_info, 0, PAGE_SIZE);
    62.7 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
    62.8 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
    62.9 +    /* NB. evtchn_upcall_mask is unused: leave as zero. */
   62.10      memset(&shared_info->evtchn_mask[0], 0xff,
   62.11             sizeof(shared_info->evtchn_mask));
   62.12      munmap(shared_info, PAGE_SIZE);
    63.1 --- a/tools/libxc/xc_linux_build.c	Thu Jan 18 09:54:33 2007 +0000
    63.2 +++ b/tools/libxc/xc_linux_build.c	Thu Jan 18 15:18:07 2007 +0000
    63.3 @@ -741,7 +741,7 @@ static int setup_guest(int xc_handle,
    63.4          /*
    63.5           * Enable shadow translate mode. This must happen after
    63.6           * populate physmap because the p2m reservation is based on
    63.7 -         * the domains current memory allocation.
    63.8 +         * the domain's current memory allocation.
    63.9           */
   63.10          if ( xc_shadow_control(xc_handle, dom,
   63.11                             XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE,
    64.1 --- a/tools/libxc/xc_linux_restore.c	Thu Jan 18 09:54:33 2007 +0000
    64.2 +++ b/tools/libxc/xc_linux_restore.c	Thu Jan 18 15:18:07 2007 +0000
    64.3 @@ -12,7 +12,7 @@
    64.4  #include "xg_private.h"
    64.5  #include "xg_save_restore.h"
    64.6  
    64.7 -/* max mfn of the whole machine */
    64.8 +/* max mfn of the current host machine */
    64.9  static unsigned long max_mfn;
   64.10  
   64.11  /* virtual starting address of the hypervisor */
   64.12 @@ -30,6 +30,9 @@ static xen_pfn_t *live_p2m = NULL;
   64.13  /* A table mapping each PFN to its new MFN. */
   64.14  static xen_pfn_t *p2m = NULL;
   64.15  
   64.16 +/* A table of P2M mappings in the current region */
   64.17 +static xen_pfn_t *p2m_batch = NULL;
   64.18 +
   64.19  
   64.20  static ssize_t
   64.21  read_exact(int fd, void *buf, size_t count)
   64.22 @@ -57,46 +60,78 @@ read_exact(int fd, void *buf, size_t cou
   64.23  ** This function inverts that operation, replacing the pfn values with
   64.24  ** the (now known) appropriate mfn values.
   64.25  */
   64.26 -static int uncanonicalize_pagetable(unsigned long type, void *page)
   64.27 +static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, 
   64.28 +                                    unsigned long type, void *page)
   64.29  {
   64.30      int i, pte_last;
   64.31      unsigned long pfn;
   64.32      uint64_t pte;
   64.33 +    int nr_mfns = 0; 
   64.34  
   64.35      pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8);
   64.36  
   64.37 -    /* Now iterate through the page table, uncanonicalizing each PTE */
   64.38 +    /* First pass: work out how many (if any) MFNs we need to alloc */
   64.39 +    for(i = 0; i < pte_last; i++) {
   64.40 +        
   64.41 +        if(pt_levels == 2)
   64.42 +            pte = ((uint32_t *)page)[i];
   64.43 +        else
   64.44 +            pte = ((uint64_t *)page)[i];
   64.45 +        
   64.46 +        /* XXX SMH: below needs fixing for PROT_NONE etc */
   64.47 +        if(!(pte & _PAGE_PRESENT))
   64.48 +            continue; 
   64.49 +        
   64.50 +        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
   64.51 +        
   64.52 +        if(pfn >= max_pfn) {
   64.53 +            /* This "page table page" is probably not one; bail. */
   64.54 +            ERROR("Frame number in type %lu page table is out of range: "
   64.55 +                  "i=%d pfn=0x%lx max_pfn=%lu",
   64.56 +                  type >> 28, i, pfn, max_pfn);
   64.57 +            return 0;
   64.58 +        }
   64.59 +        
   64.60 +        if(p2m[pfn] == INVALID_P2M_ENTRY) {
   64.61 +            /* Have a 'valid' PFN without a matching MFN - need to alloc */
   64.62 +            p2m_batch[nr_mfns++] = pfn; 
   64.63 +        }
   64.64 +    }
   64.65 +    
   64.66 +    
   64.67 +    /* Alllocate the requistite number of mfns */
   64.68 +    if (nr_mfns && xc_domain_memory_populate_physmap(
   64.69 +            xc_handle, dom, nr_mfns, 0, 0, p2m_batch) != 0) { 
   64.70 +        ERROR("Failed to allocate memory for batch.!\n"); 
   64.71 +        errno = ENOMEM;
   64.72 +        return 0; 
   64.73 +    }
   64.74 +    
   64.75 +    /* Second pass: uncanonicalize each present PTE */
   64.76 +    nr_mfns = 0;
   64.77      for(i = 0; i < pte_last; i++) {
   64.78  
   64.79          if(pt_levels == 2)
   64.80              pte = ((uint32_t *)page)[i];
   64.81          else
   64.82              pte = ((uint64_t *)page)[i];
   64.83 -
   64.84 -        if(pte & _PAGE_PRESENT) {
   64.85 -
   64.86 -            pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
   64.87 -
   64.88 -            if(pfn >= max_pfn) {
   64.89 -                /* This "page table page" is probably not one; bail. */
   64.90 -                ERROR("Frame number in type %lu page table is out of range: "
   64.91 -                    "i=%d pfn=0x%lx max_pfn=%lu",
   64.92 -                    type >> 28, i, pfn, max_pfn);
   64.93 -                return 0;
   64.94 -            }
   64.95 +        
   64.96 +        /* XXX SMH: below needs fixing for PROT_NONE etc */
   64.97 +        if(!(pte & _PAGE_PRESENT))
   64.98 +            continue;
   64.99 +        
  64.100 +        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
  64.101 +        
  64.102 +        if(p2m[pfn] == INVALID_P2M_ENTRY)
  64.103 +            p2m[pfn] = p2m_batch[nr_mfns++];
  64.104  
  64.105 -
  64.106 -            pte &= 0xffffff0000000fffULL;
  64.107 -            pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
  64.108 +        pte &= 0xffffff0000000fffULL;
  64.109 +        pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
  64.110  
  64.111 -            if(pt_levels == 2)
  64.112 -                ((uint32_t *)page)[i] = (uint32_t)pte;
  64.113 -            else
  64.114 -                ((uint64_t *)page)[i] = (uint64_t)pte;
  64.115 -
  64.116 -
  64.117 -
  64.118 -        }
  64.119 +        if(pt_levels == 2)
  64.120 +            ((uint32_t *)page)[i] = (uint32_t)pte;
  64.121 +        else
  64.122 +            ((uint64_t *)page)[i] = (uint64_t)pte;
  64.123      }
  64.124  
  64.125      return 1;
  64.126 @@ -140,6 +175,7 @@ int xc_linux_restore(int xc_handle, int 
  64.127      /* A temporary mapping of the guest's start_info page. */
  64.128      start_info_t *start_info;
  64.129  
  64.130 +    /* Our mapping of the current region (batch) */
  64.131      char *region_base;
  64.132  
  64.133      xc_mmu_t *mmu = NULL;
  64.134 @@ -244,8 +280,10 @@ int xc_linux_restore(int xc_handle, int 
  64.135      p2m        = calloc(max_pfn, sizeof(xen_pfn_t));
  64.136      pfn_type   = calloc(max_pfn, sizeof(unsigned long));
  64.137      region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
  64.138 +    p2m_batch  = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
  64.139  
  64.140 -    if ((p2m == NULL) || (pfn_type == NULL) || (region_mfn == NULL)) {
  64.141 +    if ((p2m == NULL) || (pfn_type == NULL) ||
  64.142 +        (region_mfn == NULL) || (p2m_batch == NULL)) {
  64.143          ERROR("memory alloc failed");
  64.144          errno = ENOMEM;
  64.145          goto out;
  64.146 @@ -256,6 +294,11 @@ int xc_linux_restore(int xc_handle, int 
  64.147          goto out;
  64.148      }
  64.149  
  64.150 +    if (lock_pages(p2m_batch, sizeof(xen_pfn_t) * MAX_BATCH_SIZE)) {
  64.151 +        ERROR("Could not lock p2m_batch");
  64.152 +        goto out;
  64.153 +    }
  64.154 +
  64.155      /* Get the domain's shared-info frame. */
  64.156      domctl.cmd = XEN_DOMCTL_getdomaininfo;
  64.157      domctl.domain = (domid_t)dom;
  64.158 @@ -270,17 +313,9 @@ int xc_linux_restore(int xc_handle, int 
  64.159          goto out;
  64.160      }
  64.161  
  64.162 +    /* Mark all PFNs as invalid; we allocate on demand */
  64.163      for ( pfn = 0; pfn < max_pfn; pfn++ )
  64.164 -        p2m[pfn] = pfn;
  64.165 -
  64.166 -    if (xc_domain_memory_populate_physmap(xc_handle, dom, max_pfn,
  64.167 -                                          0, 0, p2m) != 0) {
  64.168 -        ERROR("Failed to increase reservation by %lx KB", PFN_TO_KB(max_pfn));
  64.169 -        errno = ENOMEM;
  64.170 -        goto out;
  64.171 -    }
  64.172 -
  64.173 -    DPRINTF("Increased domain reservation by %lx KB\n", PFN_TO_KB(max_pfn));
  64.174 +        p2m[pfn] = INVALID_P2M_ENTRY;
  64.175  
  64.176      if(!(mmu = xc_init_mmu_updates(xc_handle, dom))) {
  64.177          ERROR("Could not initialise for MMU updates");
  64.178 @@ -298,7 +333,7 @@ int xc_linux_restore(int xc_handle, int 
  64.179      n = 0;
  64.180      while (1) {
  64.181  
  64.182 -        int j;
  64.183 +        int j, nr_mfns = 0; 
  64.184  
  64.185          this_pc = (n * 100) / max_pfn;
  64.186          if ( (this_pc - prev_pc) >= 5 )
  64.187 @@ -333,6 +368,33 @@ int xc_linux_restore(int xc_handle, int 
  64.188              goto out;
  64.189          }
  64.190  
  64.191 +        /* First pass for this batch: work out how much memory to alloc */
  64.192 +        nr_mfns = 0; 
  64.193 +        for ( i = 0; i < j; i++ )
  64.194 +        {
  64.195 +            unsigned long pfn, pagetype;
  64.196 +            pfn      = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
  64.197 +            pagetype = region_pfn_type[i] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
  64.198 +
  64.199 +            if ( (pagetype != XEN_DOMCTL_PFINFO_XTAB) && 
  64.200 +                 (p2m[pfn] == INVALID_P2M_ENTRY) )
  64.201 +            {
  64.202 +                /* Have a live PFN which hasn't had an MFN allocated */
  64.203 +                p2m_batch[nr_mfns++] = pfn; 
  64.204 +            }
  64.205 +        } 
  64.206 +
  64.207 +
  64.208 +        /* Now allocate a bunch of mfns for this batch */
  64.209 +        if (nr_mfns && xc_domain_memory_populate_physmap(
  64.210 +                xc_handle, dom, nr_mfns, 0, 0, p2m_batch) != 0) { 
  64.211 +            ERROR("Failed to allocate memory for batch.!\n"); 
  64.212 +            errno = ENOMEM;
  64.213 +            goto out;
  64.214 +        }
  64.215 +
  64.216 +        /* Second pass for this batch: update p2m[] and region_mfn[] */
  64.217 +        nr_mfns = 0; 
  64.218          for ( i = 0; i < j; i++ )
  64.219          {
  64.220              unsigned long pfn, pagetype;
  64.221 @@ -340,13 +402,23 @@ int xc_linux_restore(int xc_handle, int 
  64.222              pagetype = region_pfn_type[i] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
  64.223  
  64.224              if ( pagetype == XEN_DOMCTL_PFINFO_XTAB)
  64.225 -                region_mfn[i] = 0; /* we know map will fail, but don't care */
  64.226 -            else
  64.227 -                region_mfn[i] = p2m[pfn];
  64.228 -        }
  64.229 +                region_mfn[i] = ~0UL; /* map will fail but we don't care */
  64.230 +            else 
  64.231 +            {
  64.232 +                if (p2m[pfn] == INVALID_P2M_ENTRY) {
  64.233 +                    /* We just allocated a new mfn above; update p2m */
  64.234 +                    p2m[pfn] = p2m_batch[nr_mfns++]; 
  64.235 +                }
  64.236  
  64.237 +                /* setup region_mfn[] for batch map */
  64.238 +                region_mfn[i] = p2m[pfn]; 
  64.239 +            }
  64.240 +        } 
  64.241 +
  64.242 +        /* Map relevant mfns */
  64.243          region_base = xc_map_foreign_batch(
  64.244              xc_handle, dom, PROT_WRITE, region_mfn, j);
  64.245 +
  64.246          if ( region_base == NULL )
  64.247          {
  64.248              ERROR("map batch failed");
  64.249 @@ -401,7 +473,8 @@ int xc_linux_restore(int xc_handle, int 
  64.250                      pae_extended_cr3 ||
  64.251                      (pagetype != XEN_DOMCTL_PFINFO_L1TAB)) {
  64.252  
  64.253 -                    if (!uncanonicalize_pagetable(pagetype, page)) {
  64.254 +                    if (!uncanonicalize_pagetable(xc_handle, dom, 
  64.255 +                                                  pagetype, page)) {
  64.256                          /*
  64.257                          ** Failing to uncanonicalize a page table can be ok
  64.258                          ** under live migration since the pages type may have
  64.259 @@ -411,10 +484,8 @@ int xc_linux_restore(int xc_handle, int 
  64.260                                  pagetype >> 28, pfn, mfn);
  64.261                          nraces++;
  64.262                          continue;
  64.263 -                    }
  64.264 -
  64.265 +                    } 
  64.266                  }
  64.267 -
  64.268              }
  64.269              else if ( pagetype != XEN_DOMCTL_PFINFO_NOTAB )
  64.270              {
  64.271 @@ -486,7 +557,7 @@ int xc_linux_restore(int xc_handle, int 
  64.272          */
  64.273  
  64.274          int j, k;
  64.275 -
  64.276 +        
  64.277          /* First pass: find all L3TABs current in > 4G mfns and get new mfns */
  64.278          for ( i = 0; i < max_pfn; i++ )
  64.279          {
  64.280 @@ -555,7 +626,8 @@ int xc_linux_restore(int xc_handle, int 
  64.281                  }
  64.282  
  64.283                  for(k = 0; k < j; k++) {
  64.284 -                    if(!uncanonicalize_pagetable(XEN_DOMCTL_PFINFO_L1TAB,
  64.285 +                    if(!uncanonicalize_pagetable(xc_handle, dom, 
  64.286 +                                                 XEN_DOMCTL_PFINFO_L1TAB,
  64.287                                                   region_base + k*PAGE_SIZE)) {
  64.288                          ERROR("failed uncanonicalize pt!");
  64.289                          goto out;
  64.290 @@ -631,7 +703,7 @@ int xc_linux_restore(int xc_handle, int 
  64.291      {
  64.292          unsigned int count;
  64.293          unsigned long *pfntab;
  64.294 -        int rc;
  64.295 +        int nr_frees, rc;
  64.296  
  64.297          if (!read_exact(io_fd, &count, sizeof(count))) {
  64.298              ERROR("Error when reading pfn count");
  64.299 @@ -648,29 +720,30 @@ int xc_linux_restore(int xc_handle, int 
  64.300              goto out;
  64.301          }
  64.302  
  64.303 +        nr_frees = 0; 
  64.304          for (i = 0; i < count; i++) {
  64.305  
  64.306              unsigned long pfn = pfntab[i];
  64.307  
  64.308 -            if(pfn > max_pfn)
  64.309 -                /* shouldn't happen - continue optimistically */
  64.310 -                continue;
  64.311 -
  64.312 -            pfntab[i] = p2m[pfn];
  64.313 -            p2m[pfn]  = INVALID_P2M_ENTRY; // not in pseudo-physical map
  64.314 +            if(p2m[pfn] != INVALID_P2M_ENTRY) {
  64.315 +                /* pfn is not in physmap now, but was at some point during 
  64.316 +                   the save/migration process - need to free it */
  64.317 +                pfntab[nr_frees++] = p2m[pfn];
  64.318 +                p2m[pfn]  = INVALID_P2M_ENTRY; // not in pseudo-physical map
  64.319 +            }
  64.320          }
  64.321  
  64.322 -        if (count > 0) {
  64.323 +        if (nr_frees > 0) {
  64.324  
  64.325              struct xen_memory_reservation reservation = {
  64.326 -                .nr_extents   = count,
  64.327 +                .nr_extents   = nr_frees,
  64.328                  .extent_order = 0,
  64.329                  .domid        = dom
  64.330              };
  64.331              set_xen_guest_handle(reservation.extent_start, pfntab);
  64.332  
  64.333              if ((rc = xc_memory_op(xc_handle, XENMEM_decrease_reservation,
  64.334 -                                   &reservation)) != count) {
  64.335 +                                   &reservation)) != nr_frees) {
  64.336                  ERROR("Could not decrease reservation : %d", rc);
  64.337                  goto out;
  64.338              } else
  64.339 @@ -791,6 +864,6 @@ int xc_linux_restore(int xc_handle, int 
  64.340      free(pfn_type);
  64.341  
  64.342      DPRINTF("Restore exit with rc=%d\n", rc);
  64.343 -
  64.344 +    
  64.345      return rc;
  64.346  }
    65.1 --- a/tools/libxc/xc_linux_save.c	Thu Jan 18 09:54:33 2007 +0000
    65.2 +++ b/tools/libxc/xc_linux_save.c	Thu Jan 18 15:18:07 2007 +0000
    65.3 @@ -660,13 +660,6 @@ int xc_linux_save(int xc_handle, int io_
    65.4          goto out;
    65.5      }
    65.6  
    65.7 -   /* cheesy sanity check */
    65.8 -    if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {
    65.9 -        ERROR("Invalid state record -- pfn count out of range: %lu",
   65.10 -            (info.max_memkb >> (PAGE_SHIFT - 10)));
   65.11 -        goto out;
   65.12 -     }
   65.13 -
   65.14      /* Map the shared info frame */
   65.15      if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   65.16                                              PROT_READ, shared_info_frame))) {
    66.1 --- a/tools/libxc/xc_load_elf.c	Thu Jan 18 09:54:33 2007 +0000
    66.2 +++ b/tools/libxc/xc_load_elf.c	Thu Jan 18 15:18:07 2007 +0000
    66.3 @@ -406,17 +406,19 @@ static int parseelfimage(const char *ima
    66.4      }
    66.5  
    66.6      /*
    66.7 -     * A "bimodal" ELF note indicates the kernel will adjust to the
    66.8 -     * current paging mode, including handling extended cr3 syntax.
    66.9 -     * If we have ELF notes then PAE=yes implies that we must support
   66.10 -     * the extended cr3 syntax. Otherwise we need to find the
   66.11 -     * [extended-cr3] syntax in the __xen_guest string.
   66.12 +     * A "bimodal" ELF note indicates the kernel will adjust to the current
   66.13 +     * paging mode, including handling extended cr3 syntax.  If we have ELF
   66.14 +     * notes then PAE=yes implies that we must support the extended cr3 syntax.
   66.15 +     * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
   66.16 +     * string. We use strstr() to look for "bimodal" to allow guests to use
   66.17 +     * "yes,bimodal" or "no,bimodal" for compatibility reasons.
   66.18       */
   66.19 +
   66.20      dsi->pae_kernel = PAEKERN_no;
   66.21      if ( dsi->__elfnote_section )
   66.22      {
   66.23          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   66.24 -        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
   66.25 +        if ( p != NULL && strstr(p, "bimodal") != NULL )
   66.26              dsi->pae_kernel = PAEKERN_bimodal;
   66.27          else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   66.28              dsi->pae_kernel = PAEKERN_extended_cr3;
    67.1 --- a/tools/libxc/xc_ptrace.c	Thu Jan 18 09:54:33 2007 +0000
    67.2 +++ b/tools/libxc/xc_ptrace.c	Thu Jan 18 15:18:07 2007 +0000
    67.3 @@ -166,14 +166,11 @@ static unsigned long           *page_arr
    67.4   * tables.
    67.5   *
    67.6   */
    67.7 -static unsigned long
    67.8 -to_ma(int cpu,
    67.9 -      unsigned long in_addr)
   67.10 +static uint64_t
   67.11 +to_ma(int cpu, uint64_t maddr)
   67.12  {
   67.13 -    unsigned long maddr = in_addr;
   67.14 -
   67.15      if ( current_is_hvm && paging_enabled(&ctxt[cpu]) )
   67.16 -        maddr = page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
   67.17 +        maddr = (uint64_t)page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
   67.18      return maddr;
   67.19  }
   67.20  
   67.21 @@ -225,7 +222,8 @@ map_domain_va_pae(
   67.22      void *guest_va,
   67.23      int perm)
   67.24  {
   67.25 -    unsigned long l3e, l2e, l1e, l2p, l1p, p, va = (unsigned long)guest_va;
   67.26 +    uint64_t l3e, l2e, l1e, l2p, l1p, p;
   67.27 +    unsigned long va = (unsigned long)guest_va;
   67.28      uint64_t *l3, *l2, *l1;
   67.29      static void *v[MAX_VIRT_CPUS];
   67.30  
   67.31 @@ -380,12 +378,12 @@ map_domain_va(
   67.32  
   67.33      if (!paging_enabled(&ctxt[cpu])) {
   67.34          static void * v;
   67.35 -        unsigned long page;
   67.36 +        uint64_t page;
   67.37  
   67.38          if ( v != NULL )
   67.39              munmap(v, PAGE_SIZE);
   67.40  
   67.41 -        page = to_ma(cpu, page_array[va >> PAGE_SHIFT]);
   67.42 +        page = to_ma(cpu, va);
   67.43  
   67.44          v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
   67.45                  perm, page >> PAGE_SHIFT);
    68.1 --- a/tools/pygrub/src/pygrub	Thu Jan 18 09:54:33 2007 +0000
    68.2 +++ b/tools/pygrub/src/pygrub	Thu Jan 18 15:18:07 2007 +0000
    68.3 @@ -13,7 +13,7 @@
    68.4  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    68.5  #
    68.6  
    68.7 -import os, sys, string, struct, tempfile
    68.8 +import os, sys, string, struct, tempfile, re
    68.9  import copy
   68.10  import logging
   68.11  
   68.12 @@ -48,8 +48,7 @@ def is_disk_image(file):
   68.13          return True
   68.14      return False
   68.15  
   68.16 -SECTOR_SIZE=512
   68.17 -def get_active_offset(file):
   68.18 +def get_active_partition(file):
   68.19      """Find the offset for the start of the first active partition "
   68.20      "in the disk image file."""
   68.21  
   68.22 @@ -58,13 +57,56 @@ def get_active_offset(file):
   68.23      for poff in (446, 462, 478, 494): # partition offsets
   68.24          # active partition has 0x80 as the first byte
   68.25          if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
   68.26 -            return struct.unpack("<L",
   68.27 -                                 buf[poff+8:poff+12])[0] * SECTOR_SIZE
   68.28 +            return buf[poff:poff+16]
   68.29  
   68.30      # if there's not a partition marked as active, fall back to
   68.31      # the first partition
   68.32 -    P1 = 446
   68.33 -    return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
   68.34 +    return buf[446:446+16]
   68.35 +
   68.36 +SECTOR_SIZE=512
   68.37 +DK_LABEL_LOC=1
   68.38 +DKL_MAGIC=0xdabe
   68.39 +V_ROOT=0x2
   68.40 +
   68.41 +def get_solaris_slice(file, offset):
   68.42 +    """Find the root slice in a Solaris VTOC."""
   68.43 +
   68.44 +    fd = os.open(file, os.O_RDONLY)
   68.45 +    os.lseek(fd, offset + (DK_LABEL_LOC * SECTOR_SIZE), 0)
   68.46 +    buf = os.read(fd, 512)
   68.47 +    if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
   68.48 +        raise RuntimeError, "Invalid disklabel magic"
   68.49 +
   68.50 +    nslices = struct.unpack("<H", buf[30:32])[0]
   68.51 +
   68.52 +    for i in range(nslices):
   68.53 +        sliceoff = 72 + 12 * i
   68.54 +        slicetag = struct.unpack("<H", buf[sliceoff:sliceoff+2])[0]
   68.55 +        slicesect = struct.unpack("<L", buf[sliceoff+4:sliceoff+8])[0]
   68.56 +        if slicetag == V_ROOT:
   68.57 +            return slicesect * SECTOR_SIZE
   68.58 +
   68.59 +    raise RuntimeError, "No root slice found"      
   68.60 +
   68.61 +FDISK_PART_SOLARIS=0xbf
   68.62 +FDISK_PART_SOLARIS_OLD=0x82
   68.63 +
   68.64 +def get_fs_offset(file):
   68.65 +    if not is_disk_image(file):
   68.66 +        return 0
   68.67 +
   68.68 +    partbuf = get_active_partition(file)
   68.69 +    if len(partbuf) == 0:
   68.70 +        raise RuntimeError, "Unable to find active partition on disk"
   68.71 +
   68.72 +    offset = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
   68.73 +
   68.74 +    type = struct.unpack("<B", partbuf[4:5])[0]
   68.75 +
   68.76 +    if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
   68.77 +        offset += get_solaris_slice(file, offset)
   68.78 +
   68.79 +    return offset
   68.80  
   68.81  class GrubLineEditor(curses.textpad.Textbox):
   68.82      def __init__(self, screen, startx, starty, line = ""):
   68.83 @@ -143,12 +185,12 @@ class GrubLineEditor(curses.textpad.Text
   68.84          
   68.85  
   68.86  class Grub:
   68.87 -    def __init__(self, file, isconfig = False):
   68.88 +    def __init__(self, file, fs = None):
   68.89          self.screen = None
   68.90          self.entry_win = None
   68.91          self.text_win = None
   68.92          if file:
   68.93 -            self.read_config(file, isconfig)
   68.94 +            self.read_config(file, fs)
   68.95  
   68.96      def draw_main_windows(self):
   68.97          if self.screen is None: #only init stuff once
   68.98 @@ -295,8 +337,8 @@ class Grub:
   68.99              # else, we cancelled and should just go back
  68.100              break
  68.101  
  68.102 -    def read_config(self, fn, isConfig = False):
  68.103 -        """Read the given file to parse the config.  If isconfig, then
  68.104 +    def read_config(self, fn, fs = None):
  68.105 +        """Read the given file to parse the config.  If fs = None, then
  68.106          we're being given a raw config file rather than a disk image."""
  68.107          
  68.108          if not os.access(fn, os.R_OK):
  68.109 @@ -304,38 +346,25 @@ class Grub:
  68.110  
  68.111          self.cf = grub.GrubConf.GrubConfigFile()
  68.112  
  68.113 -        if isConfig:
  68.114 +        if not fs:
  68.115              # set the config file and parse it
  68.116              self.cf.filename = fn
  68.117              self.cf.parse()
  68.118              return
  68.119  
  68.120 -        offset = 0
  68.121 -        if is_disk_image(fn):
  68.122 -            offset = get_active_offset(fn)
  68.123 -            if offset == -1:
  68.124 -                raise RuntimeError, "Unable to find active partition on disk"
  68.125 -
  68.126 -        # open the image and read the grub config
  68.127 -        fs = fsimage.open(fn, offset)
  68.128 -
  68.129 -        if fs is not None:
  68.130 -            grubfile = None
  68.131 -            for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
  68.132 -                      "/grub/menu.lst", "/grub/grub.conf"):
  68.133 -                if fs.file_exists(f):
  68.134 -                    grubfile = f
  68.135 -                    break
  68.136 -            if grubfile is None:
  68.137 -                raise RuntimeError, "we couldn't find grub config file in the image provided."
  68.138 -            f = fs.open_file(grubfile)
  68.139 -            buf = f.read()
  68.140 -            del f
  68.141 -            del fs
  68.142 -            # then parse the grub config
  68.143 -            self.cf.parse(buf)
  68.144 -        else:
  68.145 -            raise RuntimeError, "Unable to read filesystem" 
  68.146 +        grubfile = None
  68.147 +        for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
  68.148 +                  "/grub/menu.lst", "/grub/grub.conf"):
  68.149 +            if fs.file_exists(f):
  68.150 +                grubfile = f
  68.151 +                break
  68.152 +        if grubfile is None:
  68.153 +            raise RuntimeError, "we couldn't find grub config file in the image provided."
  68.154 +        f = fs.open_file(grubfile)
  68.155 +        buf = f.read()
  68.156 +        del f
  68.157 +        # then parse the grub config
  68.158 +        self.cf.parse(buf)
  68.159  
  68.160      def run(self):
  68.161          timeout = int(self.cf.timeout)
  68.162 @@ -376,6 +405,9 @@ class Grub:
  68.163              c = self.screen.getch()
  68.164              if mytime != -1:
  68.165                  mytime += 1
  68.166 +                if mytime >= int(timeout):
  68.167 +                    self.isdone = True
  68.168 +                    break
  68.169  
  68.170              # handle keypresses
  68.171              if c == ord('c'):
  68.172 @@ -431,19 +463,93 @@ def get_entry_idx(cf, entry):
  68.173  
  68.174      return None
  68.175  
  68.176 +def run_grub(file, entry, fs):
  68.177 +    global g
  68.178 +    global sel
  68.179 +
  68.180 +    def run_main(scr, *args):
  68.181 +        global sel
  68.182 +        global g
  68.183 +        sel = g.run()
  68.184 +
  68.185 +    g = Grub(file, fs)
  68.186 +    if interactive:
  68.187 +        curses.wrapper(run_main)
  68.188 +    else:
  68.189 +        sel = g.cf.default
  68.190 +
  68.191 +    # set the entry to boot as requested
  68.192 +    if entry is not None:
  68.193 +        idx = get_entry_idx(g.cf, entry)
  68.194 +        if idx is not None and idx > 0 and idx < len(g.cf.images):
  68.195 +           sel = idx
  68.196 +
  68.197 +    if sel == -1:
  68.198 +        print "No kernel image selected!"
  68.199 +        sys.exit(1)
  68.200 +
  68.201 +    img = g.cf.images[sel]
  68.202 +
  68.203 +    grubcfg = { "kernel": None, "ramdisk": None, "args": None }
  68.204 +
  68.205 +    grubcfg["kernel"] = img.kernel[1]
  68.206 +    if img.initrd:
  68.207 +        grubcfg["ramdisk"] = img.initrd[1]
  68.208 +    if img.args:
  68.209 +        grubcfg["args"] = img.args
  68.210 +
  68.211 +    return grubcfg
  68.212 +
  68.213 +# If nothing has been specified, look for a Solaris domU. If found, perform the
  68.214 +# necessary tweaks.
  68.215 +def sniff_solaris(fs, cfg):
  68.216 +    if not fs.file_exists("/platform/i86xen/kernel/unix"):
  68.217 +        return cfg
  68.218 +    
  68.219 +    # darned python
  68.220 +    longmode = (sys.maxint != 2147483647L)
  68.221 +    if not longmode:
  68.222 +        longmode = os.uname()[4] == "x86_64"
  68.223 +    if not longmode:
  68.224 +        if (os.access("/usr/bin/isainfo", os.R_OK) and
  68.225 +            os.popen("/usr/bin/isainfo -b").read() == "64\n"):
  68.226 +            longmode = True
  68.227 +
  68.228 +    if not cfg["kernel"]:
  68.229 +        cfg["kernel"] = "/platform/i86xen/kernel/unix"
  68.230 +        cfg["ramdisk"] = "/platform/i86pc/boot_archive"
  68.231 +        if longmode:
  68.232 +            cfg["kernel"] = "/platform/i86xen/kernel/amd64/unix"
  68.233 +            cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive"
  68.234 +
  68.235 +    # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k',
  68.236 +    # and we need to maintain Xen properties (root= and ip=) and the kernel
  68.237 +    # before any user args.
  68.238 +    
  68.239 +    xenargs = ""
  68.240 +    userargs = ""
  68.241 +    
  68.242 +    if not cfg["args"]:
  68.243 +        cfg["args"] = cfg["kernel"]
  68.244 +    else:
  68.245 +        for arg in cfg["args"].split():
  68.246 +            if re.match("^root=", arg) or re.match("^ip=", arg):
  68.247 +                xenargs += arg + " "
  68.248 +            elif arg != cfg["kernel"]:
  68.249 +                userargs += arg + " "
  68.250 +        cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs
  68.251 +
  68.252 +    return cfg
  68.253 + 
  68.254  if __name__ == "__main__":
  68.255      sel = None
  68.256      
  68.257 -    def run_main(scr, *args):
  68.258 -        global sel
  68.259 -        sel = g.run()
  68.260 -
  68.261      def usage():
  68.262 -        print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] <image>" %(sys.argv[0],)
  68.263 +        print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] <image>" %(sys.argv[0],)
  68.264  
  68.265      try:
  68.266          opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::',
  68.267 -                                   ["quiet", "help", "output=", "entry=",
  68.268 +                                   ["quiet", "help", "output=", "entry=", "kernel=", "ramdisk=", "args=",
  68.269                                      "isconfig"])
  68.270      except getopt.GetoptError:
  68.271          usage()
  68.272 @@ -458,6 +564,14 @@ if __name__ == "__main__":
  68.273      entry = None
  68.274      interactive = True
  68.275      isconfig = False
  68.276 +
  68.277 +    # what was passed in
  68.278 +    incfg = { "kernel": None, "ramdisk": None, "args": None }
  68.279 +    # what grub or sniffing chose
  68.280 +    chosencfg = { "kernel": None, "ramdisk": None, "args": None }
  68.281 +    # what to boot
  68.282 +    bootcfg = { "kernel": None, "ramdisk": None, "args": None }
  68.283 +
  68.284      for o, a in opts:
  68.285          if o in ("-q", "--quiet"):
  68.286              interactive = False
  68.287 @@ -466,6 +580,12 @@ if __name__ == "__main__":
  68.288              sys.exit()
  68.289          elif o in ("--output",):
  68.290              output = a
  68.291 +        elif o in ("--kernel",):
  68.292 +            incfg["kernel"] = a
  68.293 +        elif o in ("--ramdisk",):
  68.294 +            incfg["ramdisk"] = a
  68.295 +        elif o in ("--args",):
  68.296 +            incfg["args"] = a
  68.297          elif o in ("--entry",):
  68.298              entry = a
  68.299              # specifying the entry to boot implies non-interactive
  68.300 @@ -478,58 +598,42 @@ if __name__ == "__main__":
  68.301      else:
  68.302          fd = os.open(output, os.O_WRONLY)
  68.303  
  68.304 -    g = Grub(file, isconfig)
  68.305 -    if interactive:
  68.306 -        curses.wrapper(run_main)
  68.307 -    else:
  68.308 -        sel = g.cf.default
  68.309 -
  68.310 -    # set the entry to boot as requested
  68.311 -    if entry is not None:
  68.312 -        idx = get_entry_idx(g.cf, entry)
  68.313 -        if idx is not None and idx > 0 and idx < len(g.cf.images):
  68.314 -            sel = idx
  68.315 -
  68.316 -    if sel == -1:
  68.317 -        print "No kernel image selected!"
  68.318 -        sys.exit(1)
  68.319 -
  68.320 -    img = g.cf.images[sel]
  68.321 -    print "Going to boot %s" %(img.title)
  68.322 -    print "  kernel: %s" %(img.kernel[1],)
  68.323 -    if img.initrd:
  68.324 -        print "  initrd: %s" %(img.initrd[1],)
  68.325 -
  68.326 +    # debug
  68.327      if isconfig:
  68.328 -        print "  args: %s" %(img.args,)
  68.329 +        chosencfg = run_grub(file, entry)
  68.330 +        print "  kernel: %s" % chosencfg["kernel"]
  68.331 +        if img.initrd:
  68.332 +            print "  initrd: %s" % chosencfg["ramdisk"]
  68.333 +        print "  args: %s" % chosencfg["args"]
  68.334          sys.exit(0)
  68.335 -        
  68.336 -    offset = 0
  68.337 -    if is_disk_image(file):
  68.338 -        offset = get_active_offset(file)
  68.339 -        if offset == -1:
  68.340 -            raise RuntimeError, "Unable to find active partition on disk"
  68.341 +
  68.342 +    fs = fsimage.open(file, get_fs_offset(file))
  68.343  
  68.344 -    # read the kernel and initrd onto the hostfs
  68.345 -    fs = fsimage.open(file, offset)
  68.346 +    chosencfg = sniff_solaris(fs, incfg)
  68.347 +
  68.348 +    if not chosencfg["kernel"]:
  68.349 +        chosencfg = run_grub(file, entry, fs)
  68.350  
  68.351 -    kernel = fs.open_file(img.kernel[1],).read()
  68.352 -    (tfd, fn) = tempfile.mkstemp(prefix="boot_kernel.",
  68.353 +    data = fs.open_file(chosencfg["kernel"]).read()
  68.354 +    (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.",
  68.355          dir="/var/run/xend/boot")
  68.356 -    os.write(tfd, kernel)
  68.357 +    os.write(tfd, data)
  68.358      os.close(tfd)
  68.359 -    sxp = "linux (kernel %s)" %(fn,)
  68.360  
  68.361 -    if img.initrd:
  68.362 -        initrd = fs.open_file(img.initrd[1],).read()
  68.363 -        (tfd, fn) = tempfile.mkstemp(prefix="boot_ramdisk.",
  68.364 +    if chosencfg["ramdisk"]:
  68.365 +        data = fs.open_file(chosencfg["ramdisk"],).read()
  68.366 +        (tfd, bootcfg["ramdisk"]) = tempfile.mkstemp(prefix="boot_ramdisk.",
  68.367              dir="/var/run/xend/boot")
  68.368 -        os.write(tfd, initrd)
  68.369 +        os.write(tfd, data)
  68.370          os.close(tfd)
  68.371 -        sxp += "(ramdisk %s)" %(fn,)
  68.372      else:
  68.373          initrd = None
  68.374 -    sxp += "(args '%s')" %(img.args,)
  68.375 +
  68.376 +    sxp = "linux (kernel %s)" % bootcfg["kernel"]
  68.377 +    if bootcfg["ramdisk"]:
  68.378 +        sxp += "(ramdisk %s)" % bootcfg["ramdisk"]
  68.379 +    if chosencfg["args"]:
  68.380 +        sxp += "(args \"%s\")" % chosencfg["args"]
  68.381  
  68.382      sys.stdout.flush()
  68.383      os.write(fd, sxp)
    69.1 --- a/tools/python/xen/xend/XendBootloader.py	Thu Jan 18 09:54:33 2007 +0000
    69.2 +++ b/tools/python/xen/xend/XendBootloader.py	Thu Jan 18 15:18:07 2007 +0000
    69.3 @@ -53,6 +53,12 @@ def bootloader(blexec, disk, quiet = Fal
    69.4      child = os.fork()
    69.5      if (not child):
    69.6          args = [ blexec ]
    69.7 +        if kernel:
    69.8 +            args.append("--kernel=%s" % kernel)
    69.9 +        if ramdisk:
   69.10 +            args.append("--ramdisk=%s" % ramdisk)
   69.11 +        if kernel_args:
   69.12 +            args.append("--args=%s" % kernel_args)
   69.13          if quiet:
   69.14              args.append("-q")
   69.15          args.append("--output=%s" % fifo)
    70.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Thu Jan 18 09:54:33 2007 +0000
    70.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Thu Jan 18 15:18:07 2007 +0000
    70.3 @@ -147,18 +147,20 @@ def restore(xd, fd, dominfo = None, paus
    70.4      assert store_port
    70.5      assert console_port
    70.6  
    70.7 +    nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 
    70.8 +
    70.9      try:
   70.10          l = read_exact(fd, sizeof_unsigned_long,
   70.11                         "not a valid guest state file: pfn count read")
   70.12 -        nr_pfns = unpack("L", l)[0]    # native sizeof long
   70.13 -        if nr_pfns > 16*1024*1024:     # XXX 
   70.14 +        max_pfn = unpack("L", l)[0]    # native sizeof long
   70.15 +        if max_pfn > 16*1024*1024:     # XXX 
   70.16              raise XendError(
   70.17                  "not a valid guest state file: pfn count out of range")
   70.18  
   70.19          balloon.free(xc.pages_to_kib(nr_pfns))
   70.20  
   70.21          cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
   70.22 -                        fd, dominfo.getDomid(), nr_pfns,
   70.23 +                        fd, dominfo.getDomid(), max_pfn,
   70.24                          store_port, console_port])
   70.25          log.debug("[xc_restore]: %s", string.join(cmd))
   70.26  
    71.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Jan 18 09:54:33 2007 +0000
    71.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Jan 18 15:18:07 2007 +0000
    71.3 @@ -126,6 +126,7 @@ XENAPI_CFG_TYPES = {
    71.4      'memory_dynamic_min': int,
    71.5      'memory_dynamic_max': int,
    71.6      'memory_actual': int,
    71.7 +    'cpus': list,
    71.8      'vcpus_policy': str,
    71.9      'vcpus_params': str,
   71.10      'vcpus_number': int,
   71.11 @@ -1020,10 +1021,11 @@ class XendConfig(dict):
   71.12          @return: Returns True if succesfully found and updated a device conf
   71.13          """
   71.14          if dev_uuid in self['devices']:
   71.15 -            config = sxp.child0(cfg_sxp)
   71.16 -            dev_type = sxp.name(config)
   71.17 -            dev_info = {}
   71.18 -
   71.19 +            if sxp.child0(cfg_sxp) == 'device':            
   71.20 +                config = sxp.child0(cfg_sxp)
   71.21 +            else:
   71.22 +                config = cfg_sxp
   71.23 +                
   71.24              for opt_val in config[1:]:
   71.25                  try:
   71.26                      opt, val = opt_val
    72.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Jan 18 09:54:33 2007 +0000
    72.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Jan 18 15:18:07 2007 +0000
    72.3 @@ -377,7 +377,7 @@ class XendDomain:
    72.4              dom0.setVCpuCount(target)
    72.5  
    72.6  
    72.7 -    def _refresh(self):
    72.8 +    def _refresh(self, refresh_shutdown = True):
    72.9          """Refresh the domain list. Needs to be called when
   72.10          either xenstore has changed or when a method requires
   72.11          up to date information (like uptime, cputime stats).
   72.12 @@ -393,7 +393,7 @@ class XendDomain:
   72.13          for dom in running:
   72.14              domid = dom['domid']
   72.15              if domid in self.domains:
   72.16 -                self.domains[domid].update(dom)
   72.17 +                self.domains[domid].update(dom, refresh_shutdown)
   72.18              elif domid not in self.domains and dom['dying'] != 1:
   72.19                  try:
   72.20                      new_dom = XendDomainInfo.recreate(dom, False)
   72.21 @@ -495,7 +495,7 @@ class XendDomain:
   72.22          """
   72.23          self.domains_lock.acquire()
   72.24          try:
   72.25 -            self._refresh()
   72.26 +            self._refresh(refresh_shutdown = False)
   72.27              dom = self.domain_lookup_nr(domid)
   72.28              if not dom:
   72.29                  raise XendError("No domain named '%s'." % str(domid))
   72.30 @@ -731,7 +731,7 @@ class XendDomain:
   72.31          
   72.32          self.domains_lock.acquire()
   72.33          try:
   72.34 -            self._refresh()
   72.35 +            self._refresh(refresh_shutdown = False)
   72.36              
   72.37              # active domains
   72.38              active_domains = self.domains.values()
    73.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Jan 18 09:54:33 2007 +0000
    73.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Jan 18 15:18:07 2007 +0000
    73.3 @@ -37,7 +37,7 @@ from xen.util import asserts
    73.4  from xen.util.blkif import blkdev_uname_to_file
    73.5  from xen.util import security
    73.6  
    73.7 -from xen.xend import balloon, sxp, uuid, image, arch
    73.8 +from xen.xend import balloon, sxp, uuid, image, arch, osdep
    73.9  from xen.xend import XendRoot, XendNode, XendConfig
   73.10  
   73.11  from xen.xend.XendConfig import scrub_password
   73.12 @@ -496,7 +496,7 @@ class XendDomainInfo:
   73.13          self._waitForDevice(dev_type, devid)
   73.14          return self.getDeviceController(dev_type).sxpr(devid)
   73.15  
   73.16 -    def device_configure(self, dev_config, devid = None):
   73.17 +    def device_configure(self, dev_sxp, devid = None):
   73.18          """Configure an existing device.
   73.19          
   73.20          @param dev_config: device configuration
   73.21 @@ -506,19 +506,24 @@ class XendDomainInfo:
   73.22          @return: Returns True if successfully updated device
   73.23          @rtype: boolean
   73.24          """
   73.25 -        deviceClass = sxp.name(dev_config)
   73.26 -        
   73.27 -        # look up uuid of the device
   73.28 -        dev_control =  self.getDeviceController(deviceClass)
   73.29 -        dev_sxpr = dev_control.sxpr(devid)
   73.30 -        dev_uuid = sxp.child_value(dev_sxpr, 'uuid')
   73.31 -        if not dev_uuid:
   73.32 -            return False
   73.33  
   73.34 -        self.info.device_update(dev_uuid, dev_config)
   73.35 -        dev_config_dict = self.info['devices'].get(dev_uuid)
   73.36 -        if dev_config_dict:
   73.37 -            dev_control.reconfigureDevice(devid, dev_config_dict[1])
   73.38 +        # convert device sxp to a dict
   73.39 +        dev_class = sxp.name(dev_sxp)
   73.40 +        dev_config = {}
   73.41 +        for opt_val in dev_sxp[1:]:
   73.42 +            try:
   73.43 +                dev_config[opt_val[0]] = opt_val[1]
   73.44 +            except IndexError:
   73.45 +                pass
   73.46 +
   73.47 +        # use DevController.reconfigureDevice to change device config
   73.48 +        dev_control = self.getDeviceController(dev_class)
   73.49 +        dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
   73.50 +
   73.51 +        # update XendConfig with new device info
   73.52 +        if dev_uuid:
   73.53 +            self.info.device_update(dev_uuid, dev_sxp)
   73.54 +            
   73.55          return True
   73.56  
   73.57      def waitForDevices(self):
   73.58 @@ -1575,7 +1580,7 @@ class XendDomainInfo:
   73.59          else:
   73.60              # Boot using bootloader
   73.61              if not blexec or blexec == 'pygrub':
   73.62 -                blexec = '/usr/bin/pygrub'
   73.63 +                blexec = osdep.pygrub_path
   73.64  
   73.65              blcfg = None
   73.66              for (devtype, devinfo) in self.info.all_devices_sxpr():
    74.1 --- a/tools/python/xen/xend/XendNode.py	Thu Jan 18 09:54:33 2007 +0000
    74.2 +++ b/tools/python/xen/xend/XendNode.py	Thu Jan 18 15:18:07 2007 +0000
    74.3 @@ -365,14 +365,24 @@ class XendNode:
    74.4  
    74.5          return [[k, info[k]] for k in ITEM_ORDER]
    74.6  
    74.7 +    def xenschedinfo(self):
    74.8 +        sched_id = self.xc.sched_id_get()
    74.9 +        if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
   74.10 +            return 'sedf'
   74.11 +        elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT:
   74.12 +            return 'credit'
   74.13 +        else:
   74.14 +            return 'unknown'
   74.15  
   74.16      def xeninfo(self):
   74.17          info = self.xc.xeninfo()
   74.18 +        info['xen_scheduler'] = self.xenschedinfo()
   74.19  
   74.20          ITEM_ORDER = ['xen_major',
   74.21                        'xen_minor',
   74.22                        'xen_extra',
   74.23                        'xen_caps',
   74.24 +                      'xen_scheduler',
   74.25                        'xen_pagesize',
   74.26                        'platform_params',
   74.27                        'xen_changeset',
    75.1 --- a/tools/python/xen/xend/osdep.py	Thu Jan 18 09:54:33 2007 +0000
    75.2 +++ b/tools/python/xen/xend/osdep.py	Thu Jan 18 15:18:07 2007 +0000
    75.3 @@ -29,8 +29,13 @@ import os
    75.4      "SunOS": False,
    75.5  }
    75.6  
    75.7 +_pygrub_path = {
    75.8 +    "SunOS": "/usr/lib/xen/bin/pygrub"
    75.9 +}
   75.10 +
   75.11  def _get(var, default=None):
   75.12      return var.get(os.uname()[0], default)
   75.13  
   75.14  scripts_dir = _get(_scripts_dir, "/etc/xen/scripts")
   75.15  xend_autorestart = _get(_xend_autorestart)
   75.16 +pygrub_path = _get(_pygrub_path, "/usr/bin/pygrub")
    76.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Jan 18 09:54:33 2007 +0000
    76.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Jan 18 15:18:07 2007 +0000
    76.3 @@ -101,6 +101,7 @@ class BlkifController(DevController):
    76.4              self.writeBackend(devid,
    76.5                                'type', new_back['type'],
    76.6                                'params', new_back['params'])
    76.7 +            return new_back.get('uuid')
    76.8          else:
    76.9              raise VmError('Refusing to reconfigure device %s:%d to %s' %
   76.10                            (self.deviceClass, devid, config))
    77.1 --- a/tools/python/xen/xm/create.py	Thu Jan 18 09:54:33 2007 +0000
    77.2 +++ b/tools/python/xen/xm/create.py	Thu Jan 18 15:18:07 2007 +0000
    77.3 @@ -28,6 +28,7 @@ import xmlrpclib
    77.4  
    77.5  from xen.xend import sxp
    77.6  from xen.xend import PrettyPrint
    77.7 +from xen.xend import osdep
    77.8  import xen.xend.XendClient
    77.9  from xen.xend.XendBootloader import bootloader
   77.10  from xen.util import blkif
   77.11 @@ -291,7 +292,8 @@ gopts.var('vfb', val="type={vnc,sdl},vnc
   77.12            For type=vnc, connect an external vncviewer.  The server will listen
   77.13            on ADDR (default 127.0.0.1) on port N+5900.  N defaults to the
   77.14            domain id.  If vncunused=1, the server will try to find an arbitrary
   77.15 -          unused port above 5900.
   77.16 +          unused port above 5900.  vncpasswd overrides the XenD configured
   77.17 +          default password.
   77.18            For type=sdl, a viewer will be started automatically using the
   77.19            given DISPLAY and XAUTHORITY, which default to the current user's
   77.20            ones.""")
   77.21 @@ -718,8 +720,11 @@ def run_bootloader(vals, config_image):
   77.22               "--entry= directly.")
   77.23          vals.bootargs = "--entry=%s" %(vals.bootentry,)
   77.24  
   77.25 +    kernel = sxp.child_value(config_image, 'kernel')
   77.26 +    ramdisk = sxp.child_value(config_image, 'ramdisk')
   77.27 +    args = sxp.child_value(config_image, 'args')
   77.28      return bootloader(vals.bootloader, file, not vals.console_autoconnect,
   77.29 -                      vals.bootargs, config_image)
   77.30 +                      vals.bootargs, kernel, ramdisk, args)
   77.31  
   77.32  def make_config(vals):
   77.33      """Create the domain configuration.
   77.34 @@ -759,7 +764,14 @@ def make_config(vals):
   77.35  
   77.36      config_image = configure_image(vals)
   77.37      if vals.bootloader:
   77.38 -        config_image = run_bootloader(vals, config_image)
   77.39 +        if vals.bootloader == "pygrub":
   77.40 +            vals.bootloader = osdep.pygrub_path
   77.41 +
   77.42 +        # if a kernel is specified, we're using the bootloader
   77.43 +        # non-interactively, and need to let xend run it so we preserve the
   77.44 +        # real kernel choice.
   77.45 +        if not vals.kernel:
   77.46 +            config_image = run_bootloader(vals, config_image)
   77.47          config.append(['bootloader', vals.bootloader])
   77.48          if vals.bootargs:
   77.49              config.append(['bootloader_args', vals.bootargs])
   77.50 @@ -990,8 +1002,6 @@ def preprocess_vnc(vals):
   77.51              vals.extra = vnc + ' ' + vals.extra
   77.52      
   77.53  def preprocess(vals):
   77.54 -    if not vals.kernel and not vals.bootloader:
   77.55 -        err("No kernel specified")
   77.56      preprocess_disk(vals)
   77.57      preprocess_pci(vals)
   77.58      preprocess_ioports(vals)
    78.1 --- a/tools/tests/Makefile	Thu Jan 18 09:54:33 2007 +0000
    78.2 +++ b/tools/tests/Makefile	Thu Jan 18 15:18:07 2007 +0000
    78.3 @@ -7,12 +7,21 @@ TARGET := test_x86_emulator
    78.4  .PHONY: all
    78.5  all: $(TARGET)
    78.6  
    78.7 +.PHONY: blowfish.bin
    78.8 +blowfish.bin:
    78.9 +	make -f blowfish.mk all
   78.10 +
   78.11 +blowfish.h: blowfish.bin
   78.12 +	(echo "static unsigned int blowfish_code[] = {"; \
   78.13 +	od -v -t x $< | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$$/,/';\
   78.14 +	echo "};") >$@
   78.15 +
   78.16  $(TARGET): x86_emulate.o test_x86_emulator.o
   78.17  	$(HOSTCC) -o $@ $^
   78.18  
   78.19  .PHONY: clean
   78.20  clean:
   78.21 -	rm -rf $(TARGET) *.o *~ core
   78.22 +	rm -rf $(TARGET) *.o *~ core blowfish.h blowfish.bin
   78.23  
   78.24  .PHONY: install
   78.25  install:
   78.26 @@ -20,5 +29,5 @@ install:
   78.27  x86_emulate.o: $(XEN_ROOT)/xen/arch/x86/x86_emulate.c
   78.28  	$(HOSTCC) $(HOSTCFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
   78.29  
   78.30 -%.o: %.c
   78.31 +test_x86_emulator.o: test_x86_emulator.c blowfish.h
   78.32  	$(HOSTCC) $(HOSTCFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/tools/tests/blowfish.c	Thu Jan 18 15:18:07 2007 +0000
    79.3 @@ -0,0 +1,439 @@
    79.4 +/*
    79.5 +blowfish.c:  C implementation of the Blowfish algorithm.
    79.6 +
    79.7 +Copyright (C) 1997 by Paul Kocher
    79.8 +
    79.9 +This library is free software; you can redistribute it and/or
   79.10 +modify it under the terms of the GNU Lesser General Public
   79.11 +License as published by the Free Software Foundation; either
   79.12 +version 2.1 of the License, or (at your option) any later version.
   79.13 +This library is distributed in the hope that it will be useful,
   79.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   79.16 +Lesser General Public License for more details.
   79.17 +You should have received a copy of the GNU Lesser General Public
   79.18 +License along with this library; if not, write to the Free Software
   79.19 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   79.20 +*/
   79.21 +
   79.22 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
   79.23 +#define __attribute_used__ __attribute__((__used__))
   79.24 +#else
   79.25 +#define __attribute_used__ __attribute__((__unused__))
   79.26 +#endif
   79.27 +
   79.28 +static unsigned long long blowfish_test(unsigned long long input)
   79.29 +    __attribute_used__;
   79.30 +
   79.31 +asm (
   79.32 +    ".globl _start\n"
   79.33 +    "_start:\n"
   79.34 +    "push %edx; push %eax; "
   79.35 +    "call blowfish_test; "
   79.36 +    "addl $8,%esp; "
   79.37 +    "ret"
   79.38 +    );
   79.39 +
   79.40 +typedef struct {
   79.41 +  unsigned long P[16 + 2];
   79.42 +  unsigned long S[4][256];
   79.43 +} BLOWFISH_CTX;
   79.44 +
   79.45 +#define N               16
   79.46 +
   79.47 +static const unsigned long ORIG_P[16 + 2] = {
   79.48 +        0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
   79.49 +        0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
   79.50 +        0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
   79.51 +        0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
   79.52 +        0x9216D5D9L, 0x8979FB1BL
   79.53 +};
   79.54 +
   79.55 +static const unsigned long ORIG_S[4][256] = {
   79.56 +    {   0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
   79.57 +        0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
   79.58 +        0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
   79.59 +        0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
   79.60 +        0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
   79.61 +        0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
   79.62 +        0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
   79.63 +        0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
   79.64 +        0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
   79.65 +        0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
   79.66 +        0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
   79.67 +        0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
   79.68 +        0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
   79.69 +        0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
   79.70 +        0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
   79.71 +        0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
   79.72 +        0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
   79.73 +        0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
   79.74 +        0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
   79.75 +        0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
   79.76 +        0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
   79.77 +        0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
   79.78 +        0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
   79.79 +        0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
   79.80 +        0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
   79.81 +        0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
   79.82 +        0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
   79.83 +        0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
   79.84 +        0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
   79.85 +        0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
   79.86 +        0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
   79.87 +        0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
   79.88 +        0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
   79.89 +        0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
   79.90 +        0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
   79.91 +        0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
   79.92 +        0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
   79.93 +        0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
   79.94 +        0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
   79.95 +        0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
   79.96 +        0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
   79.97 +        0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
   79.98 +        0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
   79.99 +        0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
  79.100 +        0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
  79.101 +        0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
  79.102 +        0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
  79.103 +        0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
  79.104 +        0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
  79.105 +        0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
  79.106 +        0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
  79.107 +        0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
  79.108 +        0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
  79.109 +        0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
  79.110 +        0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
  79.111 +        0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
  79.112 +        0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
  79.113 +        0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
  79.114 +        0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
  79.115 +        0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
  79.116 +        0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
  79.117 +        0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
  79.118 +        0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
  79.119 +        0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL   },
  79.120 +    {   0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
  79.121 +        0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
  79.122 +        0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
  79.123 +        0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
  79.124 +        0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
  79.125 +        0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
  79.126 +        0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
  79.127 +        0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
  79.128 +        0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
  79.129 +        0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
  79.130 +        0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
  79.131 +        0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
  79.132 +        0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
  79.133 +        0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
  79.134 +        0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
  79.135 +        0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
  79.136 +        0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
  79.137 +        0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
  79.138 +        0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
  79.139 +        0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
  79.140 +        0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
  79.141 +        0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
  79.142 +        0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
  79.143 +        0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
  79.144 +        0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
  79.145 +        0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
  79.146 +        0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
  79.147 +        0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
  79.148 +        0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
  79.149 +        0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
  79.150 +        0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
  79.151 +        0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
  79.152 +        0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
  79.153 +        0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
  79.154 +        0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
  79.155 +        0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
  79.156 +        0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
  79.157 +        0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
  79.158 +        0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
  79.159 +        0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
  79.160 +        0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
  79.161 +        0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
  79.162 +        0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
  79.163 +        0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
  79.164 +        0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
  79.165 +        0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
  79.166 +        0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
  79.167 +        0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
  79.168 +        0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
  79.169 +        0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
  79.170 +        0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
  79.171 +        0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
  79.172 +        0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
  79.173 +        0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
  79.174 +        0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
  79.175 +        0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
  79.176 +        0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
  79.177 +        0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
  79.178 +        0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
  79.179 +        0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
  79.180 +        0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
  79.181 +        0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
  79.182 +        0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
  79.183 +        0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L   },
  79.184 +    {   0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
  79.185 +        0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
  79.186 +        0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
  79.187 +        0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
  79.188 +        0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
  79.189 +        0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
  79.190 +        0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
  79.191 +        0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
  79.192 +        0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
  79.193 +        0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
  79.194 +        0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
  79.195 +        0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
  79.196 +        0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
  79.197 +        0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
  79.198 +        0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
  79.199 +        0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
  79.200 +        0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
  79.201 +        0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
  79.202 +        0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
  79.203 +        0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
  79.204 +        0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
  79.205 +        0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
  79.206 +        0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
  79.207 +        0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
  79.208 +        0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
  79.209 +        0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
  79.210 +        0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
  79.211 +        0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
  79.212 +        0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
  79.213 +        0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
  79.214 +        0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
  79.215 +        0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
  79.216 +        0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
  79.217 +        0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
  79.218 +        0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
  79.219 +        0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
  79.220 +        0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
  79.221 +        0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
  79.222 +        0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
  79.223 +        0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
  79.224 +        0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
  79.225 +        0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
  79.226 +        0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
  79.227 +        0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
  79.228 +        0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
  79.229 +        0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
  79.230 +        0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
  79.231 +        0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
  79.232 +        0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
  79.233 +        0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
  79.234 +        0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
  79.235 +        0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
  79.236 +        0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
  79.237 +        0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
  79.238 +        0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
  79.239 +        0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
  79.240 +        0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
  79.241 +        0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
  79.242 +        0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
  79.243 +        0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
  79.244 +        0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
  79.245 +        0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
  79.246 +        0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
  79.247 +        0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L  },
  79.248 +    {   0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
  79.249 +        0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
  79.250 +        0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
  79.251 +        0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
  79.252 +        0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
  79.253 +        0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
  79.254 +        0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
  79.255 +        0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
  79.256 +        0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
  79.257 +        0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
  79.258 +        0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
  79.259 +        0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
  79.260 +        0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
  79.261 +        0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
  79.262 +        0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
  79.263 +        0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
  79.264 +        0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
  79.265 +        0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
  79.266 +        0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
  79.267 +        0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
  79.268 +        0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
  79.269 +        0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
  79.270 +        0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
  79.271 +        0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
  79.272 +        0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
  79.273 +        0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
  79.274 +        0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
  79.275 +        0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
  79.276 +        0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
  79.277 +        0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
  79.278 +        0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
  79.279 +        0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
  79.280 +        0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
  79.281 +        0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
  79.282 +        0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
  79.283 +        0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
  79.284 +        0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
  79.285 +        0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
  79.286 +        0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
  79.287 +        0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
  79.288 +        0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
  79.289 +        0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
  79.290 +        0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
  79.291 +        0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
  79.292 +        0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
  79.293 +        0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
  79.294 +        0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
  79.295 +        0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
  79.296 +        0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
  79.297 +        0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
  79.298 +        0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
  79.299 +        0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
  79.300 +        0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
  79.301 +        0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
  79.302 +        0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
  79.303 +        0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
  79.304 +        0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
  79.305 +        0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
  79.306 +        0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
  79.307 +        0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
  79.308 +        0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
  79.309 +        0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
  79.310 +        0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
  79.311 +        0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L  }
  79.312 +};
  79.313 +
  79.314 +
  79.315 +static unsigned long F(BLOWFISH_CTX *ctx, unsigned long x) {
  79.316 +   unsigned short a, b, c, d;
  79.317 +   unsigned long  y;
  79.318 +
  79.319 +   d = (unsigned short)(x & 0xFF);
  79.320 +   x >>= 8;
  79.321 +   c = (unsigned short)(x & 0xFF);
  79.322 +   x >>= 8;
  79.323 +   b = (unsigned short)(x & 0xFF);
  79.324 +   x >>= 8;
  79.325 +   a = (unsigned short)(x & 0xFF);
  79.326 +   y = ctx->S[0][a] + ctx->S[1][b];
  79.327 +   y = y ^ ctx->S[2][c];
  79.328 +   y = y + ctx->S[3][d];
  79.329 +
  79.330 +   return y;
  79.331 +}
  79.332 +
  79.333 +
  79.334 +static void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr){
  79.335 +  unsigned long  Xl;
  79.336 +  unsigned long  Xr;
  79.337 +  unsigned long  temp;
  79.338 +  short       i;
  79.339 +
  79.340 +  Xl = *xl;
  79.341 +  Xr = *xr;
  79.342 +
  79.343 +  for (i = 0; i < N; ++i) {
  79.344 +    Xl = Xl ^ ctx->P[i];
  79.345 +    Xr = F(ctx, Xl) ^ Xr;
  79.346 +
  79.347 +    temp = Xl;
  79.348 +    Xl = Xr;
  79.349 +    Xr = temp;
  79.350 +  }
  79.351 +
  79.352 +  temp = Xl;
  79.353 +  Xl = Xr;
  79.354 +  Xr = temp;
  79.355 +
  79.356 +  Xr = Xr ^ ctx->P[N];
  79.357 +  Xl = Xl ^ ctx->P[N + 1];
  79.358 +
  79.359 +  *xl = Xl;
  79.360 +  *xr = Xr;
  79.361 +}
  79.362 +
  79.363 +
  79.364 +static void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr){
  79.365 +  unsigned long  Xl;
  79.366 +  unsigned long  Xr;
  79.367 +  unsigned long  temp;
  79.368 +  short       i;
  79.369 +
  79.370 +  Xl = *xl;
  79.371 +  Xr = *xr;
  79.372 +
  79.373 +  for (i = N + 1; i > 1; --i) {
  79.374 +    Xl = Xl ^ ctx->P[i];
  79.375 +    Xr = F(ctx, Xl) ^ Xr;
  79.376 +
  79.377 +    /* Exchange Xl and Xr */
  79.378 +    temp = Xl;
  79.379 +    Xl = Xr;
  79.380 +    Xr = temp;
  79.381 +  }
  79.382 +
  79.383 +  /* Exchange Xl and Xr */
  79.384 +  temp = Xl;
  79.385 +  Xl = Xr;
  79.386 +  Xr = temp;
  79.387 +
  79.388 +  Xr = Xr ^ ctx->P[1];
  79.389 +  Xl = Xl ^ ctx->P[0];
  79.390 +
  79.391 +  *xl = Xl;
  79.392 +  *xr = Xr;
  79.393 +}
  79.394 +
  79.395 +static void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen) {
  79.396 +  int i, j, k;
  79.397 +  unsigned long data, datal, datar;
  79.398 +
  79.399 +  for (i = 0; i < 4; i++) {
  79.400 +    for (j = 0; j < 256; j++)
  79.401 +      ctx->S[i][j] = ORIG_S[i][j];
  79.402 +  }
  79.403 +
  79.404 +  j = 0;
  79.405 +  for (i = 0; i < N + 2; ++i) {
  79.406 +    data = 0x00000000;
  79.407 +    for (k = 0; k < 4; ++k) {
  79.408 +      data = (data << 8) | key[j];
  79.409 +      j = j + 1;
  79.410 +      if (j >= keyLen)
  79.411 +        j = 0;
  79.412 +    }
  79.413 +    ctx->P[i] = ORIG_P[i] ^ data;
  79.414 +  }
  79.415 +
  79.416 +  datal = 0x00000000;
  79.417 +  datar = 0x00000000;
  79.418 +
  79.419 +  for (i = 0; i < N + 2; i += 2) {
  79.420 +    Blowfish_Encrypt(ctx, &datal, &datar);
  79.421 +    ctx->P[i] = datal;
  79.422 +    ctx->P[i + 1] = datar;
  79.423 +  }
  79.424 +
  79.425 +  for (i = 0; i < 4; ++i) {
  79.426 +    for (j = 0; j < 256; j += 2) {
  79.427 +      Blowfish_Encrypt(ctx, &datal, &datar);
  79.428 +      ctx->S[i][j] = datal;
  79.429 +      ctx->S[i][j + 1] = datar;
  79.430 +    }
  79.431 +  }
  79.432 +}
  79.433 +
  79.434 +static unsigned long long blowfish_test(unsigned long long input)
  79.435 +{
  79.436 +    unsigned long L = input >> 32, R = input;
  79.437 +    BLOWFISH_CTX ctx;
  79.438 +    Blowfish_Init(&ctx, (unsigned char*)"TESTKEY", 7);
  79.439 +    Blowfish_Encrypt(&ctx, &L, &R);
  79.440 +    Blowfish_Decrypt(&ctx, &L, &R);
  79.441 +    return ((unsigned long long)L << 32) | R;
  79.442 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/tools/tests/blowfish.mk	Thu Jan 18 15:18:07 2007 +0000
    80.3 @@ -0,0 +1,23 @@
    80.4 +
    80.5 +override XEN_TARGET_ARCH = x86_32
    80.6 +XEN_ROOT = ../..
    80.7 +CFLAGS :=
    80.8 +include $(XEN_ROOT)/tools/Rules.mk
    80.9 +
   80.10 +# Disable PIE/SSP if GCC supports them. They can break us.
   80.11 +CFLAGS  += $(call cc-option,$(CC),-nopie,)
   80.12 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
   80.13 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
   80.14 +
   80.15 +OBJCOPY  = objcopy
   80.16 +CFLAGS  += -fno-builtin -O2 -msoft-float
   80.17 +LDFLAGS  = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000
   80.18 +
   80.19 +.PHONY: all
   80.20 +all: blowfish.bin
   80.21 +
   80.22 +blowfish.bin: blowfish.c
   80.23 +	$(CC) $(CFLAGS) -c blowfish.c
   80.24 +	$(CC) $(CFLAGS) $(LDFLAGS) -o blowfish.tmp blowfish.o
   80.25 +	$(OBJCOPY) -O binary blowfish.tmp blowfish.bin
   80.26 +	rm -f blowfish.tmp
    81.1 --- a/tools/tests/test_x86_emulator.c	Thu Jan 18 09:54:33 2007 +0000
    81.2 +++ b/tools/tests/test_x86_emulator.c	Thu Jan 18 15:18:07 2007 +0000
    81.3 @@ -15,6 +15,19 @@ typedef int64_t            s64;
    81.4  #include <asm-x86/x86_emulate.h>
    81.5  #include <sys/mman.h>
    81.6  
    81.7 +#include "blowfish.h"
    81.8 +
    81.9 +#define MMAP_SZ 16384
   81.10 +
   81.11 +/* EFLAGS bit definitions. */
   81.12 +#define EFLG_OF (1<<11)
   81.13 +#define EFLG_DF (1<<10)
   81.14 +#define EFLG_SF (1<<7)
   81.15 +#define EFLG_ZF (1<<6)
   81.16 +#define EFLG_AF (1<<4)
   81.17 +#define EFLG_PF (1<<2)
   81.18 +#define EFLG_CF (1<<0)
   81.19 +
   81.20  static int read(
   81.21      unsigned int seg,
   81.22      unsigned long offset,
   81.23 @@ -97,20 +110,25 @@ int main(int argc, char **argv)
   81.24  {
   81.25      struct x86_emulate_ctxt ctxt;
   81.26      struct cpu_user_regs regs;
   81.27 -    char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
   81.28 -    unsigned int *res;
   81.29 +    char *instr;
   81.30 +    unsigned int *res, i;
   81.31      int rc;
   81.32 +#ifndef __x86_64__
   81.33 +    unsigned int bcdres_native, bcdres_emul;
   81.34 +#endif
   81.35  
   81.36      ctxt.regs = &regs;
   81.37 -    ctxt.address_bytes = 4;
   81.38 +    ctxt.addr_size = 32;
   81.39 +    ctxt.sp_size   = 32;
   81.40  
   81.41 -    res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE,
   81.42 +    res = mmap((void *)0x100000, MMAP_SZ, PROT_READ|PROT_WRITE,
   81.43                 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
   81.44      if ( res == MAP_FAILED )
   81.45      {
   81.46          fprintf(stderr, "mmap to low address failed\n");
   81.47          exit(1);
   81.48      }
   81.49 +    instr = (char *)res + 0x100;
   81.50  
   81.51      printf("%-40s", "Testing addl %%ecx,(%%eax)...");
   81.52      instr[0] = 0x01; instr[1] = 0x08;
   81.53 @@ -399,6 +417,112 @@ int main(int argc, char **argv)
   81.54          goto fail;
   81.55      printf("okay\n");
   81.56  
   81.57 +    printf("%-40s", "Testing daa/das (all inputs)...");
   81.58 +#ifndef __x86_64__
   81.59 +    /* Bits 0-7: AL; Bit 8: EFLG_AF; Bit 9: EFLG_CF; Bit 10: DAA vs. DAS. */
   81.60 +    for ( i = 0; i < 0x800; i++ )
   81.61 +    {
   81.62 +        regs.eflags  = (i & 0x200) ? EFLG_CF : 0;
   81.63 +        regs.eflags |= (i & 0x100) ? EFLG_AF : 0;
   81.64 +        if ( i & 0x400 )
   81.65 +            __asm__ (
   81.66 +                "pushf; and $0xffffffee,(%%esp); or %1,(%%esp); popf; das; "
   81.67 +                "pushf; popl %1"
   81.68 +                : "=a" (bcdres_native), "=r" (regs.eflags)
   81.69 +                : "0" (i & 0xff), "1" (regs.eflags) );
   81.70 +        else
   81.71 +            __asm__ (
   81.72 +                "pushf; and $0xffffffee,(%%esp); or %1,(%%esp); popf; daa; "
   81.73 +                "pushf; popl %1"
   81.74 +                : "=a" (bcdres_native), "=r" (regs.eflags)
   81.75 +                : "0" (i & 0xff), "1" (regs.eflags) );
   81.76 +        bcdres_native |= (regs.eflags & EFLG_PF) ? 0x1000 : 0;
   81.77 +        bcdres_native |= (regs.eflags & EFLG_ZF) ? 0x800 : 0;
   81.78 +        bcdres_native |= (regs.eflags & EFLG_SF) ? 0x400 : 0;
   81.79 +        bcdres_native |= (regs.eflags & EFLG_CF) ? 0x200 : 0;
   81.80 +        bcdres_native |= (regs.eflags & EFLG_AF) ? 0x100 : 0;
   81.81 +
   81.82 +        instr[0] = (i & 0x400) ? 0x2f: 0x27; /* daa/das */
   81.83 +        regs.eflags  = (i & 0x200) ? EFLG_CF : 0;
   81.84 +        regs.eflags |= (i & 0x100) ? EFLG_AF : 0;
   81.85 +        regs.eip    = (unsigned long)&instr[0];
   81.86 +        regs.eax    = (unsigned char)i;
   81.87 +        rc = x86_emulate(&ctxt, &emulops);
   81.88 +        bcdres_emul  = regs.eax;
   81.89 +        bcdres_emul |= (regs.eflags & EFLG_PF) ? 0x1000 : 0;
   81.90 +        bcdres_emul |= (regs.eflags & EFLG_ZF) ? 0x800 : 0;
   81.91 +        bcdres_emul |= (regs.eflags & EFLG_SF) ? 0x400 : 0;
   81.92 +        bcdres_emul |= (regs.eflags & EFLG_CF) ? 0x200 : 0;
   81.93 +        bcdres_emul |= (regs.eflags & EFLG_AF) ? 0x100 : 0;
   81.94 +        if ( (rc != 0) || (regs.eax > 255) ||
   81.95 +             (regs.eip != (unsigned long)&instr[1]) )
   81.96 +            goto fail;
   81.97 +
   81.98 +        if ( bcdres_emul != bcdres_native )
   81.99 +        {
  81.100 +            printf("%s:    AL=%02x %s %s\n"
  81.101 +                   "Output: AL=%02x %s %s %s %s %s\n"
  81.102 +                   "Emul.:  AL=%02x %s %s %s %s %s\n",
  81.103 +                   (i & 0x400) ? "DAS" : "DAA",
  81.104 +                   (unsigned char)i,
  81.105 +                   (i & 0x200) ? "CF" : "  ",
  81.106 +                   (i & 0x100) ? "AF" : "  ",
  81.107 +                   (unsigned char)bcdres_native,
  81.108 +                   (bcdres_native & 0x200) ? "CF" : "  ",
  81.109 +                   (bcdres_native & 0x100) ? "AF" : "  ",
  81.110 +                   (bcdres_native & 0x1000) ? "PF" : "  ",
  81.111 +                   (bcdres_native & 0x800) ? "ZF" : "  ",
  81.112 +                   (bcdres_native & 0x400) ? "SF" : "  ",
  81.113 +                   (unsigned char)bcdres_emul,
  81.114 +                   (bcdres_emul & 0x200) ? "CF" : "  ",
  81.115 +                   (bcdres_emul & 0x100) ? "AF" : "  ",
  81.116 +                   (bcdres_emul & 0x1000) ? "PF" : "  ",
  81.117 +                   (bcdres_emul & 0x800) ? "ZF" : "  ",
  81.118 +                   (bcdres_emul & 0x400) ? "SF" : "  ");
  81.119 +            goto fail;
  81.120 +        }
  81.121 +    }
  81.122 +    printf("okay\n");
  81.123 +#else
  81.124 +    printf("skipped\n");
  81.125 +#endif
  81.126 +
  81.127 +    printf("Testing blowfish code sequence");
  81.128 +    memcpy(res, blowfish_code, sizeof(blowfish_code));
  81.129 +    regs.eax = 2;
  81.130 +    regs.edx = 1;
  81.131 +    regs.eip = (unsigned long)res;
  81.132 +    regs.esp = (unsigned long)res + MMAP_SZ - 4;
  81.133 +    *(uint32_t *)(unsigned long)regs.esp = 0x12345678;
  81.134 +    regs.eflags = 2;
  81.135 +    i = 0;
  81.136 +    while ( (uint32_t)regs.eip != 0x12345678 )
  81.137 +    {
  81.138 +        if ( (i++ & 8191) == 0 )
  81.139 +            printf(".");
  81.140 +        rc = x86_emulate(&ctxt, &emulops);
  81.141 +        if ( rc != 0 )
  81.142 +        {
  81.143 +            printf("failed at %%eip == %08x\n", (unsigned int)regs.eip);
  81.144 +            return 1;
  81.145 +        }
  81.146 +    }
  81.147 +    if ( (regs.esp != ((unsigned long)res + MMAP_SZ)) ||
  81.148 +         (regs.eax != 2) || (regs.edx != 1) )
  81.149 +        goto fail;
  81.150 +    printf("okay\n");
  81.151 +
  81.152 +#ifndef __x86_64__
  81.153 +    printf("%-40s", "Testing blowfish native execution...");    
  81.154 +    asm volatile (
  81.155 +        "movl $0x100000,%%ecx; call *%%ecx"
  81.156 +        : "=a" (regs.eax), "=d" (regs.edx)
  81.157 +        : "0" (2), "1" (1) : "ecx" );
  81.158 +    if ( (regs.eax != 2) || (regs.edx != 1) )
  81.159 +        goto fail;
  81.160 +    printf("okay\n");
  81.161 +#endif    
  81.162 +
  81.163      return 0;
  81.164  
  81.165   fail:
    82.1 --- a/tools/xenstat/xentop/xentop.c	Thu Jan 18 09:54:33 2007 +0000
    82.2 +++ b/tools/xenstat/xentop/xentop.c	Thu Jan 18 15:18:07 2007 +0000
    82.3 @@ -1067,9 +1067,9 @@ int main(int argc, char **argv)
    82.4  				gettimeofday(&curtime, NULL);
    82.5  				top();
    82.6  				oldtime = curtime;
    82.7 -				sleep(delay);
    82.8  				if ((!loop) && !(--iterations))
    82.9  					break;
   82.10 +				sleep(delay);
   82.11  			} while (1);
   82.12  	}
   82.13  
    83.1 --- a/tools/xm-test/README	Thu Jan 18 09:54:33 2007 +0000
    83.2 +++ b/tools/xm-test/README	Thu Jan 18 15:18:07 2007 +0000
    83.3 @@ -207,6 +207,49 @@ dedicated machine.  As such, the library
    83.4  running DomUs on the system to provide each test with a "clean slate".
    83.5  
    83.6  
    83.7 +Testing the XML-RPC and Xen-API interfaces of xend
    83.8 +==================================================
    83.9 +
   83.10 +The xm-test suite can be used to test xm's interface with xend using
   83.11 +either XML-RPC or the Xen-API. In order to use either one of these modes,
   83.12 +xm needs to be configured using its configuration file
   83.13 +'/etc/xen/xm-config.xml'.
   83.14 +Note: The current default configuration after a fresh install of the xen
   83.15 +sources currently is to use the XML-RPC interface for communication with xend.
   83.16 +
   83.17 +Example content for the xm-config.xml for using the Xen-API looks as
   83.18 +follows:
   83.19 +
   83.20 +<xm>
   83.21 +  <server type='Xen-API'
   83.22 +          uri='http://localhost:9363/'
   83.23 +          username='me'
   83.24 +          password='mypassword' />
   83.25 +</xm>
   83.26 +
   83.27 +This configuration makes xm talk to xend using port 9363. For this to
   83.28 +work, also xend needs to be configured to listen to port 9363. Therefore
   83.29 +The following line must be in /etc/xen/xend-config.sxp.
   83.30 +
   83.31 +(xen-api-server (( 127.0.0.1:9363 none )))
   83.32 +
   83.33 +To communicate via the legacy XML-RPC interface, the file
   83.34 +'/etc/xen/xm-config.xml' may simply have the following content or
   83.35 +may be complete remove from the /etc/xen directory.
   83.36 +
   83.37 +<xm>
   83.38 +</xm>
   83.39 +
   83.40 +A few tests have been written for the xm-test suite that test the
   83.41 +Xen-API interface directly without relying on 'xm'. These tests can be
   83.42 +found in the grouptest 'xapi' and for them to work properly, xm must have
   83.43 +been configured to use the Xen-API following the instructions above. To
   83.44 +run these test, the following command line can be invoked:
   83.45 +
   83.46 +   # ./runtest.sh -g xapi <logfile>
   83.47 +
   83.48 +
   83.49 +
   83.50  Extending
   83.51  =========
   83.52  
    84.1 --- a/tools/xm-test/configure.ac	Thu Jan 18 09:54:33 2007 +0000
    84.2 +++ b/tools/xm-test/configure.ac	Thu Jan 18 15:18:07 2007 +0000
    84.3 @@ -150,6 +150,7 @@ AC_CONFIG_FILES([
    84.4      tests/vcpu-pin/Makefile
    84.5      tests/vcpu-disable/Makefile
    84.6      tests/vtpm/Makefile
    84.7 +    tests/xapi/Makefile
    84.8      tests/enforce_dom0_cpus/Makefile
    84.9      lib/XmTestReport/xmtest.py
   84.10      lib/XmTestLib/config.py
    85.1 --- a/tools/xm-test/grouptest/xapi	Thu Jan 18 09:54:33 2007 +0000
    85.2 +++ b/tools/xm-test/grouptest/xapi	Thu Jan 18 15:18:07 2007 +0000
    85.3 @@ -1,1 +1,2 @@
    85.4 +xapi
    85.5  vtpm 09_vtpm-xapi.test
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/tools/xm-test/lib/XmTestLib/DomainTracking.py	Thu Jan 18 15:18:07 2007 +0000
    86.3 @@ -0,0 +1,61 @@
    86.4 +#!/usr/bin/python
    86.5 +"""
    86.6 + Copyright (C) International Business Machines Corp., 2005
    86.7 + Author: Dan Smith <danms@us.ibm.com>
    86.8 +
    86.9 + This program is free software; you can redistribute it and/or modify
   86.10 + it under the terms of the GNU General Public License as published by
   86.11 + the Free Software Foundation; under version 2 of the License.
   86.12 +
   86.13 + This program is distributed in the hope that it will be useful,
   86.14 + but WITHOUT ANY WARRANTY; without even the implied warranty of
   86.15 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   86.16 + GNU General Public License for more details.
   86.17 +
   86.18 + You should have received a copy of the GNU General Public License
   86.19 + along with this program; if not, write to the Free Software
   86.20 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   86.21 +
   86.22 +"""
   86.23 +
   86.24 +import atexit
   86.25 +import Test
   86.26 +import xapi
   86.27 +
   86.28 +# Tracking of managed domains
   86.29 +_managedDomains = []
   86.30 +_VMuuids = []
   86.31 +registered = 0
   86.32 +
   86.33 +def addManagedDomain(name):
   86.34 +    global registered
   86.35 +    _managedDomains.append(name)
   86.36 +    if not registered:
   86.37 +        atexit.register(destroyManagedDomains)
   86.38 +        registered = 1
   86.39 +
   86.40 +def delManagedDomain(name):
   86.41 +    if name in _managedDomains:
   86.42 +        del _managedDomains[_managedDomains.index(name)]
   86.43 +
   86.44 +def addXAPIDomain(uuid):
   86.45 +    global registered
   86.46 +    _VMuuids.append(uuid)
   86.47 +    if not registered:
   86.48 +        atexit.register(destroyManagedDomains)
   86.49 +        registered = 1
   86.50 +
   86.51 +def delXAPIDomain(uuid):
   86.52 +    _VMuuids.remove(uuid)
   86.53 +
   86.54 +def destroyManagedDomains():
   86.55 +    if len(_managedDomains) > 0:
   86.56 +        for m in _managedDomains:
   86.57 +            Test.traceCommand("xm destroy %s" % m)
   86.58 +            Test.traceCommand("xm delete %s" % m)
   86.59 +    if len(_VMuuids) > 0:
   86.60 +        for uuid in _VMuuids:
   86.61 +            Test.traceCommand("xm destroy %s" % uuid)
   86.62 +            Test.traceCommand("xm delete %s" % uuid)
   86.63 +
   86.64 +
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py	Thu Jan 18 15:18:07 2007 +0000
    87.3 @@ -0,0 +1,176 @@
    87.4 +#!/usr/bin/python
    87.5 +"""
    87.6 + Copyright (C) International Business Machines Corp., 2005
    87.7 + Author: Stefan Berger <stefanb@us.ibm.com>
    87.8 +
    87.9 + Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
   87.10 +
   87.11 + This program is free software; you can redistribute it and/or modify
   87.12 + it under the terms of the GNU General Public License as published by
   87.13 + the Free Software Foundation; under version 2 of the License.
   87.14 +
   87.15 + This program is distributed in the hope that it will be useful,
   87.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
   87.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   87.18 + GNU General Public License for more details.
   87.19 +
   87.20 + You should have received a copy of the GNU General Public License
   87.21 + along with this program; if not, write to the Free Software
   87.22 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   87.23 +
   87.24 +"""
   87.25 +import os
   87.26 +import sys
   87.27 +from XmTestLib import *
   87.28 +from xen.util.xmlrpclib2 import ServerProxy
   87.29 +from types import DictType
   87.30 +
   87.31 +
   87.32 +class XenAPIConfig:
   87.33 +    """An object to help create a VM configuration usable via Xen-API"""
   87.34 +    def __init__(self):
   87.35 +        self.opts = {}
   87.36 +        #Array to translate old option to new ones
   87.37 +        self.opttrlate = { 'name' : 'name_label' ,
   87.38 +                           'memory' : [ 'memory_static_max' ,
   87.39 +                                        'memory_static_min' ,
   87.40 +                                        'memory_dynamic_min',
   87.41 +                                        'memory_dynamic_max' ],
   87.42 +                           'kernel' : 'PV_kernel',
   87.43 +                           'ramdisk': 'PV_ramdisk',
   87.44 +                           'root'   : 'PV_args'}
   87.45 +
   87.46 +    def setOpt(self, name, value):
   87.47 +        """Set an option in the config"""
   87.48 +        if name in self.opttrlate.keys():
   87.49 +            _name = self.opttrlate[name]
   87.50 +        else:
   87.51 +            _name = name
   87.52 +
   87.53 +        if isinstance(_name, list):
   87.54 +            for _n in _name:
   87.55 +                self.opts[_n] = value
   87.56 +        else:
   87.57 +            self.opts[_name] = value
   87.58 +
   87.59 +    def getOpt(self, name):
   87.60 +        """Return the value of a config option"""
   87.61 +        if name in self.opts.keys():
   87.62 +            return self.opts[name]
   87.63 +        else:
   87.64 +            return None
   87.65 +
   87.66 +    def setOpts(self, opts):
   87.67 +        """Batch-set options from a dictionary"""
   87.68 +        for k, v in opts.items():
   87.69 +            self.setOpt(k, v)
   87.70 +
   87.71 +    def getOpts(self):
   87.72 +        return self.opts
   87.73 +
   87.74 +
   87.75 +class XenAPIDomain(XenDomain):
   87.76 +
   87.77 +    def __init__(self, name=None, config=None):
   87.78 +        if name:
   87.79 +            self.name = name
   87.80 +        else:
   87.81 +            self.name = getUniqueName()
   87.82 +
   87.83 +        self.config = config
   87.84 +        self.console = None
   87.85 +        self.netEnv = "bridge"
   87.86 +
   87.87 +        self.session = xapi.connect()
   87.88 +        session = self.session
   87.89 +        try:
   87.90 +            self.vm_uuid = session.xenapi.VM.create(self.config.getOpts())
   87.91 +            addXAPIDomain(self.vm_uuid)
   87.92 +        except:
   87.93 +            raise DomainError("Could not create VM config file for "
   87.94 +                              "managed domain.")
   87.95 +
   87.96 +        #Only support PV for now.
   87.97 +        self.type = "PV"
   87.98 +
   87.99 +    def start(self, noConsole=False, startpaused=False):
  87.100 +        #start the VM
  87.101 +        session = self.session
  87.102 +        if self.vm_uuid:
  87.103 +            try:
  87.104 +                session.xenapi.VM.start(self.vm_uuid, startpaused)
  87.105 +            except:
  87.106 +                raise DomainError("Could not start domain")
  87.107 +        else:
  87.108 +            raise DomainError("VM has no UUID - does VM config exist?")
  87.109 +
  87.110 +        if startpaused:
  87.111 +           return
  87.112 +
  87.113 +        if self.getDomainType() == "HVM":
  87.114 +           waitForBoot()
  87.115 +
  87.116 +        if self.console and noConsole == True:
  87.117 +            self.closeConsole()
  87.118 +
  87.119 +        elif self.console and noConsole == False:
  87.120 +            return self.console
  87.121 +
  87.122 +        elif not self.console and noConsole == False:
  87.123 +            return self.getConsole()
  87.124 +
  87.125 +    def stop(self):
  87.126 +        if self.vm_uuid:
  87.127 +            self.session.xenapi.VM.hard_shutdown(self.vm_uuid)
  87.128 +        else:
  87.129 +            raise DomainError("VM has no UUID - does VM config exist?")
  87.130 +
  87.131 +    def destroy(self):
  87.132 +        #Stop VM first.
  87.133 +        self.stop()
  87.134 +        if self.vm_uuid:
  87.135 +            self.session.xenapi.VM.destroy(self.vm_uuid)
  87.136 +            delXAPIDomain(self.vm_uuid)
  87.137 +        else:
  87.138 +            raise DomainError("VM has no UUID - does VM config exist?")
  87.139 +
  87.140 +    def get_uuid(self):
  87.141 +        return self.vm_uuid
  87.142 +
  87.143 +    def newDevice(self, Device, *args):
  87.144 +        raise DomainError("No support for newDevice().")
  87.145 +
  87.146 +    def removeDevice(self, id):
  87.147 +        raise DomainError("No support for removeDevice().")
  87.148 +
  87.149 +    def removeAllDevices(self, id):
  87.150 +        raise DomainError("No support for removeAllDevices().")
  87.151 +
  87.152 +    def isRunning(self):
  87.153 +        return isDomainRunning(self.name)
  87.154 +
  87.155 +    def getDevice(self, id):
  87.156 +        raise DomainError("No support for getDevice().")
  87.157 +
  87.158 +
  87.159 +class XmTestAPIDomain(XenAPIDomain):
  87.160 +
  87.161 +    """Create a new managed xm-test domain
  87.162 +    @param name: The requested domain name
  87.163 +    @param extraConfig: Additional configuration options
  87.164 +    @param baseConfig: The initial configuration defaults to use
  87.165 +    """
  87.166 +    def __init__(self, name=None, extraConfig=None,
  87.167 +                 baseConfig=arch.configDefaults):
  87.168 +        config = XenAPIConfig()
  87.169 +        config.setOpts(baseConfig)
  87.170 +        if extraConfig:
  87.171 +            config.setOpts(extraConfig)
  87.172 +
  87.173 +        if name:
  87.174 +            config.setOpt("name_label", name)
  87.175 +        elif not config.getOpt("name_label"):
  87.176 +            config.setOpt("name_label", getUniqueName())
  87.177 +
  87.178 +        XenAPIDomain.__init__(self, config.getOpt("name_label"),
  87.179 +                              config=config)
    88.1 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py	Thu Jan 18 09:54:33 2007 +0000
    88.2 +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py	Thu Jan 18 15:18:07 2007 +0000
    88.3 @@ -29,6 +29,7 @@ from Test import *
    88.4  from config import *
    88.5  from Console import *
    88.6  from XenDevice import *
    88.7 +from DomainTracking import *
    88.8  from acm import *
    88.9  
   88.10  
   88.11 @@ -147,7 +148,7 @@ class DomainError(Exception):
   88.12  
   88.13  class XenDomain:
   88.14  
   88.15 -    def __init__(self, name=None, config=None):
   88.16 +    def __init__(self, name=None, config=None, isManaged=False):
   88.17          """Create a domain object.
   88.18          @param config: String filename of config file
   88.19          """
   88.20 @@ -162,6 +163,10 @@ class XenDomain:
   88.21          self.devices = {}
   88.22          self.netEnv = "bridge"
   88.23  
   88.24 +        if os.getenv("XM_MANAGED_DOMAINS"):
   88.25 +            isManaged = True
   88.26 +        self.isManaged = isManaged
   88.27 +
   88.28          # Set domain type, either PV for ParaVirt domU or HVM for
   88.29          # FullVirt domain
   88.30          if ENABLE_HVM_SUPPORT:
   88.31 @@ -171,7 +176,17 @@ class XenDomain:
   88.32  
   88.33      def start(self, noConsole=False):
   88.34  
   88.35 -        ret, output = traceCommand("xm create %s" % self.config)
   88.36 +        if not self.isManaged:
   88.37 +            ret, output = traceCommand("xm create %s" % self.config)
   88.38 +        else:
   88.39 +            ret, output = traceCommand("xm new %s" % self.config)
   88.40 +            if ret != 0:
   88.41 +                _ret, output = traceCommand("xm delete " +
   88.42 +                                            self.config.getOpt("name"))
   88.43 +            else:
   88.44 +                ret, output = traceCommand("xm start " +
   88.45 +                                           self.config.getOpt("name"))
   88.46 +                addManagedDomain(self.config.getOpt("name"))
   88.47  
   88.48          if ret != 0:
   88.49              raise DomainError("Failed to create domain",
   88.50 @@ -218,6 +233,10 @@ class XenDomain:
   88.51              self.closeConsole()
   88.52  
   88.53          ret, output = traceCommand(prog + cmd + self.config.getOpt("name"))
   88.54 +        if self.isManaged:
   88.55 +            ret, output = traceCommand(prog + " delete " +
   88.56 +                                       self.config.getOpt("name"))
   88.57 +            delManagedDomain(self.config.getOpt("name"))
   88.58  
   88.59          return ret
   88.60  
   88.61 @@ -296,7 +315,7 @@ class XenDomain:
   88.62  class XmTestDomain(XenDomain):
   88.63  
   88.64      def __init__(self, name=None, extraConfig=None,
   88.65 -                 baseConfig=arch.configDefaults):
   88.66 +                 baseConfig=arch.configDefaults, isManaged=False):
   88.67          """Create a new xm-test domain
   88.68          @param name: The requested domain name
   88.69          @param extraConfig: Additional configuration options
   88.70 @@ -312,7 +331,8 @@ class XmTestDomain(XenDomain):
   88.71          elif not config.getOpt("name"):
   88.72              config.setOpt("name", getUniqueName())
   88.73  
   88.74 -        XenDomain.__init__(self, config.getOpt("name"), config=config)
   88.75 +        XenDomain.__init__(self, config.getOpt("name"), config=config,
   88.76 +                           isManaged=isManaged)
   88.77  
   88.78      def minSafeMem(self):
   88.79          return arch.minSafeMem
    89.1 --- a/tools/xm-test/lib/XmTestLib/XenManagedDomain.py	Thu Jan 18 09:54:33 2007 +0000
    89.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.3 @@ -1,177 +0,0 @@
    89.4 -#!/usr/bin/python
    89.5 -"""
    89.6 - Copyright (C) International Business Machines Corp., 2005
    89.7 - Author: Stefan Berger <stefanb@us.ibm.com>
    89.8 -
    89.9 - Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
   89.10 -
   89.11 - This program is free software; you can redistribute it and/or modify
   89.12 - it under the terms of the GNU General Public License as published by
   89.13 - the Free Software Foundation; under version 2 of the License.
   89.14 -
   89.15 - This program is distributed in the hope that it will be useful,
   89.16 - but WITHOUT ANY WARRANTY; without even the implied warranty of
   89.17 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   89.18 - GNU General Public License for more details.
   89.19 -
   89.20 - You should have received a copy of the GNU General Public License
   89.21 - along with this program; if not, write to the Free Software
   89.22 - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   89.23 -
   89.24 -"""
   89.25 -import os
   89.26 -import sys
   89.27 -from XmTestLib import *
   89.28 -from xen.util.xmlrpclib2 import ServerProxy
   89.29 -from types import DictType
   89.30 -
   89.31 -
   89.32 -class XenManagedConfig:
   89.33 -    """An object to help create a VM configuration usable via Xen-API"""
   89.34 -    def __init__(self):
   89.35 -        self.opts = {}
   89.36 -        #Array to translate old option to new ones
   89.37 -        self.opttrlate = { 'name' : 'name_label' ,
   89.38 -                           'memory' : [ 'memory_static_max' ,
   89.39 -                                        'memory_static_min' ,
   89.40 -                                        'memory_dynamic_min',
   89.41 -                                        'memory_dynamic_max' ],
   89.42 -                           'kernel' : 'kernel_kernel',
   89.43 -                           'ramdisk': 'kernel_initrd',
   89.44 -                           'root'   : 'kernel_args'}
   89.45 -
   89.46 -    def setOpt(self, name, value):
   89.47 -        """Set an option in the config"""
   89.48 -        if name in self.opttrlate.keys():
   89.49 -            _name = self.opttrlate[name]
   89.50 -        else:
   89.51 -            _name = name
   89.52 -
   89.53 -        if isinstance(_name, list):
   89.54 -            for _n in _name:
   89.55 -                self.opts[_n] = value
   89.56 -        else:
   89.57 -            self.opts[_name] = value
   89.58 -
   89.59 -    def getOpt(self, name):
   89.60 -        """Return the value of a config option"""
   89.61 -        if name in self.opts.keys():
   89.62 -            return self.opts[name]
   89.63 -        else:
   89.64 -            return None
   89.65 -
   89.66 -    def setOpts(self, opts):
   89.67 -        """Batch-set options from a dictionary"""
   89.68 -        for k, v in opts.items():
   89.69 -            self.setOpt(k, v)
   89.70 -
   89.71 -    def getOpts(self):
   89.72 -        return self.opts
   89.73 -
   89.74 -
   89.75 -class XenManagedDomain(XenDomain):
   89.76 -
   89.77 -    def __init__(self, name=None, config=None):
   89.78 -        if name:
   89.79 -            self.name = name
   89.80 -        else:
   89.81 -            self.name = getUniqueName()
   89.82 -
   89.83 -        self.config = config
   89.84 -        self.console = None
   89.85 -        self.netEnv = "bridge"
   89.86 -
   89.87 -        self.server, self.session = xapi._connect()
   89.88 -        server = self.server
   89.89 -        try:
   89.90 -            self.vm_uuid = xapi.execute(server.VM.create, self.session,
   89.91 -                                        self.config.getOpts())
   89.92 -            xapi._VMuuids.append(self.vm_uuid)
   89.93 -        except:
   89.94 -            raise DomainError("Could not create VM config file for "
   89.95 -                              "managed domain.")
   89.96 -
   89.97 -        #Only support PV for now.
   89.98 -        self.type = "PV"
   89.99 -
  89.100 -    def start(self, noConsole=False, startpaused=False):
  89.101 -        #start the VM
  89.102 -        server = self.server
  89.103 -        if self.vm_uuid:
  89.104 -            try:
  89.105 -                xapi.execute(server.VM.start, self.session, self.vm_uuid,
  89.106 -                             startpaused)
  89.107 -            except:
  89.108 -                raise DomainError("Could not start domain")
  89.109 -        else:
  89.110 -            raise DomainError("VM has not UUID - VM config does not exist?")
  89.111 -
  89.112 -        if self.getDomainType() == "HVM":
  89.113 -           waitForBoot()
  89.114 -
  89.115 -        if self.console and noConsole == True:
  89.116 -            self.closeConsole()
  89.117 -
  89.118 -        elif self.console and noConsole == False:
  89.119 -            return self.console
  89.120 -
  89.121 -        elif not self.console and noConsole == False:
  89.122 -            return self.getConsole()
  89.123 -
  89.124 -    def stop(self):
  89.125 -        if self.vm_uuid:
  89.126 -            server = self.server
  89.127 -            xapi.execute(server.VM.hard_shutdown, self.session, self.vm_uuid)
  89.128 -        else:
  89.129 -            raise DomainError("VM has not UUID - VM config does not exist?")
  89.130 -
  89.131 -    def destroy(self):
  89.132 -        #Stop VM first.
  89.133 -        self.stop()
  89.134 -        if self.vm_uuid:
  89.135 -            server = self.server
  89.136 -            xapi.execute(server.VM.destroy, self.session, self.vm_uuid)
  89.137 -            xapi._VMuuids.remove(self.vm_uuid)
  89.138 -        else:
  89.139 -            raise DomainError("VM has not UUID - VM config does not exist?")
  89.140 -
  89.141 -    def get_uuid(self):
  89.142 -        return self.vm_uuid
  89.143 -
  89.144 -    def newDevice(self, Device, *args):
  89.145 -        raise DomainError("No support for newDevice().")
  89.146 -
  89.147 -    def removeDevice(self, id):
  89.148 -        raise DomainError("No support for removeDevice().")
  89.149 -
  89.150 -    def removeAllDevices(self, id):
  89.151 -        raise DomainError("No support for removeAllDevices().")
  89.152 -
  89.153 -    def isRunning(self):
  89.154 -        return isDomainRunning(self.name)
  89.155 -
  89.156 -    def getDevice(self, id):
  89.157 -        raise DomainError("No support for getDevice().")
  89.158 -
  89.159 -
  89.160 -class XmTestManagedDomain(XenManagedDomain):
  89.161 -
  89.162 -    """Create a new managed xm-test domain
  89.163 -    @param name: The requested domain name
  89.164 -    @param extraConfig: Additional configuration options
  89.165 -    @param baseConfig: The initial configuration defaults to use
  89.166 -    """
  89.167 -    def __init__(self, name=None, extraConfig=None,
  89.168 -                 baseConfig=arch.configDefaults):
  89.169 -        config = XenManagedConfig()
  89.170 -        config.setOpts(baseConfig)
  89.171 -        if extraConfig:
  89.172 -            config.setOpts(extraConfig)
  89.173 -
  89.174 -        if name:
  89.175 -            config.setOpt("name_label", name)
  89.176 -        elif not config.getOpt("name_label"):
  89.177 -            config.setOpt("name_label", getUniqueName())
  89.178 -
  89.179 -        XenManagedDomain.__init__(self, config.getOpt("name_label"),
  89.180 -                                  config=config)
    90.1 --- a/tools/xm-test/lib/XmTestLib/Xm.py	Thu Jan 18 09:54:33 2007 +0000
    90.2 +++ b/tools/xm-test/lib/XmTestLib/Xm.py	Thu Jan 18 15:18:07 2007 +0000
    90.3 @@ -49,6 +49,8 @@ def domid(name):
    90.4  
    90.5      if status != 0 or "Traceback" in output:
    90.6          return -1
    90.7 +    if output == "None":
    90.8 +        return -1
    90.9      try:
   90.10          return int(output)
   90.11      except:
    91.1 --- a/tools/xm-test/lib/XmTestLib/xapi.py	Thu Jan 18 09:54:33 2007 +0000
    91.2 +++ b/tools/xm-test/lib/XmTestLib/xapi.py	Thu Jan 18 15:18:07 2007 +0000
    91.3 @@ -17,50 +17,49 @@
    91.4  # Copyright (C) 2006 IBM Corporation
    91.5  #============================================================================
    91.6  
    91.7 +import atexit
    91.8  import os
    91.9  import sys
   91.10  from XmTestLib import *
   91.11 -from xen.util.xmlrpclib2 import ServerProxy
   91.12 +from xen.xm import main as xmmain
   91.13 +from xen.xm import XenAPI
   91.14 +from xen.xm.opts import OptionError
   91.15  from types import DictType
   91.16 -
   91.17 -
   91.18 -XAPI_DEFAULT_LOGIN = " "
   91.19 -XAPI_DEFAULT_PASSWORD = " "
   91.20 -
   91.21 -class XenAPIError(Exception):
   91.22 -    pass
   91.23 -
   91.24 +import xml.dom.minidom
   91.25  
   91.26 -#A list of VMs' UUIDs that were created using vm_create
   91.27 -_VMuuids = []
   91.28 +def get_login_pwd():
   91.29 +    if xmmain.serverType == xmmain.SERVER_XEN_API:
   91.30 +        try:
   91.31 +            login, password = xmmain.parseAuthentication()
   91.32 +            return (login, password)
   91.33 +        except:
   91.34 +            raise OptionError("Configuration for login/pwd not found. "
   91.35 +                              "Need to run xapi-setup.py?")
   91.36 +    raise OptionError("Xm configuration file not using Xen-API for "
   91.37 +                      "communication with xend.")
   91.38  
   91.39 -#Terminate previously created managed(!) VMs and destroy their configs
   91.40 -def vm_destroy_all():
   91.41 -    server, session = _connect()
   91.42 -    for uuid in _VMuuids:
   91.43 -        execute(server.VM.hard_shutdown, session, uuid)
   91.44 -        execute(server.VM.destroy      , session, uuid)
   91.45 -
   91.46 +sessions=[]
   91.47  
   91.48 -def execute(fn, *args):
   91.49 -    result = fn(*args)
   91.50 -    if type(result) != DictType:
   91.51 -        raise TypeError("Function returned object of type: %s" %
   91.52 -                        str(type(result)))
   91.53 -    if 'Value' not in result:
   91.54 -        raise XenAPIError(*result['ErrorDescription'])
   91.55 -    return result['Value']
   91.56 -
   91.57 -_initialised = False
   91.58 -_server = None
   91.59 -_session = None
   91.60 -def _connect(*args):
   91.61 -    global _server, _session, _initialised
   91.62 -    if not _initialised:
   91.63 -        _server = ServerProxy('httpu:///var/run/xend/xen-api.sock')
   91.64 -        login = XAPI_DEFAULT_LOGIN
   91.65 -        password = XAPI_DEFAULT_PASSWORD
   91.66 -        creds = (login, password)
   91.67 -        _session = execute(_server.session.login_with_password, *creds)
   91.68 -        _initialised = True
   91.69 -    return (_server, _session)
   91.70 +def connect(*args):
   91.71 +    try:
   91.72 +        creds = get_login_pwd()
   91.73 +    except Exception, e:
   91.74 +        FAIL("%s" % str(e))
   91.75 +    try:
   91.76 +        session = XenAPI.Session(xmmain.serverURI)
   91.77 +    except:
   91.78 +        raise OptionError("Could not create XenAPI session with Xend." \
   91.79 +                          "URI=%s" % xmmain.serverURI)
   91.80 +    try:
   91.81 +        session.login_with_password(*creds)
   91.82 +    except:
   91.83 +        raise OptionError("Could not login to Xend. URI=%s" % xmmain.serverURI)
   91.84 +    def logout():
   91.85 +        try:
   91.86 +            for s in sessions:
   91.87 +                s.xenapi.session.logout()
   91.88 +        except:
   91.89 +            pass
   91.90 +    sessions.append(session)
   91.91 +    atexit.register(logout)
   91.92 +    return session
    92.1 --- a/tools/xm-test/ramdisk/Makefile.am	Thu Jan 18 09:54:33 2007 +0000
    92.2 +++ b/tools/xm-test/ramdisk/Makefile.am	Thu Jan 18 15:18:07 2007 +0000
    92.3 @@ -36,7 +36,12 @@ XMTEST_MAJ_VER = $(shell echo @PACKAGE_V
    92.4  XMTEST_VER_IMG = initrd-$(XMTEST_MAJ_VER)-$(BR_ARCH).img
    92.5  XMTEST_DL_IMG = $(shell echo $(XMTEST_VER_IMG) | sed -e 's/x86_64/i386/g')
    92.6  
    92.7 -EXTRA_ROOT_DIRS = sys
    92.8 +EXTRA_ROOT_DIRS = sys modules
    92.9 +
   92.10 +BLKDRV = /lib/modules/$(shell uname -r)/kernel/drivers/xen/blkfront/xenblk.ko
   92.11 +NETDRV = /lib/modules/$(shell uname -r)/kernel/drivers/xen/netfront/xennet.ko
   92.12 +PKTDRV = /lib/modules/$(shell uname -r)/kernel/net/packet/af_packet.ko
   92.13 +
   92.14  
   92.15  if HVM
   92.16  all: initrd.img disk.img
   92.17 @@ -60,7 +65,11 @@ endif
   92.18  
   92.19  $(XMTEST_VER_IMG): $(BR_IMG)
   92.20  	chmod a+x skel/etc/init.d/rcS
   92.21 -	(cd skel; mkdir -p $(EXTRA_ROOT_DIRS); tar cf - .) \
   92.22 +	cd skel && mkdir -p $(EXTRA_ROOT_DIRS)
   92.23 +	-[ -e "$(BLKDRV)" ] && cp $(BLKDRV) skel/modules
   92.24 +	-[ -e "$(NETDRV)" ] && cp $(NETDRV) skel/modules
   92.25 +	-[ -e "$(PKTDRV)" ] && cp $(PKTDRV) skel/modules
   92.26 +	(cd skel; tar cf - .) \
   92.27  		| (cd $(BR_SRC)/$(BR_ROOT); tar xvf -)
   92.28  	cd $(BR_SRC) && make
   92.29  	cp $(BR_IMG) $(XMTEST_VER_IMG)
    93.1 --- a/tools/xm-test/ramdisk/skel/etc/init.d/rcS	Thu Jan 18 09:54:33 2007 +0000
    93.2 +++ b/tools/xm-test/ramdisk/skel/etc/init.d/rcS	Thu Jan 18 15:18:07 2007 +0000
    93.3 @@ -6,3 +6,14 @@ mount -a
    93.4  if uname -r | grep -q '^2.6'; then
    93.5  	mount -t sysfs none /sys
    93.6  fi
    93.7 +
    93.8 +# If the block, net, and packet drivers are modules, we need to load them
    93.9 +if test -e /modules/xenblk.ko; then
   93.10 +	insmod /modules/xenblk.ko > /dev/null 2>&1
   93.11 +fi
   93.12 +if test -e /modules/xennet.ko; then
   93.13 +	insmod /modules/xennet.ko > /dev/null 2>&1
   93.14 +fi
   93.15 +if test -e /modules/af_packet.ko; then
   93.16 +	insmod /modules/af_packet.ko > /dev/null 2>&1
   93.17 +fi
    94.1 --- a/tools/xm-test/runtest.sh	Thu Jan 18 09:54:33 2007 +0000
    94.2 +++ b/tools/xm-test/runtest.sh	Thu Jan 18 15:18:07 2007 +0000
    94.3 @@ -16,6 +16,7 @@ usage() {
    94.4      echo "  -r <url>    : url of test results repository to use"
    94.5      echo "  -s <report> : just submit report <report>"
    94.6      echo "  -u          : unsafe -- do not run the sanity checks before starting"
    94.7 +    echo "  -md         : all created domains are xend-'managed' domains"
    94.8      echo "  -h | --help : show this help"
    94.9  }
   94.10  
   94.11 @@ -218,11 +219,14 @@ run=yes
   94.12  unsafe=no
   94.13  GROUPENTERED=default
   94.14  
   94.15 +#Prepare for usage with ACM
   94.16  if [ -d /etc/xen/acm-security/policies ]; then
   94.17  	cp -f tests/security-acm/xm-test-security_policy.xml \
   94.18  	      /etc/xen/acm-security/policies
   94.19  fi
   94.20  
   94.21 +unset XM_MANAGED_DOMAINS
   94.22 +
   94.23  # Resolve options
   94.24  while [ $# -gt 0 ]
   94.25    do
   94.26 @@ -260,6 +264,10 @@ while [ $# -gt 0 ]
   94.27  	  unsafe=yes
   94.28  	  report=no
   94.29  	  ;;
   94.30 +      -md)
   94.31 +          echo "(use managed domains)"
   94.32 +          export XM_MANAGED_DOMAINS=1
   94.33 +          ;;
   94.34        -h|--help)
   94.35            usage
   94.36            exit 0
    95.1 --- a/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py	Thu Jan 18 09:54:33 2007 +0000
    95.2 +++ b/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py	Thu Jan 18 15:18:07 2007 +0000
    95.3 @@ -2,14 +2,27 @@
    95.4  #
    95.5  # Sched-credit tests modified from SEDF tests
    95.6  #
    95.7 +
    95.8 +import re
    95.9 +
   95.10  from XmTestLib import *
   95.11  
   95.12 +paramsRE = re.compile(r'^[^ ]* *[^ ]* *([^ ]*) *([^ ]*)$')
   95.13 +
   95.14  def get_sched_credit_params(domain):
   95.15 -    status, output = traceCommand("xm sched-credit -d %s" %(domain.getName()))
   95.16 -    params = output.strip('{}').split(', ')
   95.17 -    cap = int(params[0].split(':')[1].strip(' '))
   95.18 -    weight = int(params[1].split(':')[1].strip(' '))
   95.19 -    return (status, (weight, cap))
   95.20 +    status, output = traceCommand("xm sched-credit -d %s | tail -1" %
   95.21 +                                  domain.getName())
   95.22 +
   95.23 +    if status != 0:
   95.24 +        FAIL("Getting sched-credit parameters return non-zero rv (%d)",
   95.25 +             status)
   95.26 +
   95.27 +    m = paramsRE.match(output)
   95.28 +    if not m:
   95.29 +        FAIL("xm sched-credit gave bad output")
   95.30 +    weight = int(m.group(1))
   95.31 +    cap = int(m.group(2))
   95.32 +    return (weight, cap)
   95.33  
   95.34  def set_sched_credit_weight(domain, weight):
   95.35      status, output = traceCommand("xm sched-credit -d %s -w %d" %(domain.getName(), weight))
   95.36 @@ -31,11 +44,8 @@ except DomainError, e:
   95.37      FAIL(str(e))
   95.38  
   95.39  # check default param values
   95.40 -(status, params) = get_sched_credit_params(domain)
   95.41 -if status != 0:
   95.42 -    FAIL("Getting sched-credit parameters return non-zero rv (%d)", status)
   95.43 +(weight, cap) = get_sched_credit_params(domain)
   95.44  
   95.45 -(weight, cap) = params
   95.46  if weight != 256:
   95.47      FAIL("default weight is 256 (got %d)", weight)
   95.48  if cap != 0:
   95.49 @@ -51,11 +61,8 @@ if status != 0:
   95.50      FAIL("Setting sched-credit cap return non-zero rv (%d)", status)
   95.51  
   95.52  # check new param values
   95.53 -(status, params) = get_sched_credit_params(domain)
   95.54 -if status != 0:
   95.55 -    FAIL("Getting sched-credit parameters return non-zero rv (%d)", status)
   95.56 +(weight, cap) = get_sched_credit_params(domain)
   95.57  
   95.58 -(weight, cap) = params
   95.59  if weight != 512:
   95.60      FAIL("expected weight of 512 (got %d)", weight)
   95.61  if cap != 100:
    96.1 --- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py	Thu Jan 18 09:54:33 2007 +0000
    96.2 +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py	Thu Jan 18 15:18:07 2007 +0000
    96.3 @@ -6,71 +6,66 @@
    96.4  # Test to test the vtpm class through the Xen-API
    96.5  
    96.6  from XmTestLib import xapi
    96.7 -from XmTestLib.XenManagedDomain import XmTestManagedDomain
    96.8 +from XmTestLib.XenAPIDomain import XmTestAPIDomain
    96.9  from XmTestLib import *
   96.10  from vtpm_utils import *
   96.11  import commands
   96.12  import os
   96.13  
   96.14 -def do_test():
   96.15 -    domain = XmTestManagedDomain()
   96.16 -    vm_uuid = domain.get_uuid()
   96.17 -
   96.18 -    vtpmcfg = {}
   96.19 -    vtpmcfg['type'] = "paravirtualised"
   96.20 -    vtpmcfg['backend'] = "Domain-0"
   96.21 -    vtpmcfg['instance'] = 1
   96.22 -    vtpmcfg['VM'] = vm_uuid
   96.23 -
   96.24 -    server, session = xapi._connect()
   96.25 +try:
   96.26 +    # XmTestAPIDomain tries to establish a connection to XenD
   96.27 +    domain = XmTestAPIDomain()
   96.28 +except Exception, e:
   96.29 +    SKIP("Skipping test. Error: %s" % str(e))
   96.30 +vm_uuid = domain.get_uuid()
   96.31  
   96.32 -    vtpm_uuid = xapi.execute(server.VTPM.create, session, vtpmcfg)
   96.33 +vtpmcfg = {}
   96.34 +vtpmcfg['type'] = "paravirtualised"
   96.35 +vtpmcfg['backend'] = "Domain-0"
   96.36 +vtpmcfg['instance'] = 1
   96.37 +vtpmcfg['VM'] = vm_uuid
   96.38  
   96.39 -    vtpm_id = xapi.execute(server.VTPM.get_instance, session, vtpm_uuid)
   96.40 -    vtpm_be = xapi.execute(server.VTPM.get_backend , session, vtpm_uuid)
   96.41 -    if vtpm_be != vtpmcfg['backend']:
   96.42 -        FAIL("vTPM's backend is in '%s', expected: '%s'" %
   96.43 -             (vtpm_be, vtpmcfg['backend']))
   96.44 +session = xapi.connect()
   96.45  
   96.46 -    driver = xapi.execute(server.VTPM.get_driver, session, vtpm_uuid)
   96.47 -    if driver != vtpmcfg['type']:
   96.48 -        FAIL("vTPM has driver type '%s', expected: '%s'" %
   96.49 -             (driver, vtpmcfg['type']))
   96.50 -
   96.51 -    vtpm_rec = xapi.execute(server.VTPM.get_record, session, vtpm_uuid)
   96.52 +vtpm_uuid = session.xenapi.VTPM.create(vtpmcfg)
   96.53  
   96.54 -    if vtpm_rec['driver']  != vtpmcfg['type']:
   96.55 -        FAIL("vTPM record shows driver type '%s', expected: '%s'" %
   96.56 -             (vtpm_rec['driver'], vtpmcfg['type']))
   96.57 -    if vtpm_rec['uuid']  != vtpm_uuid:
   96.58 -        FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
   96.59 -             (vtpm_rec['uuid'], vtpm_uuid))
   96.60 -    if vtpm_rec['VM']  != vm_uuid:
   96.61 -        FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
   96.62 -             (vtpm_rec['VM'], vm_uuid))
   96.63 +vtpm_id = session.xenapi.VTPM.get_instance(vtpm_uuid)
   96.64 +vtpm_be = session.xenapi.VTPM.get_backend(vtpm_uuid)
   96.65 +if vtpm_be != vtpmcfg['backend']:
   96.66 +    FAIL("vTPM's backend is in '%s', expected: '%s'" %
   96.67 +         (vtpm_be, vtpmcfg['backend']))
   96.68  
   96.69 -    success = domain.start()
   96.70 +driver = session.xenapi.VTPM.get_driver(vtpm_uuid)
   96.71 +if driver != vtpmcfg['type']:
   96.72 +    FAIL("vTPM has driver type '%s', expected: '%s'" %
   96.73 +         (driver, vtpmcfg['type']))
   96.74  
   96.75 -    console = domain.getConsole()
   96.76 +vtpm_rec = session.xenapi.VTPM.get_record(vtpm_uuid)
   96.77  
   96.78 -    try:
   96.79 -        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   96.80 -    except ConsoleError, e:
   96.81 -        saveLog(console.getHistory())
   96.82 -        vtpm_cleanup(domName)
   96.83 -        FAIL("No result from dumping the PCRs")
   96.84 +if vtpm_rec['driver']  != vtpmcfg['type']:
   96.85 +    FAIL("vTPM record shows driver type '%s', expected: '%s'" %
   96.86 +         (vtpm_rec['driver'], vtpmcfg['type']))
   96.87 +if vtpm_rec['uuid']  != vtpm_uuid:
   96.88 +    FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
   96.89 +         (vtpm_rec['uuid'], vtpm_uuid))
   96.90 +if vtpm_rec['VM']  != vm_uuid:
   96.91 +    FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
   96.92 +         (vtpm_rec['VM'], vm_uuid))
   96.93  
   96.94 -    if re.search("No such file",run["output"]):
   96.95 -        vtpm_cleanup(domName)
   96.96 -        FAIL("TPM frontend support not compiled into (domU?) kernel")
   96.97 +success = domain.start()
   96.98  
   96.99 -    domain.stop()
  96.100 -    domain.destroy()
  96.101 -
  96.102 -
  96.103 +console = domain.getConsole()
  96.104  
  96.105  try:
  96.106 -    do_test()
  96.107 -finally:
  96.108 -    #Make sure all domains are gone that were created in this test case
  96.109 -    xapi.vm_destroy_all()
  96.110 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  96.111 +except ConsoleError, e:
  96.112 +    saveLog(console.getHistory())
  96.113 +    vtpm_cleanup(domName)
  96.114 +    FAIL("No result from dumping the PCRs")
  96.115 +
  96.116 +if re.search("No such file",run["output"]):
  96.117 +    vtpm_cleanup(domName)
  96.118 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
  96.119 +
  96.120 +domain.stop()
  96.121 +domain.destroy()
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/tools/xm-test/tests/xapi/01_xapi-vm_basic.py	Thu Jan 18 15:18:07 2007 +0000
    97.3 @@ -0,0 +1,61 @@
    97.4 +#!/usr/bin/python
    97.5 +
    97.6 +# Copyright (C) International Business Machines Corp., 2006
    97.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    97.8 +
    97.9 +# Basic VM creation test
   97.10 +
   97.11 +from XmTestLib import xapi
   97.12 +from XmTestLib.XenAPIDomain import XmTestAPIDomain
   97.13 +from XmTestLib import *
   97.14 +from xen.xend import XendAPIConstants
   97.15 +import commands
   97.16 +import os
   97.17 +
   97.18 +try:
   97.19 +    # XmTestAPIDomain tries to establish a connection to XenD
   97.20 +    domain = XmTestAPIDomain()
   97.21 +except Exception, e:
   97.22 +    SKIP("Skipping test. Error: %s" % str(e))
   97.23 +vm_uuid = domain.get_uuid()
   97.24 +
   97.25 +session = xapi.connect()
   97.26 +
   97.27 +domain.start(startpaused=True)
   97.28 +
   97.29 +res = session.xenapi.VM.get_power_state(vm_uuid)
   97.30 +
   97.31 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]:
   97.32 +    FAIL("VM was not started in 'paused' state")
   97.33 +
   97.34 +res = session.xenapi.VM.unpause(vm_uuid)
   97.35 +
   97.36 +res = session.xenapi.VM.get_power_state(vm_uuid)
   97.37 +
   97.38 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]:
   97.39 +    FAIL("VM could not be put into 'running' state")
   97.40 +
   97.41 +console = domain.getConsole()
   97.42 +
   97.43 +try:
   97.44 +    run = console.runCmd("cat /proc/interrupts")
   97.45 +except ConsoleError, e:
   97.46 +    saveLog(console.getHistory())
   97.47 +    FAIL("Could not access proc-filesystem")
   97.48 +
   97.49 +res = session.xenapi.VM.pause(vm_uuid)
   97.50 +
   97.51 +res = session.xenapi.VM.get_power_state(vm_uuid)
   97.52 +
   97.53 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]:
   97.54 +    FAIL("VM could not be put into 'paused' state")
   97.55 +
   97.56 +res = session.xenapi.VM.unpause(vm_uuid)
   97.57 +
   97.58 +res = session.xenapi.VM.get_power_state(vm_uuid)
   97.59 +
   97.60 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]:
   97.61 +    FAIL("VM could not be 'unpaused'")
   97.62 +
   97.63 +domain.stop()
   97.64 +domain.destroy()
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/tools/xm-test/tests/xapi/Makefile.am	Thu Jan 18 15:18:07 2007 +0000
    98.3 @@ -0,0 +1,19 @@
    98.4 +SUBDIRS =
    98.5 +
    98.6 +TESTS = 01_xapi-vm_basic.test
    98.7 +
    98.8 +XFAIL_TESTS =
    98.9 +
   98.10 +EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) xapi_utils.py
   98.11 +TESTS_ENVIRONMENT=@TENV@
   98.12 +
   98.13 +%.test: %.py
   98.14 +	cp $< $@
   98.15 +	chmod +x $@
   98.16 +
   98.17 +clean-local: am_config_clean-local
   98.18 +
   98.19 +am_config_clean-local:
   98.20 +	rm -f *test
   98.21 +	rm -f *log
   98.22 +	rm -f *~
    99.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Thu Jan 18 09:54:33 2007 +0000
    99.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Thu Jan 18 15:18:07 2007 +0000
    99.3 @@ -179,7 +179,7 @@ static int get_hypercall_stubs(void)
    99.4  #define get_hypercall_stubs()	(0)
    99.5  #endif
    99.6  
    99.7 -static int get_callback_irq(struct pci_dev *pdev)
    99.8 +static uint64_t get_callback_via(struct pci_dev *pdev)
    99.9  {
   99.10  #ifdef __ia64__
   99.11  	int irq;
   99.12 @@ -189,16 +189,24 @@ static int get_callback_irq(struct pci_d
   99.13  	}
   99.14  	return 0;
   99.15  #else /* !__ia64__ */
   99.16 -	return pdev->irq;
   99.17 +	if (pdev->irq < 16)
   99.18 +		return pdev->irq; /* ISA IRQ */
   99.19 +	/* We don't know the GSI. Specify the PCI INTx line instead. */
   99.20 +	return (((uint64_t)0x01 << 56) | /* PCI INTx identifier */
   99.21 +		((uint64_t)pci_domain_nr(pdev->bus) << 32) |
   99.22 +		((uint64_t)pdev->bus->number << 16) |
   99.23 +		((uint64_t)(pdev->devfn & 0xff) << 8) |
   99.24 +		((uint64_t)(pdev->pin - 1) & 3));
   99.25  #endif
   99.26  }
   99.27  
   99.28  static int __devinit platform_pci_init(struct pci_dev *pdev,
   99.29  				       const struct pci_device_id *ent)
   99.30  {
   99.31 -	int i, ret, callback_irq;
   99.32 +	int i, ret;
   99.33  	long ioaddr, iolen;
   99.34  	long mmio_addr, mmio_len;
   99.35 +	uint64_t callback_via;
   99.36  
   99.37  	i = pci_enable_device(pdev);
   99.38  	if (i)
   99.39 @@ -210,9 +218,9 @@ static int __devinit platform_pci_init(s
   99.40  	mmio_addr = pci_resource_start(pdev, 1);
   99.41  	mmio_len = pci_resource_len(pdev, 1);
   99.42  
   99.43 -	callback_irq = get_callback_irq(pdev);
   99.44 +	callback_via = get_callback_via(pdev);
   99.45  
   99.46 -	if (mmio_addr == 0 || ioaddr == 0 || callback_irq == 0) {
   99.47 +	if (mmio_addr == 0 || ioaddr == 0 || callback_via == 0) {
   99.48  		printk(KERN_WARNING DRV_NAME ":no resources found\n");
   99.49  		return -ENOENT;
   99.50  	}
   99.51 @@ -242,12 +250,12 @@ static int __devinit platform_pci_init(s
   99.52  	if ((ret = init_xen_info()))
   99.53  		goto out;
   99.54  
   99.55 -	if ((ret = request_irq(pdev->irq, evtchn_interrupt, SA_SHIRQ,
   99.56 -			       "xen-platform-pci", pdev))) {
   99.57 +	if ((ret = request_irq(pdev->irq, evtchn_interrupt,
   99.58 +			       SA_SHIRQ | SA_SAMPLE_RANDOM,
   99.59 +			       "xen-platform-pci", pdev)))
   99.60  		goto out;
   99.61 -	}
   99.62  
   99.63 -	if ((ret = set_callback_irq(callback_irq)))
   99.64 +	if ((ret = set_callback_via(callback_via)))
   99.65  		goto out;
   99.66  
   99.67   out:
   99.68 @@ -297,7 +305,7 @@ static void __exit platform_pci_module_c
   99.69  {
   99.70  	printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n");
   99.71  	/* disable hypervisor for callback irq */
   99.72 -	set_callback_irq(0);
   99.73 +	set_callback_via(0);
   99.74  	if (pci_device_registered)
   99.75  		pci_unregister_driver(&platform_driver);
   99.76  }
   100.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h	Thu Jan 18 09:54:33 2007 +0000
   100.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h	Thu Jan 18 15:18:07 2007 +0000
   100.3 @@ -24,13 +24,13 @@
   100.4  #include <linux/interrupt.h>
   100.5  #include <xen/interface/hvm/params.h>
   100.6  
   100.7 -static inline int set_callback_irq(int irq)
   100.8 +static inline int set_callback_via(uint64_t via)
   100.9  {
  100.10  	struct xen_hvm_param a;
  100.11  
  100.12  	a.domid = DOMID_SELF;
  100.13  	a.index = HVM_PARAM_CALLBACK_IRQ;
  100.14 -	a.value = irq;
  100.15 +	a.value = via;
  100.16  	return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
  100.17  }
  100.18  
   101.1 --- a/xen/arch/ia64/linux-xen/unaligned.c	Thu Jan 18 09:54:33 2007 +0000
   101.2 +++ b/xen/arch/ia64/linux-xen/unaligned.c	Thu Jan 18 15:18:07 2007 +0000
   101.3 @@ -24,7 +24,7 @@
   101.4  #include <asm/uaccess.h>
   101.5  #include <asm/unaligned.h>
   101.6  
   101.7 -extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
   101.8 +extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
   101.9  
  101.10  #undef DEBUG_UNALIGNED_TRAP
  101.11  
   102.1 --- a/xen/arch/ia64/xen/xenmisc.c	Thu Jan 18 09:54:33 2007 +0000
   102.2 +++ b/xen/arch/ia64/xen/xenmisc.c	Thu Jan 18 15:18:07 2007 +0000
   102.3 @@ -77,7 +77,7 @@ void console_print(char *msg)
   102.4  // called from unaligned.c
   102.5  ////////////////////////////////////
   102.6  
   102.7 -void die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */
   102.8 +void die_if_kernel(char *str, struct pt_regs *regs, long err)
   102.9  {
  102.10  	if (user_mode(regs))
  102.11  		return;
  102.12 @@ -88,7 +88,7 @@ void die_if_kernel(char *str, struct pt_
  102.13  	domain_crash_synchronous();
  102.14  }
  102.15  
  102.16 -void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */
  102.17 +void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err)
  102.18  {
  102.19  	if (vmx_user_mode(regs))
  102.20  		return;
   103.1 --- a/xen/arch/x86/domain.c	Thu Jan 18 09:54:33 2007 +0000
   103.2 +++ b/xen/arch/x86/domain.c	Thu Jan 18 15:18:07 2007 +0000
   103.3 @@ -1047,7 +1047,7 @@ void context_switch(struct vcpu *prev, s
   103.4  
   103.5      local_irq_disable();
   103.6  
   103.7 -    if ( is_hvm_vcpu(prev) )
   103.8 +    if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) )
   103.9          pt_freeze_time(prev);
  103.10  
  103.11      set_current(next);
   104.1 --- a/xen/arch/x86/hvm/hpet.c	Thu Jan 18 09:54:33 2007 +0000
   104.2 +++ b/xen/arch/x86/hvm/hpet.c	Thu Jan 18 15:18:07 2007 +0000
   104.3 @@ -356,8 +356,6 @@ static void hpet_timer_fn(void *opaque)
   104.4          }
   104.5          set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn]));
   104.6      }
   104.7 -
   104.8 -    vcpu_kick(h->vcpu);    
   104.9  }
  104.10  
  104.11  void hpet_migrate_timers(struct vcpu *v)
   105.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Jan 18 09:54:33 2007 +0000
   105.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Jan 18 15:18:07 2007 +0000
   105.3 @@ -800,7 +800,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
   105.4                  d->arch.hvm_domain.buffered_io_va = (unsigned long)p;
   105.5                  break;
   105.6              case HVM_PARAM_CALLBACK_IRQ:
   105.7 -                hvm_set_callback_gsi(d, a.value);
   105.8 +                hvm_set_callback_via(d, a.value);
   105.9                  break;
  105.10              }
  105.11              d->arch.hvm_domain.params[a.index] = a.value;
   106.1 --- a/xen/arch/x86/hvm/i8254.c	Thu Jan 18 09:54:33 2007 +0000
   106.2 +++ b/xen/arch/x86/hvm/i8254.c	Thu Jan 18 15:18:07 2007 +0000
   106.3 @@ -182,11 +182,9 @@ void pit_time_fired(struct vcpu *v, void
   106.4      s->count_load_time = hvm_get_guest_time(v);
   106.5  }
   106.6  
   106.7 -static inline void pit_load_count(PITChannelState *s, int val)
   106.8 +static inline void pit_load_count(PITChannelState *s, int channel, int val)
   106.9  {
  106.10      u32 period;
  106.11 -    PITChannelState *ch0 =
  106.12 -        &current->domain->arch.hvm_domain.pl_time.vpit.channels[0];
  106.13  
  106.14      if (val == 0)
  106.15          val = 0x10000;
  106.16 @@ -194,7 +192,7 @@ static inline void pit_load_count(PITCha
  106.17      s->count = val;
  106.18      period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
  106.19  
  106.20 -    if (s != ch0)
  106.21 +    if (channel != 0)
  106.22          return;
  106.23  
  106.24  #ifdef DEBUG_PIT
  106.25 @@ -282,17 +280,17 @@ static void pit_ioport_write(void *opaqu
  106.26          switch(s->write_state) {
  106.27          default:
  106.28          case RW_STATE_LSB:
  106.29 -            pit_load_count(s, val);
  106.30 +            pit_load_count(s, addr, val);
  106.31              break;
  106.32          case RW_STATE_MSB:
  106.33 -            pit_load_count(s, val << 8);
  106.34 +            pit_load_count(s, addr, val << 8);
  106.35              break;
  106.36          case RW_STATE_WORD0:
  106.37              s->write_latch = val;
  106.38              s->write_state = RW_STATE_WORD1;
  106.39              break;
  106.40          case RW_STATE_WORD1:
  106.41 -            pit_load_count(s, s->write_latch | (val << 8));
  106.42 +            pit_load_count(s, addr, s->write_latch | (val << 8));
  106.43              s->write_state = RW_STATE_WORD0;
  106.44              break;
  106.45          }
  106.46 @@ -369,7 +367,7 @@ static void pit_reset(void *opaque)
  106.47          destroy_periodic_time(&s->pt);
  106.48          s->mode = 0xff; /* the init mode */
  106.49          s->gate = (i != 2);
  106.50 -        pit_load_count(s, 0);
  106.51 +        pit_load_count(s, i, 0);
  106.52      }
  106.53  }
  106.54  
   107.1 --- a/xen/arch/x86/hvm/irq.c	Thu Jan 18 09:54:33 2007 +0000
   107.2 +++ b/xen/arch/x86/hvm/irq.c	Thu Jan 18 15:18:07 2007 +0000
   107.3 @@ -25,7 +25,7 @@
   107.4  #include <xen/sched.h>
   107.5  #include <asm/hvm/domain.h>
   107.6  
   107.7 -void hvm_pci_intx_assert(
   107.8 +static void __hvm_pci_intx_assert(
   107.9      struct domain *d, unsigned int device, unsigned int intx)
  107.10  {
  107.11      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  107.12 @@ -33,10 +33,8 @@ void hvm_pci_intx_assert(
  107.13  
  107.14      ASSERT((device <= 31) && (intx <= 3));
  107.15  
  107.16 -    spin_lock(&hvm_irq->lock);
  107.17 -
  107.18      if ( __test_and_set_bit(device*4 + intx, &hvm_irq->pci_intx) )
  107.19 -        goto out;
  107.20 +        return;
  107.21  
  107.22      gsi = hvm_pci_intx_gsi(device, intx);
  107.23      if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
  107.24 @@ -50,12 +48,19 @@ void hvm_pci_intx_assert(
  107.25          vioapic_irq_positive_edge(d, isa_irq);
  107.26          vpic_irq_positive_edge(d, isa_irq);
  107.27      }
  107.28 +}
  107.29  
  107.30 - out:
  107.31 +void hvm_pci_intx_assert(
  107.32 +    struct domain *d, unsigned int device, unsigned int intx)
  107.33 +{
  107.34 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  107.35 +
  107.36 +    spin_lock(&hvm_irq->lock);
  107.37 +    __hvm_pci_intx_assert(d, device, intx);
  107.38      spin_unlock(&hvm_irq->lock);
  107.39  }
  107.40  
  107.41 -void hvm_pci_intx_deassert(
  107.42 +static void __hvm_pci_intx_deassert(
  107.43      struct domain *d, unsigned int device, unsigned int intx)
  107.44  {
  107.45      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  107.46 @@ -63,10 +68,8 @@ void hvm_pci_intx_deassert(
  107.47  
  107.48      ASSERT((device <= 31) && (intx <= 3));
  107.49  
  107.50 -    spin_lock(&hvm_irq->lock);
  107.51 -
  107.52      if ( !__test_and_clear_bit(device*4 + intx, &hvm_irq->pci_intx) )
  107.53 -        goto out;
  107.54 +        return;
  107.55  
  107.56      gsi = hvm_pci_intx_gsi(device, intx);
  107.57      --hvm_irq->gsi_assert_count[gsi];
  107.58 @@ -76,8 +79,15 @@ void hvm_pci_intx_deassert(
  107.59      if ( (--hvm_irq->pci_link_assert_count[link] == 0) && isa_irq &&
  107.60           (--hvm_irq->gsi_assert_count[isa_irq] == 0) )
  107.61          vpic_irq_negative_edge(d, isa_irq);
  107.62 +}
  107.63  
  107.64 - out:
  107.65 +void hvm_pci_intx_deassert(
  107.66 +    struct domain *d, unsigned int device, unsigned int intx)
  107.67 +{
  107.68 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  107.69 +
  107.70 +    spin_lock(&hvm_irq->lock);
  107.71 +    __hvm_pci_intx_deassert(d, device, intx);
  107.72      spin_unlock(&hvm_irq->lock);
  107.73  }
  107.74  
  107.75 @@ -123,36 +133,47 @@ void hvm_set_callback_irq_level(void)
  107.76      struct vcpu *v = current;
  107.77      struct domain *d = v->domain;
  107.78      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  107.79 -    unsigned int gsi = hvm_irq->callback_gsi;
  107.80 +    unsigned int gsi, pdev, pintx, asserted;
  107.81  
  107.82      /* Fast lock-free tests. */
  107.83 -    if ( (v->vcpu_id != 0) || (gsi == 0) )
  107.84 +    if ( (v->vcpu_id != 0) ||
  107.85 +         (hvm_irq->callback_via_type == HVMIRQ_callback_none) )
  107.86          return;
  107.87  
  107.88      spin_lock(&hvm_irq->lock);
  107.89  
  107.90 -    gsi = hvm_irq->callback_gsi;
  107.91 -    if ( gsi == 0 )
  107.92 +    /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */
  107.93 +    asserted = !!vcpu_info(v, evtchn_upcall_pending);
  107.94 +    if ( hvm_irq->callback_via_asserted == asserted )
  107.95          goto out;
  107.96 +    hvm_irq->callback_via_asserted = asserted;
  107.97  
  107.98 -    if ( local_events_need_delivery() )
  107.99 +    /* Callback status has changed. Update the callback via. */
 107.100 +    switch ( hvm_irq->callback_via_type )
 107.101      {
 107.102 -        if ( !__test_and_set_bit(0, &hvm_irq->callback_irq_wire) &&
 107.103 -             (hvm_irq->gsi_assert_count[gsi]++ == 0) )
 107.104 +    case HVMIRQ_callback_gsi:
 107.105 +        gsi = hvm_irq->callback_via.gsi;
 107.106 +        if ( asserted && (hvm_irq->gsi_assert_count[gsi]++ == 0) )
 107.107          {
 107.108              vioapic_irq_positive_edge(d, gsi);
 107.109              if ( gsi <= 15 )
 107.110                  vpic_irq_positive_edge(d, gsi);
 107.111          }
 107.112 -    }
 107.113 -    else
 107.114 -    {
 107.115 -        if ( __test_and_clear_bit(0, &hvm_irq->callback_irq_wire) &&
 107.116 -             (--hvm_irq->gsi_assert_count[gsi] == 0) )
 107.117 +        else if ( !asserted && (--hvm_irq->gsi_assert_count[gsi] == 0) )
 107.118          {
 107.119              if ( gsi <= 15 )
 107.120                  vpic_irq_negative_edge(d, gsi);
 107.121          }
 107.122 +        break;
 107.123 +    case HVMIRQ_callback_pci_intx:
 107.124 +        pdev  = hvm_irq->callback_via.pci.dev;
 107.125 +        pintx = hvm_irq->callback_via.pci.intx;
 107.126 +        if ( asserted )
 107.127 +            __hvm_pci_intx_assert(d, pdev, pintx);
 107.128 +        else
 107.129 +            __hvm_pci_intx_deassert(d, pdev, pintx);
 107.130 +    default:
 107.131 +        break;
 107.132      }
 107.133  
 107.134   out:
 107.135 @@ -192,40 +213,79 @@ void hvm_set_pci_link_route(struct domai
 107.136              d->domain_id, link, old_isa_irq, isa_irq);
 107.137  }
 107.138  
 107.139 -void hvm_set_callback_gsi(struct domain *d, unsigned int gsi)
 107.140 +void hvm_set_callback_via(struct domain *d, uint64_t via)
 107.141  {
 107.142      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 107.143 -    unsigned int old_gsi;
 107.144 +    unsigned int gsi=0, pdev=0, pintx=0;
 107.145 +    uint8_t via_type;
 107.146  
 107.147 -    if ( gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count) )
 107.148 -        gsi = 0;
 107.149 +    via_type = (uint8_t)(via >> 56) + 1;
 107.150 +    if ( ((via_type == HVMIRQ_callback_gsi) && (via == 0)) ||
 107.151 +         (via_type > HVMIRQ_callback_pci_intx) )
 107.152 +        via_type = HVMIRQ_callback_none;
 107.153  
 107.154      spin_lock(&hvm_irq->lock);
 107.155  
 107.156 -    old_gsi = hvm_irq->callback_gsi;
 107.157 -    if ( old_gsi == gsi )
 107.158 -        goto out;
 107.159 -    hvm_irq->callback_gsi = gsi;
 107.160 -
 107.161 -    if ( !test_bit(0, &hvm_irq->callback_irq_wire) )
 107.162 -        goto out;
 107.163 -
 107.164 -    if ( old_gsi && (--hvm_irq->gsi_assert_count[old_gsi] == 0) )
 107.165 -        if ( old_gsi <= 15 )
 107.166 -            vpic_irq_negative_edge(d, old_gsi);
 107.167 -
 107.168 -    if ( gsi && (hvm_irq->gsi_assert_count[gsi]++ == 0) )
 107.169 +    /* Tear down old callback via. */
 107.170 +    if ( hvm_irq->callback_via_asserted )
 107.171      {
 107.172 -        vioapic_irq_positive_edge(d, gsi);
 107.173 -        if ( gsi <= 15 )
 107.174 -            vpic_irq_positive_edge(d, gsi);
 107.175 +        switch ( hvm_irq->callback_via_type )
 107.176 +        {
 107.177 +        case HVMIRQ_callback_gsi:
 107.178 +            gsi = hvm_irq->callback_via.gsi;
 107.179 +            if ( (--hvm_irq->gsi_assert_count[gsi] == 0) && (gsi <= 15) )
 107.180 +                vpic_irq_negative_edge(d, gsi);
 107.181 +            break;
 107.182 +        case HVMIRQ_callback_pci_intx:
 107.183 +            pdev  = hvm_irq->callback_via.pci.dev;
 107.184 +            pintx = hvm_irq->callback_via.pci.intx;
 107.185 +            __hvm_pci_intx_deassert(d, pdev, pintx);
 107.186 +            break;
 107.187 +        default:
 107.188 +            break;
 107.189 +        }
 107.190      }
 107.191  
 107.192 - out:
 107.193 +    /* Set up new callback via. */
 107.194 +    switch ( hvm_irq->callback_via_type = via_type )
 107.195 +    {
 107.196 +    case HVMIRQ_callback_gsi:
 107.197 +        gsi = hvm_irq->callback_via.gsi = (uint8_t)via;
 107.198 +        if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) )
 107.199 +            hvm_irq->callback_via_type = HVMIRQ_callback_none;
 107.200 +        else if ( hvm_irq->callback_via_asserted &&
 107.201 +                  (hvm_irq->gsi_assert_count[gsi]++ == 0) )
 107.202 +        {
 107.203 +            vioapic_irq_positive_edge(d, gsi);
 107.204 +            if ( gsi <= 15 )
 107.205 +                vpic_irq_positive_edge(d, gsi);
 107.206 +        }
 107.207 +        break;
 107.208 +    case HVMIRQ_callback_pci_intx:
 107.209 +        pdev  = hvm_irq->callback_via.pci.dev  = (uint8_t)(via >> 11) & 31;
 107.210 +        pintx = hvm_irq->callback_via.pci.intx = (uint8_t)via & 3;
 107.211 +        if ( hvm_irq->callback_via_asserted )
 107.212 +             __hvm_pci_intx_assert(d, pdev, pintx);
 107.213 +        break;
 107.214 +    default:
 107.215 +        break;
 107.216 +    }
 107.217 +
 107.218      spin_unlock(&hvm_irq->lock);
 107.219  
 107.220 -    dprintk(XENLOG_G_INFO, "Dom%u callback GSI changed %u -> %u\n",
 107.221 -            d->domain_id, old_gsi, gsi);
 107.222 +    dprintk(XENLOG_G_INFO, "Dom%u callback via changed to ", d->domain_id);
 107.223 +    switch ( via_type )
 107.224 +    {
 107.225 +    case HVMIRQ_callback_gsi:
 107.226 +        printk("GSI %u\n", gsi);
 107.227 +        break;
 107.228 +    case HVMIRQ_callback_pci_intx:
 107.229 +        printk("PCI INTx Dev 0x%02x Int%c\n", pdev, 'A' + pintx);
 107.230 +        break;
 107.231 +    default:
 107.232 +        printk("None\n");
 107.233 +        break;
 107.234 +    }
 107.235  }
 107.236  
 107.237  int cpu_has_pending_irq(struct vcpu *v)
   108.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Jan 18 09:54:33 2007 +0000
   108.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Jan 18 15:18:07 2007 +0000
   108.3 @@ -482,8 +482,8 @@ static int svm_guest_x86_mode(struct vcp
   108.4  {
   108.5      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   108.6  
   108.7 -    if ( vmcb->efer & EFER_LMA )
   108.8 -        return (vmcb->cs.attr.fields.l ? 8 : 4);
   108.9 +    if ( (vmcb->efer & EFER_LMA) && vmcb->cs.attr.fields.l )
  108.10 +        return 8;
  108.11  
  108.12      if ( svm_realmode(v) )
  108.13          return 2;
   109.1 --- a/xen/arch/x86/hvm/vioapic.c	Thu Jan 18 09:54:33 2007 +0000
   109.2 +++ b/xen/arch/x86/hvm/vioapic.c	Thu Jan 18 15:18:07 2007 +0000
   109.3 @@ -309,6 +309,13 @@ static uint32_t ioapic_get_delivery_bitm
   109.4      return mask;
   109.5  }
   109.6  
   109.7 +static inline int pit_channel0_enabled(void)
   109.8 +{
   109.9 +    PITState *pit = &current->domain->arch.hvm_domain.pl_time.vpit;
  109.10 +    struct periodic_time *pt = &pit->channels[0].pt;
  109.11 +    return pt->enabled;
  109.12 +}
  109.13 +
  109.14  static void vioapic_deliver(struct vioapic *vioapic, int irq)
  109.15  {
  109.16      uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
  109.17 @@ -341,7 +348,7 @@ static void vioapic_deliver(struct vioap
  109.18      {
  109.19  #ifdef IRQ0_SPECIAL_ROUTING
  109.20          /* Force round-robin to pick VCPU 0 */
  109.21 -        if ( irq == hvm_isa_irq_to_gsi(0) )
  109.22 +        if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
  109.23          {
  109.24              v = vioapic_domain(vioapic)->vcpu[0];
  109.25              target = v ? vcpu_vlapic(v) : NULL;
  109.26 @@ -374,7 +381,7 @@ static void vioapic_deliver(struct vioap
  109.27              deliver_bitmask &= ~(1 << bit);
  109.28  #ifdef IRQ0_SPECIAL_ROUTING
  109.29              /* Do not deliver timer interrupts to VCPU != 0 */
  109.30 -            if ( irq == hvm_isa_irq_to_gsi(0) )
  109.31 +            if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
  109.32                  v = vioapic_domain(vioapic)->vcpu[0];
  109.33              else
  109.34  #endif
   110.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Jan 18 09:54:33 2007 +0000
   110.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Jan 18 15:18:07 2007 +0000
   110.3 @@ -278,7 +278,14 @@ static void vmx_set_host_env(struct vcpu
   110.4      host_env.tr_base = (unsigned long) &init_tss[cpu];
   110.5      __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
   110.6      __vmwrite(HOST_TR_BASE, host_env.tr_base);
   110.7 -    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
   110.8 +
   110.9 +    /*
  110.10 +     * Skip end of cpu_user_regs when entering the hypervisor because the
  110.11 +     * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc
  110.12 +     * all get saved into the VMCS instead.
  110.13 +     */
  110.14 +    __vmwrite(HOST_RSP,
  110.15 +              (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code);
  110.16  }
  110.17  
  110.18  static void construct_vmcs(struct vcpu *v)
   111.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Jan 18 09:54:33 2007 +0000
   111.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Jan 18 15:18:07 2007 +0000
   111.3 @@ -410,10 +410,6 @@ static void vmx_store_cpu_guest_regs(
   111.4          regs->eflags = __vmread(GUEST_RFLAGS);
   111.5          regs->ss = __vmread(GUEST_SS_SELECTOR);
   111.6          regs->cs = __vmread(GUEST_CS_SELECTOR);
   111.7 -        regs->ds = __vmread(GUEST_DS_SELECTOR);
   111.8 -        regs->es = __vmread(GUEST_ES_SELECTOR);
   111.9 -        regs->gs = __vmread(GUEST_GS_SELECTOR);
  111.10 -        regs->fs = __vmread(GUEST_FS_SELECTOR);
  111.11          regs->eip = __vmread(GUEST_RIP);
  111.12          regs->esp = __vmread(GUEST_RSP);
  111.13      }
  111.14 @@ -429,62 +425,39 @@ static void vmx_store_cpu_guest_regs(
  111.15      vmx_vmcs_exit(v);
  111.16  }
  111.17  
  111.18 -/*
  111.19 - * The VMX spec (section 4.3.1.2, Checks on Guest Segment
  111.20 - * Registers) says that virtual-8086 mode guests' segment
  111.21 - * base-address fields in the VMCS must be equal to their
  111.22 - * corresponding segment selector field shifted right by
  111.23 - * four bits upon vmentry.
  111.24 - *
  111.25 - * This function (called only for VM86-mode guests) fixes
  111.26 - * the bases to be consistent with the selectors in regs
  111.27 - * if they're not already.  Without this, we can fail the
  111.28 - * vmentry check mentioned above.
  111.29 - */
  111.30 -static void fixup_vm86_seg_bases(struct cpu_user_regs *regs)
  111.31 +static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
  111.32  {
  111.33      unsigned long base;
  111.34  
  111.35 -    base = __vmread(GUEST_ES_BASE);
  111.36 -    if (regs->es << 4 != base)
  111.37 -        __vmwrite(GUEST_ES_BASE, regs->es << 4);
  111.38 -    base = __vmread(GUEST_CS_BASE);
  111.39 -    if (regs->cs << 4 != base)
  111.40 -        __vmwrite(GUEST_CS_BASE, regs->cs << 4);
  111.41 -    base = __vmread(GUEST_SS_BASE);
  111.42 -    if (regs->ss << 4 != base)
  111.43 -        __vmwrite(GUEST_SS_BASE, regs->ss << 4);
  111.44 -    base = __vmread(GUEST_DS_BASE);
  111.45 -    if (regs->ds << 4 != base)
  111.46 -        __vmwrite(GUEST_DS_BASE, regs->ds << 4);
  111.47 -    base = __vmread(GUEST_FS_BASE);
  111.48 -    if (regs->fs << 4 != base)
  111.49 -        __vmwrite(GUEST_FS_BASE, regs->fs << 4);
  111.50 -    base = __vmread(GUEST_GS_BASE);
  111.51 -    if (regs->gs << 4 != base)
  111.52 -        __vmwrite(GUEST_GS_BASE, regs->gs << 4);
  111.53 -}
  111.54 -
  111.55 -static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
  111.56 -{
  111.57      vmx_vmcs_enter(v);
  111.58  
  111.59      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
  111.60 -    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
  111.61 -    __vmwrite(GUEST_ES_SELECTOR, regs->es);
  111.62 -    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
  111.63 -    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
  111.64 -
  111.65      __vmwrite(GUEST_RSP, regs->esp);
  111.66  
  111.67      /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */
  111.68      __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL);
  111.69 -    if (regs->eflags & EF_TF)
  111.70 +
  111.71 +    if ( regs->eflags & EF_TF )
  111.72          __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  111.73      else
  111.74          __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  111.75 -    if (regs->eflags & EF_VM)
  111.76 -        fixup_vm86_seg_bases(regs);
  111.77 +
  111.78 +    if ( regs->eflags & EF_VM )
  111.79 +    {
  111.80 +        /*
  111.81 +         * The VMX spec (section 4.3.1.2, Checks on Guest Segment
  111.82 +         * Registers) says that virtual-8086 mode guests' segment
  111.83 +         * base-address fields in the VMCS must be equal to their
  111.84 +         * corresponding segment selector field shifted right by
  111.85 +         * four bits upon vmentry.
  111.86 +         */
  111.87 +        base = __vmread(GUEST_CS_BASE);
  111.88 +        if ( (regs->cs << 4) != base )
  111.89 +            __vmwrite(GUEST_CS_BASE, regs->cs << 4);
  111.90 +        base = __vmread(GUEST_SS_BASE);
  111.91 +        if ( (regs->ss << 4) != base )
  111.92 +            __vmwrite(GUEST_SS_BASE, regs->ss << 4);
  111.93 +    }
  111.94  
  111.95      __vmwrite(GUEST_CS_SELECTOR, regs->cs);
  111.96      __vmwrite(GUEST_RIP, regs->eip);
  111.97 @@ -518,8 +491,7 @@ static unsigned long vmx_get_segment_bas
  111.98      ASSERT(v == current);
  111.99  
 111.100  #ifdef __x86_64__
 111.101 -    if ( vmx_long_mode_enabled(v) &&
 111.102 -         (__vmread(GUEST_CS_AR_BYTES) & (1u<<13)) )
 111.103 +    if ( vmx_long_mode_enabled(v) && (__vmread(GUEST_CS_AR_BYTES) & (1u<<13)) )
 111.104          long_mode = 1;
 111.105  #endif
 111.106  
 111.107 @@ -694,8 +666,8 @@ static int vmx_guest_x86_mode(struct vcp
 111.108  
 111.109      cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
 111.110  
 111.111 -    if ( vmx_long_mode_enabled(v) )
 111.112 -        return ((cs_ar_bytes & (1u<<13)) ? 8 : 4);
 111.113 +    if ( vmx_long_mode_enabled(v) && (cs_ar_bytes & (1u<<13)) )
 111.114 +        return 8;
 111.115  
 111.116      if ( vmx_realmode(v) )
 111.117          return 2;
 111.118 @@ -2251,47 +2223,54 @@ static void vmx_reflect_exception(struct
 111.119      }
 111.120  }
 111.121  
 111.122 +static void vmx_failed_vmentry(unsigned int exit_reason)
 111.123 +{
 111.124 +    unsigned int failed_vmentry_reason = (uint16_t)exit_reason;
 111.125 +    unsigned long exit_qualification;
 111.126 +
 111.127 +    exit_qualification = __vmread(EXIT_QUALIFICATION);
 111.128 +    printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
 111.129 +    switch ( failed_vmentry_reason )
 111.130 +    {
 111.131 +    case EXIT_REASON_INVALID_GUEST_STATE:
 111.132 +        printk("caused by invalid guest state (%ld).\n", exit_qualification);
 111.133 +        break;
 111.134 +    case EXIT_REASON_MSR_LOADING:
 111.135 +        printk("caused by MSR entry %ld loading.\n", exit_qualification);
 111.136 +        break;
 111.137 +    case EXIT_REASON_MACHINE_CHECK:
 111.138 +        printk("caused by machine check.\n");
 111.139 +        break;
 111.140 +    default:
 111.141 +        printk("reason not known yet!");
 111.142 +        break;
 111.143 +    }
 111.144 +
 111.145 +    printk("************* VMCS Area **************\n");
 111.146 +    vmcs_dump_vcpu();
 111.147 +    printk("**************************************\n");
 111.148 +
 111.149 +    domain_crash(current->domain);
 111.150 +}
 111.151 +
 111.152  asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
 111.153  {
 111.154      unsigned int exit_reason;
 111.155      unsigned long exit_qualification, inst_len = 0;
 111.156      struct vcpu *v = current;
 111.157  
 111.158 +    TRACE_3D(TRC_VMX_VMEXIT + v->vcpu_id, 0, 0, 0);
 111.159 +
 111.160      exit_reason = __vmread(VM_EXIT_REASON);
 111.161  
 111.162      perfc_incra(vmexits, exit_reason);
 111.163 +    TRACE_VMEXIT(0, exit_reason);
 111.164  
 111.165      if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
 111.166          local_irq_enable();
 111.167  
 111.168      if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
 111.169 -    {
 111.170 -        unsigned int failed_vmentry_reason = exit_reason & 0xFFFF;
 111.171 -
 111.172 -        exit_qualification = __vmread(EXIT_QUALIFICATION);
 111.173 -        printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
 111.174 -        switch ( failed_vmentry_reason ) {
 111.175 -        case EXIT_REASON_INVALID_GUEST_STATE:
 111.176 -            printk("caused by invalid guest state (%ld).\n", exit_qualification);
 111.177 -            break;
 111.178 -        case EXIT_REASON_MSR_LOADING:
 111.179 -            printk("caused by MSR entry %ld loading.\n", exit_qualification);
 111.180 -            break;
 111.181 -        case EXIT_REASON_MACHINE_CHECK:
 111.182 -            printk("caused by machine check.\n");
 111.183 -            break;
 111.184 -        default:
 111.185 -            printk("reason not known yet!");
 111.186 -            break;
 111.187 -        }
 111.188 -
 111.189 -        printk("************* VMCS Area **************\n");
 111.190 -        vmcs_dump_vcpu();
 111.191 -        printk("**************************************\n");
 111.192 -        goto exit_and_crash;
 111.193 -    }
 111.194 -
 111.195 -    TRACE_VMEXIT(0, exit_reason);
 111.196 +        return vmx_failed_vmentry(exit_reason);
 111.197  
 111.198      switch ( exit_reason )
 111.199      {
 111.200 @@ -2519,11 +2498,6 @@ asmlinkage void vmx_trace_vmentry(void)
 111.201      TRACE_VMEXIT(4, 0);
 111.202  }
 111.203  
 111.204 -asmlinkage void vmx_trace_vmexit (void)
 111.205 -{
 111.206 -    TRACE_3D(TRC_VMX_VMEXIT + current->vcpu_id, 0, 0, 0);
 111.207 -}
 111.208 -
 111.209  /*
 111.210   * Local variables:
 111.211   * mode: C
   112.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Thu Jan 18 09:54:33 2007 +0000
   112.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Thu Jan 18 15:18:07 2007 +0000
   112.3 @@ -29,35 +29,7 @@
   112.4          andl $~3,reg;            \
   112.5          movl (reg),reg;
   112.6  
   112.7 -/*
   112.8 - * At VMExit time the processor saves the guest selectors, esp, eip, 
   112.9 - * and eflags. Therefore we don't save them, but simply decrement 
  112.10 - * the kernel stack pointer to make it consistent with the stack frame 
  112.11 - * at usual interruption time. The eflags of the host is not saved by VMX, 
  112.12 - * and we set it to the fixed value.
  112.13 - *
  112.14 - * We also need the room, especially because orig_eax field is used 
  112.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
  112.16 - *   (10) u32 gs;                 
  112.17 - *   (9)  u32 fs;
  112.18 - *   (8)  u32 ds;
  112.19 - *   (7)  u32 es;
  112.20 - *               <- get_stack_bottom() (= HOST_ESP)
  112.21 - *   (6)  u32 ss;
  112.22 - *   (5)  u32 esp;
  112.23 - *   (4)  u32 eflags;
  112.24 - *   (3)  u32 cs;
  112.25 - *   (2)  u32 eip;
  112.26 - * (2/1)  u16 entry_vector;
  112.27 - * (1/1)  u16 error_code;
  112.28 - * However, get_stack_bottom() actually returns 20 bytes before the real
  112.29 - * bottom of the stack to allow space for:
  112.30 - * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers.
  112.31 - */
  112.32 -
  112.33 -#define NR_SKIPPED_REGS 6 /* See the above explanation */
  112.34  #define HVM_SAVE_ALL_NOSEGREGS                                              \
  112.35 -        subl $(NR_SKIPPED_REGS*4), %esp;                                    \
  112.36          movl $0, 0xc(%esp);  /* XXX why do we need to force eflags==0 ?? */ \
  112.37          pushl %eax;                                                         \
  112.38          pushl %ebp;                                                         \
  112.39 @@ -74,14 +46,11 @@
  112.40          popl %esi;                              \
  112.41          popl %edi;                              \
  112.42          popl %ebp;                              \
  112.43 -        popl %eax;                              \
  112.44 -        addl $(NR_SKIPPED_REGS*4), %esp
  112.45 +        popl %eax
  112.46  
  112.47          ALIGN
  112.48  ENTRY(vmx_asm_vmexit_handler)
  112.49 -        /* selectors are restored/saved by VMX */
  112.50          HVM_SAVE_ALL_NOSEGREGS
  112.51 -        call vmx_trace_vmexit
  112.52          movl %esp,%eax
  112.53          push %eax
  112.54          call vmx_vmexit_handler
   113.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S	Thu Jan 18 09:54:33 2007 +0000
   113.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S	Thu Jan 18 15:18:07 2007 +0000
   113.3 @@ -29,31 +29,7 @@
   113.4          andq $~7,reg;            \
   113.5          movq (reg),reg;
   113.6  
   113.7 -/*
   113.8 - * At VMExit time the processor saves the guest selectors, rsp, rip, 
   113.9 - * and rflags. Therefore we don't save them, but simply decrement 
  113.10 - * the kernel stack pointer to make it consistent with the stack frame 
  113.11 - * at usual interruption time. The rflags of the host is not saved by VMX, 
  113.12 - * and we set it to the fixed value.
  113.13 - *
  113.14 - * We also need the room, especially because orig_eax field is used 
  113.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
  113.16 - *   (10) u64 gs;                 
  113.17 - *   (9)  u64 fs;
  113.18 - *   (8)  u64 ds;
  113.19 - *   (7)  u64 es;
  113.20 - *               <- get_stack_bottom() (= HOST_ESP)
  113.21 - *   (6)  u64 ss;
  113.22 - *   (5)  u64 rsp;
  113.23 - *   (4)  u64 rflags;
  113.24 - *   (3)  u64 cs;
  113.25 - *   (2)  u64 rip;
  113.26 - * (2/1)  u32 entry_vector;
  113.27 - * (1/1)  u32 error_code;
  113.28 - */
  113.29 -#define NR_SKIPPED_REGS 6 /* See the above explanation */
  113.30  #define HVM_SAVE_ALL_NOSEGREGS                  \
  113.31 -        subq $(NR_SKIPPED_REGS*8), %rsp;        \
  113.32          pushq %rdi;                             \
  113.33          pushq %rsi;                             \
  113.34          pushq %rdx;                             \
  113.35 @@ -85,14 +61,11 @@
  113.36          popq %rcx;                              \
  113.37          popq %rdx;                              \
  113.38          popq %rsi;                              \
  113.39 -        popq %rdi;                              \
  113.40 -        addq $(NR_SKIPPED_REGS*8), %rsp;
  113.41 +        popq %rdi
  113.42  
  113.43          ALIGN
  113.44  ENTRY(vmx_asm_vmexit_handler)
  113.45 -        /* selectors are restored/saved by VMX */
  113.46          HVM_SAVE_ALL_NOSEGREGS
  113.47 -        call vmx_trace_vmexit
  113.48          movq %rsp,%rdi
  113.49          call vmx_vmexit_handler
  113.50          jmp vmx_asm_do_vmentry
   114.1 --- a/xen/arch/x86/microcode.c	Thu Jan 18 09:54:33 2007 +0000
   114.2 +++ b/xen/arch/x86/microcode.c	Thu Jan 18 15:18:07 2007 +0000
   114.3 @@ -249,14 +249,14 @@ static int find_matching_ucodes (void)
   114.4  		}
   114.5  
   114.6  		total_size = get_totalsize(&mc_header);
   114.7 -		if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) {
   114.8 +		if (cursor + total_size > user_buffer_size) {
   114.9  			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
  114.10  			error = -EINVAL;
  114.11  			goto out;
  114.12  		}
  114.13  
  114.14  		data_size = get_datasize(&mc_header);
  114.15 -		if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) {
  114.16 +		if (data_size + MC_HEADER_SIZE > total_size) {
  114.17  			printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
  114.18  			error = -EINVAL;
  114.19  			goto out;
  114.20 @@ -459,11 +459,6 @@ int microcode_update(XEN_GUEST_HANDLE(vo
  114.21  {
  114.22  	int ret;
  114.23  
  114.24 -	if (len < DEFAULT_UCODE_TOTALSIZE) {
  114.25 -		printk(KERN_ERR "microcode: not enough data\n");
  114.26 -		return -EINVAL;
  114.27 -	}
  114.28 -
  114.29  	if (len != (typeof(user_buffer_size))len) {
  114.30  		printk(KERN_ERR "microcode: too much data\n");
  114.31  		return -E2BIG;
   115.1 --- a/xen/arch/x86/mm.c	Thu Jan 18 09:54:33 2007 +0000
   115.2 +++ b/xen/arch/x86/mm.c	Thu Jan 18 15:18:07 2007 +0000
   115.3 @@ -154,6 +154,15 @@ l2_pgentry_t *compat_idle_pg_table_l2 = 
   115.4  #define l3_disallow_mask(d) L3_DISALLOW_MASK
   115.5  #endif
   115.6  
   115.7 +static void queue_deferred_ops(struct domain *d, unsigned int ops)
   115.8 +{
   115.9 +    if ( d == current->domain )
  115.10 +        this_cpu(percpu_mm_info).deferred_ops |= ops;
  115.11 +    else
  115.12 +        BUG_ON(!test_bit(_DOMF_paused, &d->domain_flags) ||
  115.13 +               !cpus_empty(d->domain_dirty_cpumask));
  115.14 +}
  115.15 +
  115.16  void __init init_frametable(void)
  115.17  {
  115.18      unsigned long nr_pages, page_step, i, mfn;
  115.19 @@ -416,8 +425,7 @@ void invalidate_shadow_ldt(struct vcpu *
  115.20      }
  115.21  
  115.22      /* Dispose of the (now possibly invalid) mappings from the TLB.  */
  115.23 -    ASSERT(v->processor == smp_processor_id());
  115.24 -    this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_TLB | DOP_RELOAD_LDT;
  115.25 +    queue_deferred_ops(v->domain, DOP_FLUSH_TLB | DOP_RELOAD_LDT);
  115.26  }
  115.27  
  115.28  
  115.29 @@ -826,7 +834,7 @@ static void put_page_from_l2e(l2_pgentry
  115.30  {
  115.31      if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && 
  115.32           (l2e_get_pfn(l2e) != pfn) )
  115.33 -        put_page_and_type(mfn_to_page(l2e_get_pfn(l2e)));
  115.34 +        put_page_and_type(l2e_get_page(l2e));
  115.35  }
  115.36  
  115.37  
  115.38 @@ -835,7 +843,7 @@ static void put_page_from_l3e(l3_pgentry
  115.39  {
  115.40      if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && 
  115.41           (l3e_get_pfn(l3e) != pfn) )
  115.42 -        put_page_and_type(mfn_to_page(l3e_get_pfn(l3e)));
  115.43 +        put_page_and_type(l3e_get_page(l3e));
  115.44  }
  115.45  #endif
  115.46  
  115.47 @@ -844,7 +852,7 @@ static void put_page_from_l4e(l4_pgentry
  115.48  {
  115.49      if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && 
  115.50           (l4e_get_pfn(l4e) != pfn) )
  115.51 -        put_page_and_type(mfn_to_page(l4e_get_pfn(l4e)));
  115.52 +        put_page_and_type(l4e_get_page(l4e));
  115.53  }
  115.54  #endif
  115.55  
  115.56 @@ -945,7 +953,8 @@ static int create_pae_xen_mappings(struc
  115.57      }
  115.58  #else
  115.59      memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)],
  115.60 -           &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
  115.61 +           &compat_idle_pg_table_l2[
  115.62 +               l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
  115.63             COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e));
  115.64  #endif
  115.65      unmap_domain_page(pl2e);
  115.66 @@ -1376,7 +1385,7 @@ static int mod_l2_entry(l2_pgentry_t *pl
  115.67          if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT))
  115.68              return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current);
  115.69  
  115.70 -        if ( unlikely(!get_page_from_l2e(nl2e, pfn, current->domain)) )
  115.71 +        if ( unlikely(!get_page_from_l2e(nl2e, pfn, d)) )
  115.72              return 0;
  115.73  
  115.74          if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current)) )
  115.75 @@ -1439,7 +1448,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
  115.76          if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT))
  115.77              return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current);
  115.78  
  115.79 -        if ( unlikely(!get_page_from_l3e(nl3e, pfn, current->domain)) )
  115.80 +        if ( unlikely(!get_page_from_l3e(nl3e, pfn, d)) )
  115.81              return 0;
  115.82  
  115.83          if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current)) )
  115.84 @@ -1561,7 +1570,7 @@ void free_page_type(struct page_info *pa
  115.85           * (e.g., update_va_mapping()) or we could end up modifying a page
  115.86           * that is no longer a page table (and hence screw up ref counts).
  115.87           */
  115.88 -        this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_ALL_TLBS;
  115.89 +        queue_deferred_ops(owner, DOP_FLUSH_ALL_TLBS);
  115.90  
  115.91          if ( unlikely(shadow_mode_enabled(owner)) )
  115.92          {
  115.93 @@ -1759,24 +1768,14 @@ int new_guest_cr3(unsigned long mfn)
  115.94      int okay;
  115.95      unsigned long old_base_mfn;
  115.96  
  115.97 -    if ( is_hvm_domain(d) && !hvm_paging_enabled(v) )
  115.98 -        return 0;
  115.99 -
 115.100  #ifdef CONFIG_COMPAT
 115.101      if ( IS_COMPAT(d) )
 115.102      {
 115.103 -        l4_pgentry_t l4e = l4e_from_pfn(mfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
 115.104 -
 115.105 -        if ( shadow_mode_refcounts(d) )
 115.106 -        {
 115.107 -            okay = get_page_from_pagenr(mfn, d);
 115.108 -            old_base_mfn = l4e_get_pfn(l4e);
 115.109 -            if ( okay && old_base_mfn )
 115.110 -                put_page(mfn_to_page(old_base_mfn));
 115.111 -        }
 115.112 -        else
 115.113 -            okay = mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)),
 115.114 -                                l4e, 0);
 115.115 +        okay = shadow_mode_refcounts(d)
 115.116 +            ? 0 /* Old code was broken, but what should it be? */
 115.117 +            : mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)),
 115.118 +                           l4e_from_pfn(mfn, (_PAGE_PRESENT|_PAGE_RW|
 115.119 +                                              _PAGE_USER|_PAGE_ACCESSED)), 0);
 115.120          if ( unlikely(!okay) )
 115.121          {
 115.122              MEM_LOG("Error while installing new compat baseptr %lx", mfn);
 115.123 @@ -1789,41 +1788,13 @@ int new_guest_cr3(unsigned long mfn)
 115.124          return 1;
 115.125      }
 115.126  #endif
 115.127 -    if ( shadow_mode_refcounts(d) )
 115.128 -    {
 115.129 -        okay = get_page_from_pagenr(mfn, d);
 115.130 -        if ( unlikely(!okay) )
 115.131 -        {
 115.132 -            MEM_LOG("Error while installing new baseptr %lx", mfn);
 115.133 -            return 0;
 115.134 -        }
 115.135 -    }
 115.136 -    else
 115.137 +    okay = shadow_mode_refcounts(d)
 115.138 +        ? get_page_from_pagenr(mfn, d)
 115.139 +        : get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
 115.140 +    if ( unlikely(!okay) )
 115.141      {
 115.142 -        okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
 115.143 -        if ( unlikely(!okay) )
 115.144 -        {
 115.145 -            /* Switch to idle pagetable: this VCPU has no active p.t. now. */
 115.146 -            MEM_LOG("New baseptr %lx: slow path via idle pagetables", mfn);
 115.147 -            old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
 115.148 -            v->arch.guest_table = pagetable_null();
 115.149 -            update_cr3(v);
 115.150 -            write_cr3(__pa(idle_pg_table));
 115.151 -            if ( old_base_mfn != 0 )
 115.152 -                put_page_and_type(mfn_to_page(old_base_mfn));
 115.153 -
 115.154 -            /* Retry the validation with no active p.t. for this VCPU. */
 115.155 -            okay = get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
 115.156 -            if ( !okay )
 115.157 -            {
 115.158 -                /* Failure here is unrecoverable: the VCPU has no pagetable! */
 115.159 -                MEM_LOG("Fatal error while installing new baseptr %lx", mfn);
 115.160 -                domain_crash(d);
 115.161 -                ASSERT(v->processor == smp_processor_id());
 115.162 -                this_cpu(percpu_mm_info).deferred_ops = 0;
 115.163 -                return 0;
 115.164 -            }
 115.165 -        }
 115.166 +        MEM_LOG("Error while installing new baseptr %lx", mfn);
 115.167 +        return 0;
 115.168      }
 115.169  
 115.170      invalidate_shadow_ldt(v);
 115.171 @@ -1831,7 +1802,7 @@ int new_guest_cr3(unsigned long mfn)
 115.172      old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
 115.173  
 115.174      v->arch.guest_table = pagetable_from_pfn(mfn);
 115.175 -    update_cr3(v); /* update shadow_table and cr3 fields of vcpu struct */
 115.176 +    update_cr3(v);
 115.177  
 115.178      write_ptbase(v);
 115.179  
 115.180 @@ -3182,7 +3153,7 @@ static int ptwr_emulated_update(
 115.181      unsigned int do_cmpxchg,
 115.182      struct ptwr_emulate_ctxt *ptwr_ctxt)
 115.183  {
 115.184 -    unsigned long gmfn, mfn;
 115.185 +    unsigned long mfn;
 115.186      struct page_info *page;
 115.187      l1_pgentry_t pte, ol1e, nl1e, *pl1e;
 115.188      struct vcpu *v = current;
 115.189 @@ -3222,8 +3193,7 @@ static int ptwr_emulated_update(
 115.190      }
 115.191  
 115.192      pte  = ptwr_ctxt->pte;
 115.193 -    gmfn = l1e_get_pfn(pte);
 115.194 -    mfn  = gmfn_to_mfn(d, gmfn);
 115.195 +    mfn  = l1e_get_pfn(pte);
 115.196      page = mfn_to_page(mfn);
 115.197  
 115.198      /* We are looking only for read-only mappings of p.t. pages. */
 115.199 @@ -3237,15 +3207,14 @@ static int ptwr_emulated_update(
 115.200      if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
 115.201      {
 115.202          if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) &&
 115.203 -             (bytes == 4) &&
 115.204 -             !do_cmpxchg &&
 115.205 +             (bytes == 4) && (addr & 4) && !do_cmpxchg &&
 115.206               (l1e_get_flags(nl1e) & _PAGE_PRESENT) )
 115.207          {
 115.208              /*
 115.209 -             * If this is a half-write to a PAE PTE then we assume that the
 115.210 -             * guest has simply got the two writes the wrong way round. We
 115.211 -             * zap the PRESENT bit on the assumption the bottom half will be
 115.212 -             * written immediately after we return to the guest.
 115.213 +             * If this is an upper-half write to a PAE PTE then we assume that
 115.214 +             * the guest has simply got the two writes the wrong way round. We
 115.215 +             * zap the PRESENT bit on the assumption that the bottom half will
 115.216 +             * be written immediately after we return to the guest.
 115.217               */
 115.218              MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte,
 115.219                      l1e_get_intpte(nl1e));
 115.220 @@ -3354,7 +3323,6 @@ int ptwr_do_page_fault(struct vcpu *v, u
 115.221                         struct cpu_user_regs *regs)
 115.222  {
 115.223      struct domain *d = v->domain;
 115.224 -    unsigned long     pfn;
 115.225      struct page_info *page;
 115.226      l1_pgentry_t      pte;
 115.227      struct ptwr_emulate_ctxt ptwr_ctxt;
 115.228 @@ -3368,8 +3336,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
 115.229      guest_get_eff_l1e(v, addr, &pte);
 115.230      if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
 115.231          goto bail;
 115.232 -    pfn  = l1e_get_pfn(pte);
 115.233 -    page = mfn_to_page(pfn);
 115.234 +    page = l1e_get_page(pte);
 115.235  
 115.236      /* We are looking only for read-only mappings of p.t. pages. */
 115.237      if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||
 115.238 @@ -3378,8 +3345,9 @@ int ptwr_do_page_fault(struct vcpu *v, u
 115.239           (page_get_owner(page) != d) )
 115.240          goto bail;
 115.241  
 115.242 -    ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
 115.243 -    ptwr_ctxt.ctxt.address_bytes = IS_COMPAT(d) ? 4 : sizeof(long);
 115.244 +    ptwr_ctxt.ctxt.regs = regs;
 115.245 +    ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size =
 115.246 +        IS_COMPAT(d) ? 32 : BITS_PER_LONG;
 115.247      ptwr_ctxt.cr2 = addr;
 115.248      ptwr_ctxt.pte = pte;
 115.249      if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
   116.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Jan 18 09:54:33 2007 +0000
   116.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Jan 18 15:18:07 2007 +0000
   116.3 @@ -110,7 +110,7 @@ static int hvm_translate_linear_addr(
   116.4      unsigned long limit, addr = offset;
   116.5      uint32_t last_byte;
   116.6  
   116.7 -    if ( sh_ctxt->ctxt.address_bytes != 8 )
   116.8 +    if ( sh_ctxt->ctxt.addr_size != 64 )
   116.9      {
  116.10          /*
  116.11           * COMPATIBILITY MODE: Apply segment checks and add base.
  116.12 @@ -399,7 +399,7 @@ static struct x86_emulate_ops pv_shadow_
  116.13  struct x86_emulate_ops *shadow_init_emulation(
  116.14      struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs)
  116.15  {
  116.16 -    struct segment_register *creg;
  116.17 +    struct segment_register *creg, *sreg;
  116.18      struct vcpu *v = current;
  116.19      unsigned long addr;
  116.20  
  116.21 @@ -407,7 +407,7 @@ struct x86_emulate_ops *shadow_init_emul
  116.22  
  116.23      if ( !is_hvm_vcpu(v) )
  116.24      {
  116.25 -        sh_ctxt->ctxt.address_bytes = sizeof(long);
  116.26 +        sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = BITS_PER_LONG;
  116.27          return &pv_shadow_emulator_ops;
  116.28      }
  116.29  
  116.30 @@ -416,12 +416,20 @@ struct x86_emulate_ops *shadow_init_emul
  116.31      creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt);
  116.32  
  116.33      /* Work out the emulation mode. */
  116.34 -    if ( hvm_long_mode_enabled(v) )
  116.35 -        sh_ctxt->ctxt.address_bytes = creg->attr.fields.l ? 8 : 4;
  116.36 +    if ( hvm_long_mode_enabled(v) && creg->attr.fields.l )
  116.37 +    {
  116.38 +        sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = 64;
  116.39 +    }
  116.40      else if ( regs->eflags & X86_EFLAGS_VM )
  116.41 -        sh_ctxt->ctxt.address_bytes = 2;
  116.42 +    {
  116.43 +        sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = 16;
  116.44 +    }
  116.45      else
  116.46 -        sh_ctxt->ctxt.address_bytes = creg->attr.fields.db ? 4 : 2;
  116.47 +    {
  116.48 +        sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
  116.49 +        sh_ctxt->ctxt.addr_size = creg->attr.fields.db ? 32 : 16;
  116.50 +        sh_ctxt->ctxt.sp_size   = sreg->attr.fields.db ? 32 : 16;
  116.51 +    }
  116.52  
  116.53      /* Attempt to prefetch whole instruction. */
  116.54      sh_ctxt->insn_buf_bytes =
  116.55 @@ -1303,6 +1311,9 @@ shadow_alloc_p2m_table(struct domain *d)
  116.56      if ( !shadow_set_p2m_entry(d, gfn, mfn) )
  116.57          goto error;
  116.58  
  116.59 +    /* Build a p2m map that matches the m2p entries for this domain's
  116.60 +     * allocated pages.  Skip any pages that have an explicitly invalid
  116.61 +     * or obviously bogus m2p entry. */
  116.62      for ( entry = d->page_list.next;
  116.63            entry != &d->page_list;
  116.64            entry = entry->next )
  116.65 @@ -1318,6 +1329,8 @@ shadow_alloc_p2m_table(struct domain *d)
  116.66              (gfn != 0x55555555L)
  116.67  #endif
  116.68               && gfn != INVALID_M2P_ENTRY
  116.69 +             && (gfn < 
  116.70 +                 (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof (l1_pgentry_t))
  116.71               && !shadow_set_p2m_entry(d, gfn, mfn) )
  116.72              goto error;
  116.73      }
   117.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Jan 18 09:54:33 2007 +0000
   117.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Jan 18 15:18:07 2007 +0000
   117.3 @@ -851,9 +851,7 @@ static inline void safe_write_entry(void
   117.4       * then writing the high word before the low word. */
   117.5      BUILD_BUG_ON(sizeof (shadow_l1e_t) != 2 * sizeof (unsigned long));
   117.6      d[0] = 0;
   117.7 -    wmb();
   117.8      d[1] = s[1];
   117.9 -    wmb();
  117.10      d[0] = s[0];
  117.11  #else
  117.12      /* In 32-bit and 64-bit, sizeof(pte) == sizeof(ulong) == 1 word,
  117.13 @@ -3946,7 +3944,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
  117.14      if ( !skip ) sh_validate_guest_pt_write(v, mfn, addr, bytes);
  117.15  
  117.16      /* If we are writing zeros to this page, might want to unshadow */
  117.17 -    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) )
  117.18 +    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) )
  117.19          check_for_early_unshadow(v, mfn);
  117.20  
  117.21      sh_unmap_domain_page(addr);
  117.22 @@ -3998,7 +3996,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
  117.23                    vaddr, prev, old, new, *(unsigned long *)addr, bytes);
  117.24  
  117.25      /* If we are writing zeros to this page, might want to unshadow */
  117.26 -    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) )
  117.27 +    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) )
  117.28          check_for_early_unshadow(v, mfn);
  117.29  
  117.30      sh_unmap_domain_page(addr);
   118.1 --- a/xen/arch/x86/mm/shadow/private.h	Thu Jan 18 09:54:33 2007 +0000
   118.2 +++ b/xen/arch/x86/mm/shadow/private.h	Thu Jan 18 15:18:07 2007 +0000
   118.3 @@ -427,6 +427,11 @@ extern int sh_remove_write_access(struct
   118.4  #undef mfn_valid
   118.5  #define mfn_valid(_mfn) (mfn_x(_mfn) < max_page)
   118.6  
   118.7 +#if GUEST_PAGING_LEVELS >= 3
   118.8 +# define is_lo_pte(_vaddr) (((_vaddr)&0x4)==0)
   118.9 +#else
  118.10 +# define is_lo_pte(_vaddr) (1)
  118.11 +#endif
  118.12  
  118.13  static inline int
  118.14  sh_mfn_is_a_page_table(mfn_t gmfn)
   119.1 --- a/xen/arch/x86/oprofile/nmi_int.c	Thu Jan 18 09:54:33 2007 +0000
   119.2 +++ b/xen/arch/x86/oprofile/nmi_int.c	Thu Jan 18 15:18:07 2007 +0000
   119.3 @@ -42,7 +42,7 @@ extern int is_profiled(struct domain *d)
   119.4  extern size_t strlcpy(char *dest, const char *src, size_t size);
   119.5  
   119.6  
   119.7 -int nmi_callback(struct cpu_user_regs *regs, int cpu)
   119.8 +static int nmi_callback(struct cpu_user_regs *regs, int cpu)
   119.9  {
  119.10  	int xen_mode, ovf;
  119.11  
   120.1 --- a/xen/arch/x86/setup.c	Thu Jan 18 09:54:33 2007 +0000
   120.2 +++ b/xen/arch/x86/setup.c	Thu Jan 18 15:18:07 2007 +0000
   120.3 @@ -411,6 +411,23 @@ void __init __start_xen(multiboot_info_t
   120.4          printk("WARNING: Buggy e820 map detected and fixed "
   120.5                 "(truncated length fields).\n");
   120.6  
   120.7 +    /* Ensure that all E820 RAM regions are page-aligned and -sized. */
   120.8 +    for ( i = 0; i < e820_raw_nr; i++ )
   120.9 +    {
  120.10 +        uint64_t s, e;
  120.11 +        if ( e820_raw[i].type != E820_RAM )
  120.12 +            continue;
  120.13 +        s = PFN_UP(e820_raw[i].addr);
  120.14 +        e = PFN_DOWN(e820_raw[i].addr + e820_raw[i].size);
  120.15 +        e820_raw[i].size = 0; /* discarded later */
  120.16 +        if ( s < e )
  120.17 +        {
  120.18 +            e820_raw[i].addr = s << PAGE_SHIFT;
  120.19 +            e820_raw[i].size = (e - s) << PAGE_SHIFT;
  120.20 +        }
  120.21 +    }
  120.22 +
  120.23 +    /* Sanitise the raw E820 map to produce a final clean version. */
  120.24      max_page = init_e820(e820_raw, &e820_raw_nr);
  120.25  
  120.26      modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
  120.27 @@ -423,7 +440,7 @@ void __init __start_xen(multiboot_info_t
  120.28              printk("Not enough memory to stash the DOM0 kernel image.\n");
  120.29              for ( ; ; ) ;
  120.30          }
  120.31 -        
  120.32 +
  120.33          if ( (e820.map[i].type == E820_RAM) &&
  120.34               (e820.map[i].size >= modules_length) &&
  120.35               ((e820.map[i].addr + e820.map[i].size) >=
  120.36 @@ -474,10 +491,10 @@ void __init __start_xen(multiboot_info_t
  120.37              start = PFN_UP(e820.map[i].addr);
  120.38              end   = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
  120.39              /* Clip the range to exclude what the bootstrapper initialised. */
  120.40 -            if ( end < init_mapped )
  120.41 -                continue;
  120.42              if ( start < init_mapped )
  120.43                  start = init_mapped;
  120.44 +            if ( end <= start )
  120.45 +                continue;
  120.46              /* Request the mapping. */
  120.47              map_pages_to_xen(
  120.48                  PAGE_OFFSET + (start << PAGE_SHIFT),
  120.49 @@ -486,7 +503,7 @@ void __init __start_xen(multiboot_info_t
  120.50  #endif
  120.51      }
  120.52  
  120.53 -    if ( kexec_crash_area.size > 0 )
  120.54 +    if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0)
  120.55      {
  120.56          unsigned long kdump_start, kdump_size, k;
  120.57  
   121.1 --- a/xen/arch/x86/traps.c	Thu Jan 18 09:54:33 2007 +0000
   121.2 +++ b/xen/arch/x86/traps.c	Thu Jan 18 15:18:07 2007 +0000
   121.3 @@ -1121,7 +1121,7 @@ static int emulate_privileged_op(struct 
   121.4  {
   121.5      struct vcpu *v = current;
   121.6      unsigned long *reg, eip = regs->eip, res;
   121.7 -    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0;
   121.8 +    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
   121.9      enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
  121.10      unsigned int port, i, data_sel, ar, data, rc;
  121.11      unsigned int op_bytes, op_default, ad_bytes, ad_default;
  121.12 @@ -1184,6 +1184,7 @@ static int emulate_privileged_op(struct 
  121.13              data_sel = regs->ss;
  121.14              continue;
  121.15          case 0xf0: /* LOCK */
  121.16 +            lock = 1;
  121.17              continue;
  121.18          case 0xf2: /* REPNE/REPNZ */
  121.19          case 0xf3: /* REP/REPE/REPZ */
  121.20 @@ -1210,6 +1211,9 @@ static int emulate_privileged_op(struct 
  121.21      if ( opcode == 0x0f )
  121.22          goto twobyte_opcode;
  121.23      
  121.24 +    if ( lock )
  121.25 +        goto fail;
  121.26 +
  121.27      /* Input/Output String instructions. */
  121.28      if ( (opcode >= 0x6c) && (opcode <= 0x6f) )
  121.29      {
  121.30 @@ -1472,6 +1476,8 @@ static int emulate_privileged_op(struct 
  121.31  
  121.32      /* Privileged (ring 0) instructions. */
  121.33      opcode = insn_fetch(u8, code_base, eip, code_limit);
  121.34 +    if ( lock && (opcode & ~3) != 0x20 )
  121.35 +        goto fail;
  121.36      switch ( opcode )
  121.37      {
  121.38      case 0x06: /* CLTS */
  121.39 @@ -1490,7 +1496,7 @@ static int emulate_privileged_op(struct 
  121.40  
  121.41      case 0x20: /* MOV CR?,<reg> */
  121.42          opcode = insn_fetch(u8, code_base, eip, code_limit);
  121.43 -        modrm_reg |= (opcode >> 3) & 7;
  121.44 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
  121.45          modrm_rm  |= (opcode >> 0) & 7;
  121.46          reg = decode_register(modrm_rm, regs, 0);
  121.47          switch ( modrm_reg )
  121.48 @@ -1530,7 +1536,7 @@ static int emulate_privileged_op(struct 
  121.49  
  121.50      case 0x21: /* MOV DR?,<reg> */
  121.51          opcode = insn_fetch(u8, code_base, eip, code_limit);
  121.52 -        modrm_reg |= (opcode >> 3) & 7;
  121.53 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
  121.54          modrm_rm  |= (opcode >> 0) & 7;
  121.55          reg = decode_register(modrm_rm, regs, 0);
  121.56          if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 )
  121.57 @@ -1540,7 +1546,7 @@ static int emulate_privileged_op(struct 
  121.58  
  121.59      case 0x22: /* MOV <reg>,CR? */
  121.60          opcode = insn_fetch(u8, code_base, eip, code_limit);
  121.61 -        modrm_reg |= (opcode >> 3) & 7;
  121.62 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
  121.63          modrm_rm  |= (opcode >> 0) & 7;
  121.64          reg = decode_register(modrm_rm, regs, 0);
  121.65          switch ( modrm_reg )
  121.66 @@ -1588,7 +1594,7 @@ static int emulate_privileged_op(struct 
  121.67  
  121.68      case 0x23: /* MOV <reg>,DR? */
  121.69          opcode = insn_fetch(u8, code_base, eip, code_limit);
  121.70 -        modrm_reg |= (opcode >> 3) & 7;
  121.71 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
  121.72          modrm_rm  |= (opcode >> 0) & 7;
  121.73          reg = decode_register(modrm_rm, regs, 0);
  121.74          if ( do_set_debugreg(modrm_reg, *reg) != 0 )
  121.75 @@ -1854,7 +1860,7 @@ static int dummy_nmi_callback(struct cpu
  121.76  }
  121.77   
  121.78  static nmi_callback_t nmi_callback = dummy_nmi_callback;
  121.79 - 
  121.80 +
  121.81  asmlinkage void do_nmi(struct cpu_user_regs *regs)
  121.82  {
  121.83      unsigned int cpu = smp_processor_id();
   122.1 --- a/xen/arch/x86/x86_64/compat/mm.c	Thu Jan 18 09:54:33 2007 +0000
   122.2 +++ b/xen/arch/x86/x86_64/compat/mm.c	Thu Jan 18 15:18:07 2007 +0000
   122.3 @@ -1,6 +1,7 @@
   122.4  #ifdef CONFIG_COMPAT
   122.5  
   122.6  #include <xen/event.h>
   122.7 +#include <xen/multicall.h>
   122.8  #include <compat/memory.h>
   122.9  #include <compat/xen.h>
  122.10  
  122.11 @@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
  122.12              if ( err == __HYPERVISOR_mmuext_op )
  122.13              {
  122.14                  struct cpu_user_regs *regs = guest_cpu_user_regs();
  122.15 -                unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED;
  122.16 +                struct mc_state *mcs = &this_cpu(mc_state);
  122.17 +                unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags)
  122.18 +                                    ? regs->ecx
  122.19 +                                    : mcs->call.args[1];
  122.20 +                unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
  122.21  
  122.22 -                BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED));
  122.23 +                BUG_ON(left == arg1);
  122.24                  BUG_ON(left > count);
  122.25                  guest_handle_add_offset(nat_ops, count - left);
  122.26                  BUG_ON(left + i < count);
  122.27                  guest_handle_add_offset(cmp_uops, (signed int)(count - left - i));
  122.28                  left = 1;
  122.29                  BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
  122.30 -                BUG_ON(left != regs->ecx);
  122.31 -                regs->ecx += count - i;
  122.32 +                BUG_ON(left != arg1);
  122.33 +                if (!test_bit(_MCSF_in_multicall, &mcs->flags))
  122.34 +                    regs->_ecx += count - i;
  122.35 +                else
  122.36 +                    mcs->compat_call.args[1] += count - i;
  122.37              }
  122.38              else
  122.39 -                BUG_ON(rc > 0);
  122.40 +                BUG_ON(err > 0);
  122.41              rc = err;
  122.42          }
  122.43  
   123.1 --- a/xen/arch/x86/x86_emulate.c	Thu Jan 18 09:54:33 2007 +0000
   123.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Jan 18 15:18:07 2007 +0000
   123.3 @@ -3,7 +3,21 @@
   123.4   * 
   123.5   * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
   123.6   * 
   123.7 - * Copyright (c) 2005 Keir Fraser
   123.8 + * Copyright (c) 2005-2007 Keir Fraser
   123.9 + * 
  123.10 + * This program is free software; you can redistribute it and/or modify
  123.11 + * it under the terms of the GNU General Public License as published by
  123.12 + * the Free Software Foundation; either version 2 of the License, or
  123.13 + * (at your option) any later version.
  123.14 + * 
  123.15 + * This program is distributed in the hope that it will be useful,
  123.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  123.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  123.18 + * GNU General Public License for more details.
  123.19 + * 
  123.20 + * You should have received a copy of the GNU General Public License
  123.21 + * along with this program; if not, write to the Free Software
  123.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  123.23   */
  123.24  
  123.25  #ifndef __XEN__
  123.26 @@ -33,9 +47,8 @@
  123.27  #define SrcReg      (1<<3) /* Register operand. */
  123.28  #define SrcMem      (2<<3) /* Memory operand. */
  123.29  #define SrcMem16    (3<<3) /* Memory operand (16-bit). */
  123.30 -#define SrcMem32    (4<<3) /* Memory operand (32-bit). */
  123.31 -#define SrcImm      (5<<3) /* Immediate operand. */
  123.32 -#define SrcImmByte  (6<<3) /* 8-bit sign-extended immediate operand. */
  123.33 +#define SrcImm      (4<<3) /* Immediate operand. */
  123.34 +#define SrcImmByte  (5<<3) /* 8-bit sign-extended immediate operand. */
  123.35  #define SrcMask     (7<<3)
  123.36  /* Generic ModRM decode. */
  123.37  #define ModRM       (1<<6)
  123.38 @@ -62,19 +75,19 @@ static uint8_t opcode_table[256] = {
  123.39      /* 0x20 - 0x27 */
  123.40      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
  123.41      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
  123.42 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0,
  123.43 +    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
  123.44      /* 0x28 - 0x2F */
  123.45      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
  123.46      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
  123.47 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0,
  123.48 +    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
  123.49      /* 0x30 - 0x37 */
  123.50      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
  123.51      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
  123.52 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0,
  123.53 +    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
  123.54      /* 0x38 - 0x3F */
  123.55      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
  123.56      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
  123.57 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0,
  123.58 +    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
  123.59      /* 0x40 - 0x4F */
  123.60      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.61      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.62 @@ -85,9 +98,13 @@ static uint8_t opcode_table[256] = {
  123.63      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
  123.64      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
  123.65      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
  123.66 -    /* 0x60 - 0x6F */
  123.67 -    0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */,
  123.68 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  123.69 +    /* 0x60 - 0x67 */
  123.70 +    ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcMem16|ModRM|Mov,
  123.71 +    0, 0, 0, 0,
  123.72 +    /* 0x68 - 0x6F */
  123.73 +    ImplicitOps|Mov, DstMem|SrcImm|ModRM|Mov,
  123.74 +    ImplicitOps|Mov, DstMem|SrcImmByte|ModRM|Mov,
  123.75 +    0, 0, 0, 0,
  123.76      /* 0x70 - 0x77 */
  123.77      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.78      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.79 @@ -107,13 +124,14 @@ static uint8_t opcode_table[256] = {
  123.80      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.81      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  123.82      /* 0x98 - 0x9F */
  123.83 -    0, 0, 0, 0, 0, 0, 0, 0,
  123.84 +    ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps,
  123.85      /* 0xA0 - 0xA7 */
  123.86      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
  123.87      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
  123.88      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0,
  123.89      /* 0xA8 - 0xAF */
  123.90 -    0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
  123.91 +    ByteOp|DstReg|SrcImm, DstReg|SrcImm,
  123.92 +    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
  123.93      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0,
  123.94      /* 0xB0 - 0xB7 */
  123.95      ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
  123.96 @@ -124,20 +142,21 @@ static uint8_t opcode_table[256] = {
  123.97      DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
  123.98      DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
  123.99      /* 0xC0 - 0xC7 */
 123.100 -    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
 123.101 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
 123.102 +    ImplicitOps, ImplicitOps,
 123.103      0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
 123.104      /* 0xC8 - 0xCF */
 123.105      0, 0, 0, 0, 0, 0, 0, 0,
 123.106      /* 0xD0 - 0xD7 */
 123.107      ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
 123.108      ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
 123.109 -    0, 0, 0, 0,
 123.110 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 123.111      /* 0xD8 - 0xDF */
 123.112      0, 0, 0, 0, 0, 0, 0, 0,
 123.113      /* 0xE0 - 0xE7 */
 123.114 -    0, 0, 0, ImplicitOps, 0, 0, 0, 0,
 123.115 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0,
 123.116      /* 0xE8 - 0xEF */
 123.117 -    0, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
 123.118 +    ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
 123.119      /* 0xF0 - 0xF7 */
 123.120      0, 0, 0, 0,
 123.121      0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
 123.122 @@ -149,8 +168,11 @@ static uint8_t opcode_table[256] = {
 123.123  static uint8_t twobyte_table[256] = {
 123.124      /* 0x00 - 0x0F */
 123.125      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
 123.126 -    /* 0x10 - 0x1F */
 123.127 -    0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0,
 123.128 +    /* 0x10 - 0x17 */
 123.129 +    0, 0, 0, 0, 0, 0, 0, 0,
 123.130 +    /* 0x18 - 0x1F */
 123.131 +    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
 123.132 +    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
 123.133      /* 0x20 - 0x2F */
 123.134      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 123.135      /* 0x30 - 0x3F */
 123.136 @@ -177,24 +199,34 @@ static uint8_t twobyte_table[256] = {
 123.137      /* 0x88 - 0x8F */
 123.138      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 123.139      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 123.140 -    /* 0x90 - 0x9F */
 123.141 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 123.142 +    /* 0x90 - 0x97 */
 123.143 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.144 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.145 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.146 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.147 +    /* 0x98 - 0x9F */
 123.148 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.149 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.150 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.151 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
 123.152      /* 0xA0 - 0xA7 */
 123.153      0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0, 
 123.154      /* 0xA8 - 0xAF */
 123.155 -    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0,
 123.156 +    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, DstReg|SrcMem|ModRM,
 123.157      /* 0xB0 - 0xB7 */
 123.158      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
 123.159      0, DstBitBase|SrcReg|ModRM,
 123.160      0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
 123.161      /* 0xB8 - 0xBF */
 123.162      0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
 123.163 -    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
 123.164 +    DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
 123.165 +    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
 123.166      /* 0xC0 - 0xC7 */
 123.167      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
 123.168      0, 0, 0, ImplicitOps|ModRM,
 123.169      /* 0xC8 - 0xCF */
 123.170 -    0, 0, 0, 0, 0, 0, 0, 0,
 123.171 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 123.172 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 123.173      /* 0xD0 - 0xDF */
 123.174      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 123.175      /* 0xE0 - 0xEF */
 123.176 @@ -205,7 +237,7 @@ static uint8_t twobyte_table[256] = {
 123.177  
 123.178  /* Type, address-of, and value of an instruction's operand. */
 123.179  struct operand {
 123.180 -    enum { OP_REG, OP_MEM, OP_IMM } type;
 123.181 +    enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
 123.182      unsigned int  bytes;
 123.183      unsigned long val, orig_val;
 123.184      union {
 123.185 @@ -228,6 +260,12 @@ struct operand {
 123.186  #define EFLG_PF (1<<2)
 123.187  #define EFLG_CF (1<<0)
 123.188  
 123.189 +/* Exception definitions. */
 123.190 +#define EXC_DE  0
 123.191 +#define EXC_BR  5
 123.192 +#define EXC_UD  6
 123.193 +#define EXC_GP 13
 123.194 +
 123.195  /*
 123.196   * Instruction emulation:
 123.197   * Most instructions are emulated directly via a fragment of inline assembly
 123.198 @@ -285,7 +323,8 @@ do{ unsigned long _tmp;                 
 123.199              _op"w %"_wx"3,%1; "                                            \
 123.200              _POST_EFLAGS("0","4","2")                                      \
 123.201              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.202 -            : _wy ((_src).val), "i" (EFLAGS_MASK) );                       \
 123.203 +            : _wy ((_src).val), "i" (EFLAGS_MASK),                         \
 123.204 +              "m" (_eflags), "m" ((_dst).val) );                           \
 123.205          break;                                                             \
 123.206      case 4:                                                                \
 123.207          __asm__ __volatile__ (                                             \
 123.208 @@ -293,7 +332,8 @@ do{ unsigned long _tmp;                 
 123.209              _op"l %"_lx"3,%1; "                                            \
 123.210              _POST_EFLAGS("0","4","2")                                      \
 123.211              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.212 -            : _ly ((_src).val), "i" (EFLAGS_MASK) );                       \
 123.213 +            : _ly ((_src).val), "i" (EFLAGS_MASK),                         \
 123.214 +              "m" (_eflags), "m" ((_dst).val) );                           \
 123.215          break;                                                             \
 123.216      case 8:                                                                \
 123.217          __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy);           \
 123.218 @@ -310,7 +350,8 @@ do{ unsigned long _tmp;                 
 123.219              _op"b %"_bx"3,%1; "                                            \
 123.220              _POST_EFLAGS("0","4","2")                                      \
 123.221              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.222 -            : _by ((_src).val), "i" (EFLAGS_MASK) );                       \
 123.223 +            : _by ((_src).val), "i" (EFLAGS_MASK),                         \
 123.224 +              "m" (_eflags), "m" ((_dst).val) );                           \
 123.225          break;                                                             \
 123.226      default:                                                               \
 123.227          __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\
 123.228 @@ -341,7 +382,7 @@ do{ unsigned long _tmp;                 
 123.229              _op"b %1; "                                                    \
 123.230              _POST_EFLAGS("0","3","2")                                      \
 123.231              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.232 -            : "i" (EFLAGS_MASK) );                                         \
 123.233 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
 123.234          break;                                                             \
 123.235      case 2:                                                                \
 123.236          __asm__ __volatile__ (                                             \
 123.237 @@ -349,7 +390,7 @@ do{ unsigned long _tmp;                 
 123.238              _op"w %1; "                                                    \
 123.239              _POST_EFLAGS("0","3","2")                                      \
 123.240              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.241 -            : "i" (EFLAGS_MASK) );                                         \
 123.242 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
 123.243          break;                                                             \
 123.244      case 4:                                                                \
 123.245          __asm__ __volatile__ (                                             \
 123.246 @@ -357,7 +398,7 @@ do{ unsigned long _tmp;                 
 123.247              _op"l %1; "                                                    \
 123.248              _POST_EFLAGS("0","3","2")                                      \
 123.249              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
 123.250 -            : "i" (EFLAGS_MASK) );                                         \
 123.251 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
 123.252          break;                                                             \
 123.253      case 8:                                                                \
 123.254          __emulate_1op_8byte(_op, _dst, _eflags);                           \
 123.255 @@ -373,7 +414,8 @@ do{ __asm__ __volatile__ (              
 123.256          _op"q %"_qx"3,%1; "                                             \
 123.257          _POST_EFLAGS("0","4","2")                                       \
 123.258          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
 123.259 -        : _qy ((_src).val), "i" (EFLAGS_MASK) );                        \
 123.260 +        : _qy ((_src).val), "i" (EFLAGS_MASK),                          \
 123.261 +          "m" (_eflags), "m" ((_dst).val) );                            \
 123.262  } while (0)
 123.263  #define __emulate_1op_8byte(_op, _dst, _eflags)                         \
 123.264  do{ __asm__ __volatile__ (                                              \
 123.265 @@ -381,7 +423,7 @@ do{ __asm__ __volatile__ (              
 123.266          _op"q %1; "                                                     \
 123.267          _POST_EFLAGS("0","3","2")                                       \
 123.268          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
 123.269 -        : "i" (EFLAGS_MASK) );                                          \
 123.270 +        : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );         \
 123.271  } while (0)
 123.272  #elif defined(__i386__)
 123.273  #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
 123.274 @@ -390,39 +432,70 @@ do{ __asm__ __volatile__ (              
 123.275  
 123.276  /* Fetch next part of the instruction being emulated. */
 123.277  #define insn_fetch_bytes(_size)                                         \
 123.278 -({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes);      \
 123.279 +({ unsigned long _x, _eip = _regs.eip;                                  \
 123.280     if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
 123.281 +   _regs.eip += (_size); /* real hardware doesn't truncate */           \
 123.282 +   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
 123.283 +                         EXC_GP);                                       \
 123.284     rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
 123.285     if ( rc ) goto done;                                                 \
 123.286 -   _regs.eip += (_size); /* real hardware doesn't truncate */           \
 123.287     _x;                                                                  \
 123.288  })
 123.289  #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
 123.290  
 123.291 -#define _truncate_ea(ea, byte_width)                    \
 123.292 -({  unsigned long __ea = (ea);                          \
 123.293 -    (((byte_width) == sizeof(unsigned long)) ? __ea :   \
 123.294 -     (__ea & ((1UL << ((byte_width) << 3)) - 1)));      \
 123.295 +#define _truncate_ea(ea, byte_width)            \
 123.296 +({  unsigned long __ea = (ea);                  \
 123.297 +    unsigned int _width = (byte_width);         \
 123.298 +    ((_width == sizeof(unsigned long)) ? __ea : \
 123.299 +     (__ea & ((1UL << (_width << 3)) - 1)));    \
 123.300  })
 123.301  #define truncate_ea(ea) _truncate_ea((ea), ad_bytes)
 123.302  
 123.303  #define mode_64bit() (def_ad_bytes == 8)
 123.304  
 123.305 +#define fail_if(p)                              \
 123.306 +do {                                            \
 123.307 +    rc = (p) ? X86EMUL_UNHANDLEABLE : 0;        \
 123.308 +    if ( rc ) goto done;                        \
 123.309 +} while (0)
 123.310 +
 123.311 +/* In future we will be able to generate arbitrary exceptions. */
 123.312 +#define generate_exception_if(p, e) fail_if(p)
 123.313 +
 123.314 +/* Given byte has even parity (even number of 1s)? */
 123.315 +static int even_parity(uint8_t v)
 123.316 +{
 123.317 +    __asm__ ( "test %%al,%%al; setp %%al"
 123.318 +              : "=a" (v) : "0" (v) );
 123.319 +    return v;
 123.320 +}
 123.321 +
 123.322  /* Update address held in a register, based on addressing mode. */
 123.323  #define _register_address_increment(reg, inc, byte_width)               \
 123.324  do {                                                                    \
 123.325      int _inc = (inc); /* signed type ensures sign extension to long */  \
 123.326 -    if ( (byte_width) == sizeof(unsigned long) )                        \
 123.327 +    unsigned int _width = (byte_width);                                 \
 123.328 +    if ( _width == sizeof(unsigned long) )                              \
 123.329          (reg) += _inc;                                                  \
 123.330      else if ( mode_64bit() )                                            \
 123.331 -        (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1);    \
 123.332 +        (reg) = ((reg) + _inc) & ((1UL << (_width << 3)) - 1);          \
 123.333      else                                                                \
 123.334 -        (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) |         \
 123.335 -                (((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1));  \
 123.336 +        (reg) = ((reg) & ~((1UL << (_width << 3)) - 1)) |               \
 123.337 +                (((reg) + _inc) & ((1UL << (_width << 3)) - 1));        \
 123.338  } while (0)
 123.339  #define register_address_increment(reg, inc) \
 123.340      _register_address_increment((reg), (inc), ad_bytes)
 123.341  
 123.342 +#define sp_pre_dec(dec) ({                                              \
 123.343 +    _register_address_increment(_regs.esp, -(dec), ctxt->sp_size/8);    \
 123.344 +    _truncate_ea(_regs.esp, ctxt->sp_size/8);                           \
 123.345 +})
 123.346 +#define sp_post_inc(inc) ({                                             \
 123.347 +    unsigned long __esp = _truncate_ea(_regs.esp, ctxt->sp_size/8);     \
 123.348 +    _register_address_increment(_regs.esp, (inc), ctxt->sp_size/8);     \
 123.349 +    __esp;                                                              \
 123.350 +})
 123.351 +
 123.352  #define jmp_rel(rel)                                                    \
 123.353  do {                                                                    \
 123.354      _regs.eip += (int)(rel);                                            \
 123.355 @@ -431,6 +504,92 @@ do {                                    
 123.356                       ? (uint16_t)_regs.eip : (uint32_t)_regs.eip);      \
 123.357  } while (0)
 123.358  
 123.359 +/*
 123.360 + * Unsigned multiplication with double-word result.
 123.361 + * IN:  Multiplicand=m[0], Multiplier=m[1]
 123.362 + * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
 123.363 + */
 123.364 +static int mul_dbl(unsigned long m[2])
 123.365 +{
 123.366 +    int rc;
 123.367 +    asm ( "mul %4; seto %b2"
 123.368 +          : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
 123.369 +          : "0" (m[0]), "1" (m[1]), "2" (0) );
 123.370 +    return rc;
 123.371 +}
 123.372 +
 123.373 +/*
 123.374 + * Signed multiplication with double-word result.
 123.375 + * IN:  Multiplicand=m[0], Multiplier=m[1]
 123.376 + * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
 123.377 + */
 123.378 +static int imul_dbl(unsigned long m[2])
 123.379 +{
 123.380 +    int rc;
 123.381 +    asm ( "imul %4; seto %b2"
 123.382 +          : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
 123.383 +          : "0" (m[0]), "1" (m[1]), "2" (0) );
 123.384 +    return rc;
 123.385 +}
 123.386 +
 123.387 +/*
 123.388 + * Unsigned division of double-word dividend.
 123.389 + * IN:  Dividend=u[1]:u[0], Divisor=v
 123.390 + * OUT: Return 1: #DE
 123.391 + *      Return 0: Quotient=u[0], Remainder=u[1]
 123.392 + */
 123.393 +static int div_dbl(unsigned long u[2], unsigned long v)
 123.394 +{
 123.395 +    if ( (v == 0) || (u[1] > v) || ((u[1] == v) && (u[0] != 0)) )
 123.396 +        return 1;
 123.397 +    asm ( "div %4"
 123.398 +          : "=a" (u[0]), "=d" (u[1])
 123.399 +          : "0" (u[0]), "1" (u[1]), "r" (v) );
 123.400 +    return 0;
 123.401 +}
 123.402 +
 123.403 +/*
 123.404 + * Signed division of double-word dividend.
 123.405 + * IN:  Dividend=u[1]:u[0], Divisor=v
 123.406 + * OUT: Return 1: #DE
 123.407 + *      Return 0: Quotient=u[0], Remainder=u[1]
 123.408 + * NB. We don't use idiv directly as it's moderately hard to work out
 123.409 + *     ahead of time whether it will #DE, which we cannot allow to happen.
 123.410 + */
 123.411 +static int idiv_dbl(unsigned long u[2], unsigned long v)
 123.412 +{
 123.413 +    int negu = (long)u[1] < 0, negv = (long)v < 0;
 123.414 +
 123.415 +    /* u = abs(u) */
 123.416 +    if ( negu )
 123.417 +    {
 123.418 +        u[1] = ~u[1];
 123.419 +        if ( (u[0] = -u[0]) == 0 )
 123.420 +            u[1]++;
 123.421 +    }
 123.422 +
 123.423 +    /* abs(u) / abs(v) */
 123.424 +    if ( div_dbl(u, negv ? -v : v) )
 123.425 +        return 1;
 123.426 +
 123.427 +    /* Remainder has same sign as dividend. It cannot overflow. */
 123.428 +    if ( negu )
 123.429 +        u[1] = -u[1];
 123.430 +
 123.431 +    /* Quotient is overflowed if sign bit is set. */
 123.432 +    if ( negu ^ negv )
 123.433 +    {
 123.434 +        if ( (long)u[0] >= 0 )
 123.435 +            u[0] = -u[0];
 123.436 +        else if ( (u[0] << 1) != 0 ) /* == 0x80...0 is okay */
 123.437 +            return 1;
 123.438 +    }
 123.439 +    else if ( (long)u[0] < 0 )
 123.440 +        return 1;
 123.441 +
 123.442 +    return 0;
 123.443 +}
 123.444 +
 123.445  static int
 123.446  test_cc(
 123.447      unsigned int condition, unsigned int flags)
 123.448 @@ -519,8 +678,8 @@ x86_emulate(
 123.449  
 123.450      uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
 123.451      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
 123.452 -    unsigned int op_bytes, ad_bytes, def_ad_bytes;
 123.453 -    unsigned int lock_prefix = 0, rep_prefix = 0, i;
 123.454 +    unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
 123.455 +    unsigned int lock_prefix = 0, rep_prefix = 0;
 123.456      int rc = 0;
 123.457      struct operand src, dst;
 123.458  
 123.459 @@ -532,28 +691,25 @@ x86_emulate(
 123.460      ea.mem.seg = x86_seg_ds;
 123.461      ea.mem.off = 0;
 123.462  
 123.463 -    op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes;
 123.464 +    op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8;
 123.465      if ( op_bytes == 8 )
 123.466      {
 123.467 -        op_bytes = 4;
 123.468 +        op_bytes = def_op_bytes = 4;
 123.469  #ifndef __x86_64__
 123.470          return -1;
 123.471  #endif
 123.472      }
 123.473  
 123.474      /* Prefix bytes. */
 123.475 -    for ( i = 0; i < 8; i++ )
 123.476 +    for ( ; ; )
 123.477      {
 123.478          switch ( b = insn_fetch_type(uint8_t) )
 123.479          {
 123.480          case 0x66: /* operand-size override */
 123.481 -            op_bytes ^= 6;      /* switch between 2/4 bytes */
 123.482 +            op_bytes = def_op_bytes ^ 6;
 123.483              break;
 123.484          case 0x67: /* address-size override */
 123.485 -            if ( mode_64bit() )
 123.486 -                ad_bytes ^= 12; /* switch between 4/8 bytes */
 123.487 -            else
 123.488 -                ad_bytes ^= 6;  /* switch between 2/4 bytes */
 123.489 +            ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
 123.490              break;
 123.491          case 0x2e: /* CS override */
 123.492              ea.mem.seg = x86_seg_cs;
 123.493 @@ -614,6 +770,9 @@ x86_emulate(
 123.494              goto cannot_emulate;
 123.495      }
 123.496  
 123.497 +    /* Lock prefix is allowed only on RMW instructions. */
 123.498 +    generate_exception_if((d & Mov) && lock_prefix, EXC_GP);
 123.499 +
 123.500      /* ModRM and SIB bytes. */
 123.501      if ( d & ModRM )
 123.502      {
 123.503 @@ -746,9 +905,6 @@ x86_emulate(
 123.504      case SrcMem16:
 123.505          ea.bytes = 2;
 123.506          goto srcmem_common;
 123.507 -    case SrcMem32:
 123.508 -        ea.bytes = 4;
 123.509 -        goto srcmem_common;
 123.510      case SrcMem:
 123.511          ea.bytes = (d & ByteOp) ? 1 : op_bytes;
 123.512      srcmem_common:
 123.513 @@ -817,7 +973,7 @@ x86_emulate(
 123.514          {
 123.515              /*
 123.516               * EA       += BitOffset DIV op_bytes*8
 123.517 -             * BitOffset = BitOffset MOD op_byte*8
 123.518 +             * BitOffset = BitOffset MOD op_bytes*8
 123.519               * DIV truncates towards negative infinity.
 123.520               * MOD always produces a positive result.
 123.521               */
 123.522 @@ -853,13 +1009,18 @@ x86_emulate(
 123.523              case 8: dst.val = *(uint64_t *)dst.reg; break;
 123.524              }
 123.525          }
 123.526 -        else if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
 123.527 -                  (rc = ops->read(dst.mem.seg, dst.mem.off,
 123.528 -                                  &dst.val, dst.bytes, ctxt)) )
 123.529 -            goto done;
 123.530 +        else if ( !(d & Mov) ) /* optimisation - avoid slow emulated read */
 123.531 +        {
 123.532 +            if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
 123.533 +                                 &dst.val, dst.bytes, ctxt)) )
 123.534 +                goto done;
 123.535 +            dst.orig_val = dst.val;
 123.536 +        }
 123.537          break;
 123.538      }
 123.539 -    dst.orig_val = dst.val;
 123.540 +
 123.541 +    /* LOCK prefix allowed only on instructions with memory destination. */
 123.542 +    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP);
 123.543  
 123.544      if ( twobyte )
 123.545          goto twobyte_insn;
 123.546 @@ -868,67 +1029,136 @@ x86_emulate(
 123.547      {
 123.548      case 0x04 ... 0x05: /* add imm,%%eax */
 123.549          dst.reg = (unsigned long *)&_regs.eax;
 123.550 -        dst.val = dst.orig_val = _regs.eax;
 123.551 +        dst.val = _regs.eax;
 123.552      case 0x00 ... 0x03: add: /* add */
 123.553          emulate_2op_SrcV("add", src, dst, _regs.eflags);
 123.554          break;
 123.555  
 123.556      case 0x0c ... 0x0d: /* or imm,%%eax */
 123.557          dst.reg = (unsigned long *)&_regs.eax;
 123.558 -        dst.val = dst.orig_val = _regs.eax;
 123.559 +        dst.val = _regs.eax;
 123.560      case 0x08 ... 0x0b: or:  /* or */
 123.561          emulate_2op_SrcV("or", src, dst, _regs.eflags);
 123.562          break;
 123.563  
 123.564      case 0x14 ... 0x15: /* adc imm,%%eax */
 123.565          dst.reg = (unsigned long *)&_regs.eax;
 123.566 -        dst.val = dst.orig_val = _regs.eax;
 123.567 +        dst.val = _regs.eax;
 123.568      case 0x10 ... 0x13: adc: /* adc */
 123.569          emulate_2op_SrcV("adc", src, dst, _regs.eflags);
 123.570          break;
 123.571  
 123.572      case 0x1c ... 0x1d: /* sbb imm,%%eax */
 123.573          dst.reg = (unsigned long *)&_regs.eax;
 123.574 -        dst.val = dst.orig_val = _regs.eax;
 123.575 +        dst.val = _regs.eax;
 123.576      case 0x18 ... 0x1b: sbb: /* sbb */
 123.577          emulate_2op_SrcV("sbb", src, dst, _regs.eflags);
 123.578          break;
 123.579  
 123.580      case 0x24 ... 0x25: /* and imm,%%eax */
 123.581          dst.reg = (unsigned long *)&_regs.eax;
 123.582 -        dst.val = dst.orig_val = _regs.eax;
 123.583 +        dst.val = _regs.eax;
 123.584      case 0x20 ... 0x23: and: /* and */
 123.585          emulate_2op_SrcV("and", src, dst, _regs.eflags);
 123.586          break;
 123.587  
 123.588      case 0x2c ... 0x2d: /* sub imm,%%eax */
 123.589          dst.reg = (unsigned long *)&_regs.eax;
 123.590 -        dst.val = dst.orig_val = _regs.eax;
 123.591 +        dst.val = _regs.eax;
 123.592      case 0x28 ... 0x2b: sub: /* sub */
 123.593          emulate_2op_SrcV("sub", src, dst, _regs.eflags);
 123.594          break;
 123.595  
 123.596      case 0x34 ... 0x35: /* xor imm,%%eax */
 123.597          dst.reg = (unsigned long *)&_regs.eax;
 123.598 -        dst.val = dst.orig_val = _regs.eax;
 123.599 +        dst.val = _regs.eax;
 123.600      case 0x30 ... 0x33: xor: /* xor */
 123.601          emulate_2op_SrcV("xor", src, dst, _regs.eflags);
 123.602          break;
 123.603  
 123.604      case 0x3c ... 0x3d: /* cmp imm,%%eax */
 123.605          dst.reg = (unsigned long *)&_regs.eax;
 123.606 -        dst.val = dst.orig_val = _regs.eax;
 123.607 +        dst.val = _regs.eax;
 123.608      case 0x38 ... 0x3b: cmp: /* cmp */
 123.609          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
 123.610          break;
 123.611  
 123.612 -    case 0x63: /* movsxd */
 123.613 -        if ( !mode_64bit() )
 123.614 -            goto cannot_emulate;
 123.615 -        dst.val = (int32_t)src.val;
 123.616 +    case 0x62: /* bound */ {
 123.617 +        unsigned long src_val2;
 123.618 +        int lb, ub, idx;
 123.619 +        generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD);
 123.620 +        if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes,
 123.621 +                             &src_val2, op_bytes, ctxt)) )
 123.622 +            goto done;
 123.623 +        ub  = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
 123.624 +        lb  = (op_bytes == 2) ? (int16_t)src.val  : (int32_t)src.val;
 123.625 +        idx = (op_bytes == 2) ? (int16_t)dst.val  : (int32_t)dst.val;
 123.626 +        generate_exception_if((idx < lb) || (idx > ub), EXC_BR);
 123.627 +        dst.type = OP_NONE;
 123.628 +        break;
 123.629 +    }
 123.630 +
 123.631 +    case 0x63: /* movsxd (x86/64) / arpl (x86/32) */
 123.632 +        if ( mode_64bit() )
 123.633 +        {
 123.634 +            /* movsxd */
 123.635 +            if ( src.type == OP_REG )
 123.636 +                src.val = *(int32_t *)src.reg;
 123.637 +            else if ( (rc = ops->read(src.mem.seg, src.mem.off,
 123.638 +                                      &src.val, 4, ctxt)) )
 123.639 +                goto done;
 123.640 +            dst.val = (int32_t)src.val;
 123.641 +        }
 123.642 +        else
 123.643 +        {
 123.644 +            /* arpl */
 123.645 +            uint16_t src_val = dst.val;
 123.646 +            dst = src;
 123.647 +            _regs.eflags &= ~EFLG_ZF;
 123.648 +            _regs.eflags |= ((src_val & 3) > (dst.val & 3)) ? EFLG_ZF : 0;
 123.649 +            if ( _regs.eflags & EFLG_ZF )
 123.650 +                dst.val  = (dst.val & ~3) | (src_val & 3);
 123.651 +            else
 123.652 +                dst.type = OP_NONE;
 123.653 +        }
 123.654          break;
 123.655  
 123.656 -    case 0x80 ... 0x83: /* Grp1 */
 123.657 +    case 0x69: /* imul imm16/32 */
 123.658 +    case 0x6b: /* imul imm8 */ {
 123.659 +        unsigned long reg = *(long *)decode_register(modrm_reg, &_regs, 0);
 123.660 +        _regs.eflags &= ~(EFLG_OF|EFLG_CF);
 123.661 +        switch ( dst.bytes )
 123.662 +        {
 123.663 +        case 2:
 123.664 +            dst.val = ((uint32_t)(int16_t)src.val *
 123.665 +                       (uint32_t)(int16_t)reg);
 123.666 +            if ( (int16_t)dst.val != (uint32_t)dst.val )
 123.667 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 123.668 +            break;
 123.669 +#ifdef __x86_64__
 123.670 +        case 4:
 123.671 +            dst.val = ((uint64_t)(int32_t)src.val *
 123.672 +                       (uint64_t)(int32_t)reg);
 123.673 +            if ( (int32_t)dst.val != dst.val )
 123.674 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 123.675 +            break;
 123.676 +#endif
 123.677 +        default: {
 123.678 +            unsigned long m[2] = { src.val, reg };
 123.679 +            if ( imul_dbl(m) )
 123.680 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 123.681 +            dst.val = m[0];
 123.682 +            break;
 123.683 +        }
 123.684 +        }
 123.685 +        dst.type = OP_REG;
 123.686 +        dst.reg  = decode_register(modrm_reg, &_regs, 0);
 123.687 +        break;
 123.688 +    }
 123.689 +
 123.690 +    case 0x82: /* Grp1 (x86/32 only) */
 123.691 +        generate_exception_if(mode_64bit(), EXC_UD);
 123.692 +    case 0x80: case 0x81: case 0x83: /* Grp1 */
 123.693          switch ( modrm_reg & 7 )
 123.694          {
 123.695          case 0: goto add;
 123.696 @@ -942,6 +1172,9 @@ x86_emulate(
 123.697          }
 123.698          break;
 123.699  
 123.700 +    case 0xa8 ... 0xa9: /* test imm,%%eax */
 123.701 +        dst.reg = (unsigned long *)&_regs.eax;
 123.702 +        dst.val = _regs.eax;
 123.703      case 0x84 ... 0x85: test: /* test */
 123.704          emulate_2op_SrcV("test", src, dst, _regs.eflags);
 123.705          break;
 123.706 @@ -960,8 +1193,9 @@ x86_emulate(
 123.707          lock_prefix = 1;
 123.708          break;
 123.709  
 123.710 +    case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
 123.711 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
 123.712      case 0x88 ... 0x8b: /* mov */
 123.713 -    case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
 123.714          dst.val = src.val;
 123.715          break;
 123.716  
 123.717 @@ -970,13 +1204,13 @@ x86_emulate(
 123.718          break;
 123.719  
 123.720      case 0x8f: /* pop (sole member of Grp1a) */
 123.721 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
 123.722          /* 64-bit mode: POP defaults to a 64-bit operand. */
 123.723          if ( mode_64bit() && (dst.bytes == 4) )
 123.724              dst.bytes = 8;
 123.725 -        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
 123.726 +        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes),
 123.727                               &dst.val, dst.bytes, ctxt)) != 0 )
 123.728              goto done;
 123.729 -        register_address_increment(_regs.esp, dst.bytes);
 123.730          break;
 123.731  
 123.732      case 0xb0 ... 0xb7: /* mov imm8,r8 */
 123.733 @@ -1051,12 +1285,191 @@ x86_emulate(
 123.734          case 3: /* neg */
 123.735              emulate_1op("neg", dst, _regs.eflags);
 123.736              break;
 123.737 +        case 4: /* mul */
 123.738 +            src = dst;
 123.739 +            dst.type = OP_REG;
 123.740 +            dst.reg  = (unsigned long *)&_regs.eax;
 123.741 +            dst.val  = *dst.reg;
 123.742 +            _regs.eflags &= ~(EFLG_OF|EFLG_CF);
 123.743 +            switch ( src.bytes )
 123.744 +            {
 123.745 +            case 1:
 123.746 +                dst.val *= src.val;
 123.747 +                if ( (uint8_t)dst.val != (uint16_t)dst.val )
 123.748 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.749 +                break;
 123.750 +            case 2:
 123.751 +                dst.val *= src.val;
 123.752 +                if ( (uint16_t)dst.val != (uint32_t)dst.val )
 123.753 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.754 +                *(uint16_t *)&_regs.edx = dst.val >> 16;
 123.755 +                break;
 123.756 +#ifdef __x86_64__
 123.757 +            case 4:
 123.758 +                dst.val *= src.val;
 123.759 +                if ( (uint32_t)dst.val != dst.val )
 123.760 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.761 +                _regs.edx = (uint32_t)(dst.val >> 32);
 123.762 +                break;
 123.763 +#endif
 123.764 +            default: {
 123.765 +                unsigned long m[2] = { src.val, dst.val };
 123.766 +                if ( mul_dbl(m) )
 123.767 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.768 +                _regs.edx = m[1];
 123.769 +                dst.val  = m[0];
 123.770 +                break;
 123.771 +            }
 123.772 +            }
 123.773 +            break;
 123.774 +        case 5: /* imul */
 123.775 +            src = dst;
 123.776 +            dst.type = OP_REG;
 123.777 +            dst.reg  = (unsigned long *)&_regs.eax;
 123.778 +            dst.val  = *dst.reg;
 123.779 +            _regs.eflags &= ~(EFLG_OF|EFLG_CF);
 123.780 +            switch ( src.bytes )
 123.781 +            {
 123.782 +            case 1:
 123.783 +                dst.val = ((uint16_t)(int8_t)src.val *
 123.784 +                           (uint16_t)(int8_t)dst.val);
 123.785 +                if ( (int8_t)dst.val != (uint16_t)dst.val )
 123.786 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.787 +                break;
 123.788 +            case 2:
 123.789 +                dst.val = ((uint32_t)(int16_t)src.val *
 123.790 +                           (uint32_t)(int16_t)dst.val);
 123.791 +                if ( (int16_t)dst.val != (uint32_t)dst.val )
 123.792 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.793 +                *(uint16_t *)&_regs.edx = dst.val >> 16;
 123.794 +                break;
 123.795 +#ifdef __x86_64__
 123.796 +            case 4:
 123.797 +                dst.val = ((uint64_t)(int32_t)src.val *
 123.798 +                           (uint64_t)(int32_t)dst.val);
 123.799 +                if ( (int32_t)dst.val != dst.val )
 123.800 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.801 +                _regs.edx = (uint32_t)(dst.val >> 32);
 123.802 +                break;
 123.803 +#endif
 123.804 +            default: {
 123.805 +                unsigned long m[2] = { src.val, dst.val };
 123.806 +                if ( imul_dbl(m) )
 123.807 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
 123.808 +                _regs.edx = m[1];
 123.809 +                dst.val  = m[0];
 123.810 +                break;
 123.811 +            }
 123.812 +            }
 123.813 +            break;
 123.814 +        case 6: /* div */ {
 123.815 +            unsigned long u[2], v;
 123.816 +            src = dst;
 123.817 +            dst.type = OP_REG;
 123.818 +            dst.reg  = (unsigned long *)&_regs.eax;
 123.819 +            switch ( src.bytes )
 123.820 +            {
 123.821 +            case 1:
 123.822 +                u[0] = (uint16_t)_regs.eax;
 123.823 +                u[1] = 0;
 123.824 +                v    = (uint8_t)src.val;
 123.825 +                generate_exception_if(
 123.826 +                    div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]),
 123.827 +                    EXC_DE);
 123.828 +                dst.val = (uint8_t)u[0];
 123.829 +                ((uint8_t *)&_regs.eax)[1] = u[1];
 123.830 +                break;
 123.831 +            case 2:
 123.832 +                u[0] = ((uint32_t)_regs.edx << 16) | (uint16_t)_regs.eax;
 123.833 +                u[1] = 0;
 123.834 +                v    = (uint16_t)src.val;
 123.835 +                generate_exception_if(
 123.836 +                    div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]),
 123.837 +                    EXC_DE);
 123.838 +                dst.val = (uint16_t)u[0];
 123.839 +                *(uint16_t *)&_regs.edx = u[1];
 123.840 +                break;
 123.841 +#ifdef __x86_64__
 123.842 +            case 4:
 123.843 +                u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
 123.844 +                u[1] = 0;
 123.845 +                v    = (uint32_t)src.val;
 123.846 +                generate_exception_if(
 123.847 +                    div_dbl(u, v) || ((uint32_t)u[0] != u[0]),
 123.848 +                    EXC_DE);
 123.849 +                dst.val   = (uint32_t)u[0];
 123.850 +                _regs.edx = (uint32_t)u[1];
 123.851 +                break;
 123.852 +#endif
 123.853 +            default:
 123.854 +                u[0] = _regs.eax;
 123.855 +                u[1] = _regs.edx;
 123.856 +                v    = src.val;
 123.857 +                generate_exception_if(div_dbl(u, v), EXC_DE);
 123.858 +                dst.val   = u[0];
 123.859 +                _regs.edx = u[1];
 123.860 +                break;
 123.861 +            }
 123.862 +            break;
 123.863 +        }
 123.864 +        case 7: /* idiv */ {
 123.865 +            unsigned long u[2], v;
 123.866 +            src = dst;
 123.867 +            dst.type = OP_REG;
 123.868 +            dst.reg  = (unsigned long *)&_regs.eax;
 123.869 +            switch ( src.bytes )
 123.870 +            {
 123.871 +            case 1:
 123.872 +                u[0] = (int16_t)_regs.eax;
 123.873 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
 123.874 +                v    = (int8_t)src.val;
 123.875 +                generate_exception_if(
 123.876 +                    idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]),
 123.877 +                    EXC_DE);
 123.878 +                dst.val = (int8_t)u[0];
 123.879 +                ((int8_t *)&_regs.eax)[1] = u[1];
 123.880 +                break;
 123.881 +            case 2:
 123.882 +                u[0] = (int32_t)((_regs.edx << 16) | (uint16_t)_regs.eax);
 123.883 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
 123.884 +                v    = (int16_t)src.val;
 123.885 +                generate_exception_if(
 123.886 +                    idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]),
 123.887 +                    EXC_DE);
 123.888 +                dst.val = (int16_t)u[0];
 123.889 +                *(int16_t *)&_regs.edx = u[1];
 123.890 +                break;
 123.891 +#ifdef __x86_64__
 123.892 +            case 4:
 123.893 +                u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
 123.894 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
 123.895 +                v    = (int32_t)src.val;
 123.896 +                generate_exception_if(
 123.897 +                    idiv_dbl(u, v) || ((int32_t)u[0] != u[0]),
 123.898 +                    EXC_DE);
 123.899 +                dst.val   = (int32_t)u[0];
 123.900 +                _regs.edx = (uint32_t)u[1];
 123.901 +                break;
 123.902 +#endif
 123.903 +            default:
 123.904 +                u[0] = _regs.eax;
 123.905 +                u[1] = _regs.edx;
 123.906 +                v    = src.val;
 123.907 +                generate_exception_if(idiv_dbl(u, v), EXC_DE);
 123.908 +                dst.val   = u[0];
 123.909 +                _regs.edx = u[1];
 123.910 +                break;
 123.911 +            }
 123.912 +            break;
 123.913 +        }
 123.914          default:
 123.915              goto cannot_emulate;
 123.916          }
 123.917          break;
 123.918  
 123.919 -    case 0xfe ... 0xff: /* Grp4/Grp5 */
 123.920 +    case 0xfe: /* Grp4 */
 123.921 +        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD);
 123.922 +    case 0xff: /* Grp5 */
 123.923          switch ( modrm_reg & 7 )
 123.924          {
 123.925          case 0: /* inc */
 123.926 @@ -1065,6 +1478,20 @@ x86_emulate(
 123.927          case 1: /* dec */
 123.928              emulate_1op("dec", dst, _regs.eflags);
 123.929              break;
 123.930 +        case 2: /* call (near) */
 123.931 +        case 4: /* jmp (near) */
 123.932 +            if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
 123.933 +            {
 123.934 +                dst.bytes = op_bytes = 8;
 123.935 +                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
 123.936 +                                     &dst.val, 8, ctxt)) != 0 )
 123.937 +                    goto done;
 123.938 +            }
 123.939 +            src.val = _regs.eip;
 123.940 +            _regs.eip = dst.val;
 123.941 +            if ( (modrm_reg & 7) == 2 )
 123.942 +                goto push; /* call */
 123.943 +            break;
 123.944          case 6: /* push */
 123.945              /* 64-bit mode: PUSH defaults to a 64-bit operand. */
 123.946              if ( mode_64bit() && (dst.bytes == 4) )
 123.947 @@ -1074,12 +1501,13 @@ x86_emulate(
 123.948                                       &dst.val, 8, ctxt)) != 0 )
 123.949                      goto done;
 123.950              }
 123.951 -            register_address_increment(_regs.esp, -dst.bytes);
 123.952 -            if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp),
 123.953 +            if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
 123.954                                    dst.val, dst.bytes, ctxt)) != 0 )
 123.955                  goto done;
 123.956 -            dst.val = dst.orig_val; /* skanky: disable writeback */
 123.957 +            dst.type = OP_NONE;
 123.958              break;
 123.959 +        case 7:
 123.960 +            generate_exception_if(1, EXC_UD);
 123.961          default:
 123.962              goto cannot_emulate;
 123.963          }
 123.964 @@ -1087,33 +1515,32 @@ x86_emulate(
 123.965      }
 123.966  
 123.967   writeback:
 123.968 -    if ( (d & Mov) || (dst.orig_val != dst.val) )
 123.969 +    switch ( dst.type )
 123.970      {
 123.971 -        switch ( dst.type )
 123.972 +    case OP_REG:
 123.973 +        /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
 123.974 +        switch ( dst.bytes )
 123.975          {
 123.976 -        case OP_REG:
 123.977 -            /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
 123.978 -            switch ( dst.bytes )
 123.979 -            {
 123.980 -            case 1: *(uint8_t  *)dst.reg = (uint8_t)dst.val; break;
 123.981 -            case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
 123.982 -            case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
 123.983 -            case 8: *dst.reg = dst.val; break;
 123.984 -            }
 123.985 -            break;
 123.986 -        case OP_MEM:
 123.987 -            if ( lock_prefix )
 123.988 -                rc = ops->cmpxchg(
 123.989 -                    dst.mem.seg, dst.mem.off, dst.orig_val,
 123.990 -                    dst.val, dst.bytes, ctxt);
 123.991 -            else
 123.992 -                rc = ops->write(
 123.993 -                    dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt);
 123.994 -            if ( rc != 0 )
 123.995 -                goto done;
 123.996 -        default:
 123.997 -            break;
 123.998 +        case 1: *(uint8_t  *)dst.reg = (uint8_t)dst.val; break;
 123.999 +        case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
123.1000 +        case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
123.1001 +        case 8: *dst.reg = dst.val; break;
123.1002          }
123.1003 +        break;
123.1004 +    case OP_MEM:
123.1005 +        if ( !(d & Mov) && (dst.orig_val == dst.val) )
123.1006 +            /* nothing to do */;
123.1007 +        else if ( lock_prefix )
123.1008 +            rc = ops->cmpxchg(
123.1009 +                dst.mem.seg, dst.mem.off, dst.orig_val,
123.1010 +                dst.val, dst.bytes, ctxt);
123.1011 +        else
123.1012 +            rc = ops->write(
123.1013 +                dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt);
123.1014 +        if ( rc != 0 )
123.1015 +            goto done;
123.1016 +    default:
123.1017 +        break;
123.1018      }
123.1019  
123.1020      /* Commit shadow register state. */
123.1021 @@ -1123,8 +1550,13 @@ x86_emulate(
123.1022      return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
123.1023  
123.1024   special_insn:
123.1025 -    /* Default action: disable writeback. There may be no dest operand. */
123.1026 -    dst.orig_val = dst.val;
123.1027 +    dst.type = OP_NONE;
123.1028 +
123.1029 +    /*
123.1030 +     * The only implicit-operands instruction allowed a LOCK prefix is
123.1031 +     * CMPXCHG{8,16}B.
123.1032 +     */
123.1033 +    generate_exception_if(lock_prefix && (b != 0xc7), EXC_GP);
123.1034  
123.1035      if ( twobyte )
123.1036          goto twobyte_special_insn;
123.1037 @@ -1142,11 +1574,70 @@ x86_emulate(
123.1038  
123.1039      switch ( b )
123.1040      {
123.1041 +    case 0x27: /* daa */ {
123.1042 +        uint8_t al = _regs.eax;
123.1043 +        unsigned long eflags = _regs.eflags;
123.1044 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1045 +        _regs.eflags &= ~(EFLG_CF|EFLG_AF);
123.1046 +        if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
123.1047 +        {
123.1048 +            *(uint8_t *)&_regs.eax += 6;
123.1049 +            _regs.eflags |= EFLG_AF;
123.1050 +        }
123.1051 +        if ( (al > 0x99) || (eflags & EFLG_CF) )
123.1052 +        {
123.1053 +            *(uint8_t *)&_regs.eax += 0x60;
123.1054 +            _regs.eflags |= EFLG_CF;
123.1055 +        }
123.1056 +        _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
123.1057 +        _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
123.1058 +        _regs.eflags |= (( int8_t)_regs.eax <  0) ? EFLG_SF : 0;
123.1059 +        _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
123.1060 +        break;
123.1061 +    }
123.1062 +
123.1063 +    case 0x2f: /* das */ {
123.1064 +        uint8_t al = _regs.eax;
123.1065 +        unsigned long eflags = _regs.eflags;
123.1066 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1067 +        _regs.eflags &= ~(EFLG_CF|EFLG_AF);
123.1068 +        if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
123.1069 +        {
123.1070 +            _regs.eflags |= EFLG_AF;
123.1071 +            if ( (al < 6) || (eflags & EFLG_CF) )
123.1072 +                _regs.eflags |= EFLG_CF;
123.1073 +            *(uint8_t *)&_regs.eax -= 6;
123.1074 +        }
123.1075 +        if ( (al > 0x99) || (eflags & EFLG_CF) )
123.1076 +        {
123.1077 +            *(uint8_t *)&_regs.eax -= 0x60;
123.1078 +            _regs.eflags |= EFLG_CF;
123.1079 +        }
123.1080 +        _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
123.1081 +        _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
123.1082 +        _regs.eflags |= (( int8_t)_regs.eax <  0) ? EFLG_SF : 0;
123.1083 +        _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
123.1084 +        break;
123.1085 +    }
123.1086 +
123.1087 +    case 0x37: /* aaa */
123.1088 +    case 0x3f: /* aas */
123.1089 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1090 +        _regs.eflags &= ~EFLG_CF;
123.1091 +        if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) )
123.1092 +        {
123.1093 +            ((uint8_t *)&_regs.eax)[0] += (b == 0x37) ? 6 : -6;
123.1094 +            ((uint8_t *)&_regs.eax)[1] += (b == 0x37) ? 1 : -1;
123.1095 +            _regs.eflags |= EFLG_CF | EFLG_AF;
123.1096 +        }
123.1097 +        ((uint8_t *)&_regs.eax)[0] &= 0x0f;
123.1098 +        break;
123.1099 +
123.1100      case 0x40 ... 0x4f: /* inc/dec reg */
123.1101          dst.type  = OP_REG;
123.1102          dst.reg   = decode_register(b & 7, &_regs, 0);
123.1103          dst.bytes = op_bytes;
123.1104 -        dst.orig_val = dst.val = *dst.reg;
123.1105 +        dst.val   = *dst.reg;
123.1106          if ( b & 8 )
123.1107              emulate_1op("dec", dst, _regs.eflags);
123.1108          else
123.1109 @@ -1154,16 +1645,9 @@ x86_emulate(
123.1110          break;
123.1111  
123.1112      case 0x50 ... 0x57: /* push reg */
123.1113 -        dst.type  = OP_MEM;
123.1114 -        dst.bytes = op_bytes;
123.1115 -        if ( mode_64bit() && (dst.bytes == 4) )
123.1116 -            dst.bytes = 8;
123.1117 -        dst.val = *(unsigned long *)decode_register(
123.1118 +        src.val = *(unsigned long *)decode_register(
123.1119              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
123.1120 -        register_address_increment(_regs.esp, -dst.bytes);
123.1121 -        dst.mem.seg = x86_seg_ss;
123.1122 -        dst.mem.off = truncate_ea(_regs.esp);
123.1123 -        break;
123.1124 +        goto push;
123.1125  
123.1126      case 0x58 ... 0x5f: /* pop reg */
123.1127          dst.type  = OP_REG;
123.1128 @@ -1172,10 +1656,56 @@ x86_emulate(
123.1129          dst.bytes = op_bytes;
123.1130          if ( mode_64bit() && (dst.bytes == 4) )
123.1131              dst.bytes = 8;
123.1132 -        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
123.1133 +        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes),
123.1134                               &dst.val, dst.bytes, ctxt)) != 0 )
123.1135              goto done;
123.1136 -        register_address_increment(_regs.esp, dst.bytes);
123.1137 +        break;
123.1138 +
123.1139 +    case 0x60: /* pusha */ {
123.1140 +        int i;
123.1141 +        unsigned long regs[] = {
123.1142 +            _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
123.1143 +            _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
123.1144 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1145 +        for ( i = 0; i < 8; i++ )
123.1146 +            if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
123.1147 +                                  regs[i], op_bytes, ctxt)) != 0 )
123.1148 +            goto done;
123.1149 +        break;
123.1150 +    }
123.1151 +
123.1152 +    case 0x61: /* popa */ {
123.1153 +        int i;
123.1154 +        unsigned long dummy_esp, *regs[] = {
123.1155 +            (unsigned long *)&_regs.edi, (unsigned long *)&_regs.esi,
123.1156 +            (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
123.1157 +            (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
123.1158 +            (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
123.1159 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1160 +        for ( i = 0; i < 8; i++ )
123.1161 +            if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
123.1162 +                                 regs[i], op_bytes, ctxt)) != 0 )
123.1163 +            goto done;
123.1164 +        break;
123.1165 +    }
123.1166 +
123.1167 +    case 0x68: /* push imm{16,32,64} */
123.1168 +        src.val = ((op_bytes == 2)
123.1169 +                   ? (int32_t)insn_fetch_type(int16_t)
123.1170 +                   : insn_fetch_type(int32_t));
123.1171 +        goto push;
123.1172 +
123.1173 +    case 0x6a: /* push imm8 */
123.1174 +        src.val = insn_fetch_type(int8_t);
123.1175 +    push:
123.1176 +        d |= Mov; /* force writeback */
123.1177 +        dst.type  = OP_MEM;
123.1178 +        dst.bytes = op_bytes;
123.1179 +        if ( mode_64bit() && (dst.bytes == 4) )
123.1180 +            dst.bytes = 8;
123.1181 +        dst.val = src.val;
123.1182 +        dst.mem.seg = x86_seg_ss;
123.1183 +        dst.mem.off = sp_pre_dec(dst.bytes);
123.1184          break;
123.1185  
123.1186      case 0x70 ... 0x7f: /* jcc (short) */ {
123.1187 @@ -1196,9 +1726,41 @@ x86_emulate(
123.1188          src.val  = *src.reg;
123.1189          dst.reg  = decode_register(
123.1190              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
123.1191 -        dst.val  = dst.orig_val = *dst.reg;
123.1192 +        dst.val  = *dst.reg;
123.1193          goto xchg;
123.1194  
123.1195 +    case 0x98: /* cbw/cwde/cdqe */
123.1196 +        switch ( op_bytes )
123.1197 +        {
123.1198 +        case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */
123.1199 +        case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */
123.1200 +        case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */
123.1201 +        }
123.1202 +        break;
123.1203 +
123.1204 +    case 0x99: /* cwd/cdq/cqo */
123.1205 +        switch ( op_bytes )
123.1206 +        {
123.1207 +        case 2:
123.1208 +            *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0;
123.1209 +            break;
123.1210 +        case 4:
123.1211 +            _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0);
123.1212 +            break;
123.1213 +        case 8:
123.1214 +            _regs.edx = (_regs.eax < 0) ? -1 : 0;
123.1215 +            break;
123.1216 +        }
123.1217 +        break;
123.1218 +
123.1219 +    case 0x9e: /* sahf */
123.1220 +        *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
123.1221 +        break;
123.1222 +
123.1223 +    case 0x9f: /* lahf */
123.1224 +        ((uint8_t *)&_regs.eax)[1] = (_regs.eflags & 0xd7) | 0x02;
123.1225 +        break;
123.1226 +
123.1227      case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */
123.1228          /* Source EA is not encoded via ModRM. */
123.1229          dst.type  = OP_REG;
123.1230 @@ -1253,6 +1815,81 @@ x86_emulate(
123.1231              _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
123.1232          break;
123.1233  
123.1234 +    case 0xc2: /* ret imm16 (near) */
123.1235 +    case 0xc3: /* ret (near) */ {
123.1236 +        int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0;
123.1237 +        op_bytes = mode_64bit() ? 8 : op_bytes;
123.1238 +        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes + offset),
123.1239 +                             &dst.val, op_bytes, ctxt)) != 0 )
123.1240 +            goto done;
123.1241 +        _regs.eip = dst.val;
123.1242 +        break;
123.1243 +    }
123.1244 +
123.1245 +    case 0xd4: /* aam */ {
123.1246 +        unsigned int base = insn_fetch_type(uint8_t);
123.1247 +        uint8_t al = _regs.eax;
123.1248 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1249 +        generate_exception_if(base == 0, EXC_DE);
123.1250 +        *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
123.1251 +        _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
123.1252 +        _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
123.1253 +        _regs.eflags |= (( int8_t)_regs.eax <  0) ? EFLG_SF : 0;
123.1254 +        _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
123.1255 +        break;
123.1256 +    }
123.1257 +
123.1258 +    case 0xd5: /* aad */ {
123.1259 +        unsigned int base = insn_fetch_type(uint8_t);
123.1260 +        uint16_t ax = _regs.eax;
123.1261 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1262 +        *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
123.1263 +        _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
123.1264 +        _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
123.1265 +        _regs.eflags |= (( int8_t)_regs.eax <  0) ? EFLG_SF : 0;
123.1266 +        _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
123.1267 +        break;
123.1268 +    }
123.1269 +
123.1270 +    case 0xd6: /* salc */
123.1271 +        generate_exception_if(mode_64bit(), EXC_UD);
123.1272 +        *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00;
123.1273 +        break;
123.1274 +
123.1275 +    case 0xd7: /* xlat */ {
123.1276 +        unsigned long al = (uint8_t)_regs.eax;
123.1277 +        if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.ebx + al),
123.1278 +                             &al, 1, ctxt)) != 0 )
123.1279 +            goto done;
123.1280 +        *(uint8_t *)&_regs.eax = al;
123.1281 +        break;
123.1282 +    }
123.1283 +
123.1284 +    case 0xe0 ... 0xe2: /* loop{,z,nz} */ {
123.1285 +        int rel = insn_fetch_type(int8_t);
123.1286 +        int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */
123.1287 +        if ( b == 0xe1 )
123.1288 +            do_jmp = !do_jmp; /* loopz */
123.1289 +        else if ( b == 0xe2 )
123.1290 +            do_jmp = 1; /* loop */
123.1291 +        switch ( ad_bytes )
123.1292 +        {
123.1293 +        case 2:
123.1294 +            do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0;
123.1295 +            break;
123.1296 +        case 4:
123.1297 +            do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0;
123.1298 +            _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */
123.1299 +            break;
123.1300 +        default: /* case 8: */
123.1301 +            do_jmp &= --_regs.ecx != 0;
123.1302 +            break;
123.1303 +        }
123.1304 +        if ( do_jmp )
123.1305 +            jmp_rel(rel);
123.1306 +        break;
123.1307 +    }
123.1308 +
123.1309      case 0xe3: /* jcxz/jecxz (short) */ {
123.1310          int rel = insn_fetch_type(int8_t);
123.1311          if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx :
123.1312 @@ -1261,12 +1898,26 @@ x86_emulate(
123.1313          break;
123.1314      }
123.1315  
123.1316 -    case 0xe9: /* jmp (short) */
123.1317 -        jmp_rel(insn_fetch_type(int8_t));
123.1318 +    case 0xe8: /* call (near) */ {
123.1319 +        int rel = (((op_bytes == 2) && !mode_64bit())
123.1320 +                   ? (int32_t)insn_fetch_type(int16_t)
123.1321 +                   : insn_fetch_type(int32_t));
123.1322 +        op_bytes = mode_64bit() ? 8 : op_bytes;
123.1323 +        src.val = _regs.eip;
123.1324 +        jmp_rel(rel);
123.1325 +        goto push;
123.1326 +    }
123.1327 +
123.1328 +    case 0xe9: /* jmp (near) */ {
123.1329 +        int rel = (((op_bytes == 2) && !mode_64bit())
123.1330 +                   ? (int32_t)insn_fetch_type(int16_t)
123.1331 +                   : insn_fetch_type(int32_t));
123.1332 +        jmp_rel(rel);
123.1333          break;
123.1334 +    }
123.1335  
123.1336 -    case 0xeb: /* jmp (near) */
123.1337 -        jmp_rel(insn_fetch_bytes(mode_64bit() ? 4 : op_bytes));
123.1338 +    case 0xeb: /* jmp (short) */
123.1339 +        jmp_rel(insn_fetch_type(int8_t));
123.1340          break;
123.1341  
123.1342      case 0xf5: /* cmc */
123.1343 @@ -1294,9 +1945,14 @@ x86_emulate(
123.1344   twobyte_insn:
123.1345      switch ( b )
123.1346      {
123.1347 -    case 0x40 ... 0x4f: /* cmov */
123.1348 -        dst.val = dst.orig_val = src.val;
123.1349 -        d = (d & ~Mov) | (test_cc(b, _regs.eflags) ? Mov : 0);
123.1350 +    case 0x40 ... 0x4f: /* cmovcc */
123.1351 +        dst.val = src.val;
123.1352 +        if ( !test_cc(b, _regs.eflags) )
123.1353 +            dst.type = OP_NONE;
123.1354 +        break;
123.1355 +
123.1356 +    case 0x90 ... 0x9f: /* setcc */
123.1357 +        dst.val = test_cc(b, _regs.eflags);
123.1358          break;
123.1359  
123.1360      case 0xb0 ... 0xb1: /* cmpxchg */
123.1361 @@ -1331,6 +1987,34 @@ x86_emulate(
123.1362          emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
123.1363          break;
123.1364  
123.1365 +    case 0xaf: /* imul */
123.1366 +        _regs.eflags &= ~(EFLG_OF|EFLG_CF);
123.1367 +        switch ( dst.bytes )
123.1368 +        {
123.1369 +        case 2:
123.1370 +            dst.val = ((uint32_t)(int16_t)src.val *
123.1371 +                       (uint32_t)(int16_t)dst.val);
123.1372 +            if ( (int16_t)dst.val != (uint32_t)dst.val )
123.1373 +                _regs.eflags |= EFLG_OF|EFLG_CF;
123.1374 +            break;
123.1375 +#ifdef __x86_64__
123.1376 +        case 4:
123.1377 +            dst.val = ((uint64_t)(int32_t)src.val *
123.1378 +                       (uint64_t)(int32_t)dst.val);
123.1379 +            if ( (int32_t)dst.val != dst.val )
123.1380 +                _regs.eflags |= EFLG_OF|EFLG_CF;
123.1381 +            break;
123.1382 +#endif
123.1383 +        default: {
123.1384 +            unsigned long m[2] = { src.val, dst.val };
123.1385 +            if ( imul_dbl(m) )
123.1386 +                _regs.eflags |= EFLG_OF|EFLG_CF;
123.1387 +            dst.val = m[0];
123.1388 +            break;
123.1389 +        }
123.1390 +        }
123.1391 +        break;
123.1392 +
123.1393      case 0xb6: /* movzx rm8,r{16,32,64} */
123.1394          /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */
123.1395          dst.reg   = decode_register(modrm_reg, &_regs, 0);
123.1396 @@ -1338,6 +2022,26 @@ x86_emulate(
123.1397          dst.val   = (uint8_t)src.val;
123.1398          break;
123.1399  
123.1400 +    case 0xbc: /* bsf */ {
123.1401 +        int zf;
123.1402 +        asm ( "bsf %2,%0; setz %b1"
123.1403 +              : "=r" (dst.val), "=q" (zf)
123.1404 +              : "r" (src.val), "1" (0) );
123.1405 +        _regs.eflags &= ~EFLG_ZF;
123.1406 +        _regs.eflags |= zf ? EFLG_ZF : 0;
123.1407 +        break;
123.1408 +    }
123.1409 +
123.1410 +    case 0xbd: /* bsr */ {
123.1411 +        int zf;
123.1412 +        asm ( "bsr %2,%0; setz %b1"
123.1413 +              : "=r" (dst.val), "=q" (zf)
123.1414 +              : "r" (src.val), "1" (0) );
123.1415 +        _regs.eflags &= ~EFLG_ZF;
123.1416 +        _regs.eflags |= zf ? EFLG_ZF : 0;
123.1417 +        break;
123.1418 +    }
123.1419 +
123.1420      case 0xb7: /* movzx rm16,r{16,32,64} */
123.1421          dst.val = (uint16_t)src.val;
123.1422          break;
123.1423 @@ -1347,12 +2051,13 @@ x86_emulate(
123.1424          break;
123.1425  
123.1426      case 0xba: /* Grp8 */
123.1427 -        switch ( modrm_reg & 3 )
123.1428 +        switch ( modrm_reg & 7 )
123.1429          {
123.1430 -        case 0: goto bt;
123.1431 -        case 1: goto bts;
123.1432 -        case 2: goto btr;
123.1433 -        case 3: goto btc;
123.1434 +        case 4: goto bt;
123.1435 +        case 5: goto bts;
123.1436 +        case 6: goto btr;
123.1437 +        case 7: goto btc;
123.1438 +        default: generate_exception_if(1, EXC_UD);
123.1439          }
123.1440          break;
123.1441  
123.1442 @@ -1385,10 +2090,13 @@ x86_emulate(
123.1443      {
123.1444      case 0x0d: /* GrpP (prefetch) */
123.1445      case 0x18: /* Grp16 (prefetch/nop) */
123.1446 +    case 0x19 ... 0x1f: /* nop (amd-defined) */
123.1447          break;
123.1448  
123.1449      case 0x80 ... 0x8f: /* jcc (near) */ {
123.1450 -        int rel = insn_fetch_bytes(mode_64bit() ? 4 : op_bytes);
123.1451 +        int rel = (((op_bytes == 2) && !mode_64bit())
123.1452 +                   ? (int32_t)insn_fetch_type(int16_t)
123.1453 +                   : insn_fetch_type(int32_t));
123.1454          if ( test_cc(b, _regs.eflags) )
123.1455              jmp_rel(rel);
123.1456          break;
123.1457 @@ -1398,6 +2106,7 @@ x86_emulate(
123.1458  #if defined(__i386__)
123.1459      {
123.1460          unsigned long old_lo, old_hi;
123.1461 +        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
123.1462          if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) ||
123.1463               (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) )
123.1464              goto done;
123.1465 @@ -1424,6 +2133,7 @@ x86_emulate(
123.1466  #elif defined(__x86_64__)
123.1467      {
123.1468          unsigned long old, new;
123.1469 +        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
123.1470          if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 )
123.1471              goto done;
123.1472          if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
123.1473 @@ -1444,6 +2154,37 @@ x86_emulate(
123.1474          break;
123.1475      }
123.1476  #endif
123.1477 +
123.1478 +    case 0xc8 ... 0xcf: /* bswap */
123.1479 +        dst.type  = OP_REG;
123.1480 +        dst.reg   = decode_register(b & 7, &_regs, 0);
123.1481 +        dst.val = *dst.reg;
123.1482 +        switch ( dst.bytes = op_bytes )
123.1483 +        {
123.1484 +        case 2:
123.1485 +            dst.val = (((dst.val & 0x00FFUL) << 8) |
123.1486 +                       ((dst.val & 0xFF00UL) >> 8));
123.1487 +            break;
123.1488 +        case 4:
123.1489 +            dst.val = (((dst.val & 0x000000FFUL) << 24) |
123.1490 +                       ((dst.val & 0x0000FF00UL) <<  8) |
123.1491 +                       ((dst.val & 0x00FF0000UL) >>  8) |
123.1492 +                       ((dst.val & 0xFF000000UL) >> 24));
123.1493 +            break;
123.1494 +#ifdef __x86_64__
123.1495 +        case 8:
123.1496 +            dst.val = (((dst.val & 0x00000000000000FFUL) << 56) |
123.1497 +                       ((dst.val & 0x000000000000FF00UL) << 40) |
123.1498 +                       ((dst.val & 0x0000000000FF0000UL) << 24) |
123.1499 +                       ((dst.val & 0x00000000FF000000UL) <<  8) |
123.1500 +                       ((dst.val & 0x000000FF00000000UL) >>  8) |
123.1501 +                       ((dst.val & 0x0000FF0000000000UL) >> 24) |
123.1502 +                       ((dst.val & 0x00FF000000000000UL) >> 40) |
123.1503 +                       ((dst.val & 0xFF00000000000000UL) >> 56));
123.1504 +            break;
123.1505 +#endif
123.1506 +        }
123.1507 +        break;
123.1508      }
123.1509      goto writeback;
123.1510  
   124.1 --- a/xen/common/elf.c	Thu Jan 18 09:54:33 2007 +0000
   124.2 +++ b/xen/common/elf.c	Thu Jan 18 15:18:07 2007 +0000
   124.3 @@ -300,7 +300,7 @@ int parseelfimage(struct domain_setup_in
   124.4      if ( dsi->__elfnote_section )
   124.5      {
   124.6          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   124.7 -        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
   124.8 +        if ( p != NULL && strstr(p, "bimodal") != NULL )
   124.9              dsi->pae_kernel = PAEKERN_bimodal;
  124.10          else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  124.11              dsi->pae_kernel = PAEKERN_extended_cr3;
   125.1 --- a/xen/common/kexec.c	Thu Jan 18 09:54:33 2007 +0000
   125.2 +++ b/xen/common/kexec.c	Thu Jan 18 15:18:07 2007 +0000
   125.3 @@ -26,36 +26,34 @@
   125.4  
   125.5  typedef long ret_t;
   125.6  
   125.7 -DEFINE_PER_CPU (crash_note_t, crash_notes);
   125.8 -cpumask_t crash_saved_cpus;
   125.9 +#define ELFNOTE_ALIGN(_n_) (((_n_)+3)&~3)
  125.10 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_)))
  125.11 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz))
  125.12 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz))
  125.13  
  125.14 -xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
  125.15 +static DEFINE_PER_CPU(void *, crash_notes);
  125.16 +
  125.17 +static Elf_Note *xen_crash_note;
  125.18 +
  125.19 +static cpumask_t crash_saved_cpus;
  125.20 +
  125.21 +static xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR];
  125.22  
  125.23  #define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
  125.24  #define KEXEC_FLAG_CRASH_POS     (KEXEC_IMAGE_NR + 1)
  125.25  #define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
  125.26  
  125.27 -unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */
  125.28 +static unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */
  125.29  
  125.30 -spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
  125.31 +static spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED;
  125.32  
  125.33  xen_kexec_reserve_t kexec_crash_area;
  125.34  
  125.35  static void __init parse_crashkernel(const char *str)
  125.36  {
  125.37 -    unsigned long start, size;
  125.38 -
  125.39 -    size = parse_size_and_unit(str, &str);
  125.40 +    kexec_crash_area.size = parse_size_and_unit(str, &str);
  125.41      if ( *str == '@' )
  125.42 -        start = parse_size_and_unit(str+1, NULL);
  125.43 -    else
  125.44 -        start = 0;
  125.45 -
  125.46 -    if ( start && size )
  125.47 -    {
  125.48 -        kexec_crash_area.start = start;
  125.49 -        kexec_crash_area.size = size;
  125.50 -    }
  125.51 +        kexec_crash_area.start = parse_size_and_unit(str+1, NULL);
  125.52  }
  125.53  custom_param("crashkernel", parse_crashkernel);
  125.54  
  125.55 @@ -70,40 +68,29 @@ static void one_cpu_only(void)
  125.56  void kexec_crash_save_cpu(void)
  125.57  {
  125.58      int cpu = smp_processor_id();
  125.59 -    crash_note_t *cntp;
  125.60 +    Elf_Note *note = per_cpu(crash_notes, cpu);
  125.61 +    ELF_Prstatus *prstatus;
  125.62 +    crash_xen_core_t *xencore;
  125.63  
  125.64      if ( cpu_test_and_set(cpu, crash_saved_cpus) )
  125.65          return;
  125.66  
  125.67 -    cntp = &per_cpu(crash_notes, cpu);
  125.68 -    elf_core_save_regs(&cntp->core.desc.desc.pr_reg,
  125.69 -                       &cntp->xen_regs.desc.desc);
  125.70 +    prstatus = ELFNOTE_DESC(note);
  125.71  
  125.72 -    /* Set up crash "CORE" note. */
  125.73 -    setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS);
  125.74 +    note = ELFNOTE_NEXT(note);
  125.75 +    xencore = ELFNOTE_DESC(note);
  125.76  
  125.77 -    /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */
  125.78 -    setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN,
  125.79 -                     XEN_ELFNOTE_CRASH_REGS);
  125.80 +    elf_core_save_regs(&prstatus->pr_reg, xencore);
  125.81  }
  125.82  
  125.83  /* Set up the single Xen-specific-info crash note. */
  125.84  crash_xen_info_t *kexec_crash_save_info(void)
  125.85  {
  125.86      int cpu = smp_processor_id();
  125.87 -    crash_note_t *cntp;
  125.88 -    crash_xen_info_t *info;
  125.89 +    crash_xen_info_t *info = ELFNOTE_DESC(xen_crash_note);
  125.90  
  125.91      BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus));
  125.92  
  125.93 -    cntp = &per_cpu(crash_notes, cpu);
  125.94 -
  125.95 -    /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */
  125.96 -    setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN,
  125.97 -                     XEN_ELFNOTE_CRASH_INFO);
  125.98 -
  125.99 -    info = &cntp->xen_info.desc.desc;
 125.100 -
 125.101      info->xen_major_version = xen_major_version();
 125.102      info->xen_minor_version = xen_minor_version();
 125.103      info->xen_extra_version = __pa(xen_extra_version());
 125.104 @@ -147,14 +134,26 @@ static __init int register_crashdump_tri
 125.105  }
 125.106  __initcall(register_crashdump_trigger);
 125.107  
 125.108 +static void setup_note(Elf_Note *n, const char *name, int type, int descsz)
 125.109 +{
 125.110 +    strcpy(ELFNOTE_NAME(n), name);
 125.111 +    n->namesz = strlen(name);
 125.112 +    n->descsz = descsz;
 125.113 +    n->type = type;
 125.114 +}
 125.115 +
 125.116  #define kexec_get(x)      kexec_get_##x
 125.117  
 125.118  #endif
 125.119  
 125.120  static int kexec_get(reserve)(xen_kexec_range_t *range)
 125.121  {
 125.122 -    range->start = kexec_crash_area.start;
 125.123 -    range->size = kexec_crash_area.size;
 125.124 +    if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0) {
 125.125 +        range->start = kexec_crash_area.start;
 125.126 +        range->size = kexec_crash_area.size;
 125.127 +    }
 125.128 +    else
 125.129 +        range->start = range->size = 0;
 125.130      return 0;
 125.131  }
 125.132  
 125.133 @@ -167,11 +166,44 @@ static int kexec_get(xen)(xen_kexec_rang
 125.134  
 125.135  static int kexec_get(cpu)(xen_kexec_range_t *range)
 125.136  {
 125.137 -    if ( range->nr < 0 || range->nr >= num_present_cpus() )
 125.138 +    int nr = range->nr;
 125.139 +    int nr_bytes = sizeof(Elf_Note) * 2
 125.140 +        + ELFNOTE_ALIGN(sizeof(ELF_Prstatus))
 125.141 +        + ELFNOTE_ALIGN(sizeof(crash_xen_core_t));
 125.142 +
 125.143 +    if ( nr < 0 || nr >= num_present_cpus() )
 125.144          return -EINVAL;
 125.145  
 125.146 -    range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr));
 125.147 -    range->size = sizeof(crash_note_t);
 125.148 +    /* The Xen info note is included in CPU0's range. */
 125.149 +    if ( nr == 0 )
 125.150 +        nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t));
 125.151 +
 125.152 +    if ( per_cpu(crash_notes, nr) == NULL )
 125.153 +    {
 125.154 +        Elf_Note *note;
 125.155 +
 125.156 +        note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes);
 125.157 +
 125.158 +        if ( note == NULL )
 125.159 +            return -ENOMEM;
 125.160 +
 125.161 +        /* Setup CORE note. */
 125.162 +        setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus));
 125.163 +
 125.164 +        /* Setup Xen CORE note. */
 125.165 +        note = ELFNOTE_NEXT(note);
 125.166 +        setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS, sizeof(crash_xen_core_t));
 125.167 +
 125.168 +        if (nr == 0)
 125.169 +        {
 125.170 +            /* Setup system wide Xen info note. */
 125.171 +            xen_crash_note = note = ELFNOTE_NEXT(note);
 125.172 +            setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO, sizeof(crash_xen_info_t));
 125.173 +        }
 125.174 +    }
 125.175 +
 125.176 +    range->start = __pa((unsigned long)per_cpu(crash_notes, nr));
 125.177 +    range->size = nr_bytes;
 125.178      return 0;
 125.179  }
 125.180  
   126.1 --- a/xen/common/keyhandler.c	Thu Jan 18 09:54:33 2007 +0000
   126.2 +++ b/xen/common/keyhandler.c	Thu Jan 18 15:18:07 2007 +0000
   126.3 @@ -95,6 +95,11 @@ static void show_handlers(unsigned char 
   126.4  static void __dump_execstate(void *unused)
   126.5  {
   126.6      dump_execution_state();
   126.7 +    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
   126.8 +    if ( is_idle_vcpu(current) )
   126.9 +        printk("No guest context (CPU is idle).\n");
  126.10 +    else
  126.11 +        show_execution_state(guest_cpu_user_regs());
  126.12  }
  126.13  
  126.14  static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
  126.15 @@ -104,16 +109,18 @@ static void dump_registers(unsigned char
  126.16      printk("'%c' pressed -> dumping registers\n", key);
  126.17  
  126.18      /* Get local execution state out immediately, in case we get stuck. */
  126.19 -    printk("\n*** Dumping CPU%d state: ***\n", smp_processor_id());
  126.20 -    show_execution_state(regs);
  126.21 +    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
  126.22 +    __dump_execstate(NULL);
  126.23  
  126.24      for_each_online_cpu ( cpu )
  126.25      {
  126.26          if ( cpu == smp_processor_id() )
  126.27              continue;
  126.28 -        printk("\n*** Dumping CPU%d state: ***\n", cpu);
  126.29 +        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
  126.30          on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
  126.31      }
  126.32 +
  126.33 +    printk("\n");
  126.34  }
  126.35  
  126.36  static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
   127.1 --- a/xen/common/lib.c	Thu Jan 18 09:54:33 2007 +0000
   127.2 +++ b/xen/common/lib.c	Thu Jan 18 15:18:07 2007 +0000
   127.3 @@ -1,41 +1,44 @@
   127.4  
   127.5  #include <xen/ctype.h>
   127.6  #include <xen/lib.h>
   127.7 -
   127.8 +#include <xen/types.h>
   127.9  
  127.10 -/* for inc/ctype.h */
  127.11 +/* for ctype.h */
  127.12  unsigned char _ctype[] = {
  127.13 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
  127.14 -_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
  127.15 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
  127.16 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
  127.17 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
  127.18 -_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
  127.19 -_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
  127.20 -_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
  127.21 -_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
  127.22 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
  127.23 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
  127.24 -_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
  127.25 -_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
  127.26 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
  127.27 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
  127.28 -_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
  127.29 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
  127.30 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
  127.31 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
  127.32 -_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
  127.33 -_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
  127.34 -_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
  127.35 -_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
  127.36 -_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
  127.37 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
  127.38 +    _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
  127.39 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
  127.40 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
  127.41 +    _S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
  127.42 +    _P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
  127.43 +    _D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
  127.44 +    _D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
  127.45 +    _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
  127.46 +    _U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
  127.47 +    _U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
  127.48 +    _U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
  127.49 +    _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
  127.50 +    _L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
  127.51 +    _L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
  127.52 +    _L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
  127.53 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
  127.54 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
  127.55 +    _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
  127.56 +    _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
  127.57 +    _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
  127.58 +    _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
  127.59 +    _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
  127.60 +    _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
  127.61  
  127.62 -
  127.63 -/* a couple of 64 bit operations ported from freebsd */
  127.64 -
  127.65 -/*-
  127.66 +/*
  127.67 + * A couple of 64 bit operations ported from FreeBSD.
  127.68 + * The code within the '#if BITS_PER_LONG == 32' block below, and no other
  127.69 + * code in this file, is distributed under the following licensing terms
  127.70 + * This is the modified '3-clause' BSD license with the obnoxious
  127.71 + * advertising clause removed, as permitted by University of California.
  127.72 + *
  127.73   * Copyright (c) 1992, 1993
  127.74 - *	The Regents of the University of California.  All rights reserved.
  127.75 + * The Regents of the University of California.  All rights reserved.
  127.76   *
  127.77   * This software was developed by the Computer Systems Engineering group
  127.78   * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
  127.79 @@ -49,11 +52,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
  127.80   * 2. Redistributions in binary form must reproduce the above copyright
  127.81   *    notice, this list of conditions and the following disclaimer in the
  127.82   *    documentation and/or other materials provided with the distribution.
  127.83 - * 3. All advertising materials mentioning features or use of this software
  127.84 - *    must display the following acknowledgement:
  127.85 - *	This product includes software developed by the University of
  127.86 - *	California, Berkeley and its contributors.
  127.87 - * 4. Neither the name of the University nor the names of its contributors
  127.88 + * 3. Neither the name of the University nor the names of its contributors
  127.89   *    may be used to endorse or promote products derived from this software
  127.90   *    without specific prior written permission.
  127.91   *
  127.92 @@ -68,12 +67,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
  127.93   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  127.94   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  127.95   * SUCH DAMAGE.
  127.96 - *
  127.97 - * $FreeBSD: src/sys/libkern/divdi3.c,v 1.6 1999/08/28 00:46:31 peter Exp $
  127.98   */
  127.99 -
 127.100 -#include <asm/types.h>
 127.101 -
 127.102  #if BITS_PER_LONG == 32
 127.103  
 127.104  /*
 127.105 @@ -81,10 +75,10 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
 127.106   * one or more of the following formats.
 127.107   */
 127.108  union uu {
 127.109 -        s64            q;              /* as a (signed) quad */
 127.110 -        s64            uq;             /* as an unsigned quad */
 127.111 -        long           sl[2];          /* as two signed longs */
 127.112 -        unsigned long  ul[2];          /* as two unsigned longs */
 127.113 +    s64            q;              /* as a (signed) quad */
 127.114 +    s64            uq;             /* as an unsigned quad */
 127.115 +    long           sl[2];          /* as two signed longs */
 127.116 +    unsigned long  ul[2];          /* as two unsigned longs */
 127.117  };
 127.118  /* XXX RN: Yuck hardcoded endianess :) */
 127.119  #define _QUAD_HIGHWORD 1
 127.120 @@ -122,31 +116,26 @@ union uu {
 127.121   * Multiprecision divide.  This algorithm is from Knuth vol. 2 (2nd ed),
 127.122   * section 4.3.1, pp. 257--259.
 127.123   */
 127.124 -#define	B	(1 << HALF_BITS)	/* digit base */
 127.125 +#define B (1 << HALF_BITS) /* digit base */
 127.126  
 127.127  /* Combine two `digits' to make a single two-digit number. */
 127.128 -#define	COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
 127.129 +#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
 127.130  
 127.131 -/* select a type for digits in base B: use unsigned short if they fit */
 127.132 -#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
 127.133 -typedef unsigned short digit;
 127.134 -#else
 127.135 +/* select a type for digits in base B */
 127.136  typedef u_long digit;
 127.137 -#endif
 127.138  
 127.139  /*
 127.140   * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
 127.141   * `fall out' the left (there never will be any such anyway).
 127.142   * We may assume len >= 0.  NOTE THAT THIS WRITES len+1 DIGITS.
 127.143   */
 127.144 -static void
 127.145 -shl(register digit *p, register int len, register int sh)
 127.146 +static void shl(register digit *p, register int len, register int sh)
 127.147  {
 127.148 -	register int i;
 127.149 +    register int i;
 127.150  
 127.151 -	for (i = 0; i < len; i++)
 127.152 -		p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
 127.153 -	p[i] = LHALF(p[i] << sh);
 127.154 +    for (i = 0; i < len; i++)
 127.155 +        p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
 127.156 +    p[i] = LHALF(p[i] << sh);
 127.157  }
 127.158  
 127.159  /*
 127.160 @@ -157,234 +146,222 @@ shl(register digit *p, register int len,
 127.161   * divisor are 4 `digits' in this base (they are shorter if they have
 127.162   * leading zeros).
 127.163   */
 127.164 -u64
 127.165 -__qdivrem(u64 uq, u64 vq, u64 *arq)
 127.166 +u64 __qdivrem(u64 uq, u64 vq, u64 *arq)
 127.167  {
 127.168 -	union uu tmp;
 127.169 -	digit *u, *v, *q;
 127.170 -	register digit v1, v2;
 127.171 -	u_long qhat, rhat, t;
 127.172 -	int m, n, d, j, i;
 127.173 -	digit uspace[5], vspace[5], qspace[5];
 127.174 +    union uu tmp;
 127.175 +    digit *u, *v, *q;
 127.176 +    register digit v1, v2;
 127.177 +    u_long qhat, rhat, t;
 127.178 +    int m, n, d, j, i;
 127.179 +    digit uspace[5], vspace[5], qspace[5];
 127.180  
 127.181 -	/*
 127.182 -	 * Take care of special cases: divide by zero, and u < v.
 127.183 -	 */
 127.184 -	if (vq == 0) {
 127.185 -		/* divide by zero. */
 127.186 -		static volatile const unsigned int zero = 0;
 127.187 +    /*
 127.188 +     * Take care of special cases: divide by zero, and u < v.
 127.189 +     */
 127.190 +    if (vq == 0) {
 127.191 +        /* divide by zero. */
 127.192 +        static volatile const unsigned int zero = 0;
 127.193  
 127.194 -		tmp.ul[H] = tmp.ul[L] = 1 / zero;
 127.195 -		if (arq)
 127.196 -			*arq = uq;
 127.197 -		return (tmp.q);
 127.198 -	}
 127.199 -	if (uq < vq) {
 127.200 -		if (arq)
 127.201 -			*arq = uq;
 127.202 -		return (0);
 127.203 -	}
 127.204 -	u = &uspace[0];
 127.205 -	v = &vspace[0];
 127.206 -	q = &qspace[0];
 127.207 +        tmp.ul[H] = tmp.ul[L] = 1 / zero;
 127.208 +        if (arq)
 127.209 +            *arq = uq;
 127.210 +        return (tmp.q);
 127.211 +    }
 127.212 +    if (uq < vq) {
 127.213 +        if (arq)
 127.214 +            *arq = uq;
 127.215 +        return (0);
 127.216 +    }
 127.217 +    u = &uspace[0];
 127.218 +    v = &vspace[0];
 127.219 +    q = &qspace[0];
 127.220  
 127.221 -	/*
 127.222 -	 * Break dividend and divisor into digits in base B, then
 127.223 -	 * count leading zeros to determine m and n.  When done, we
 127.224 -	 * will have:
 127.225 -	 *	u = (u[1]u[2]...u[m+n]) sub B
 127.226 -	 *	v = (v[1]v[2]...v[n]) sub B
 127.227 -	 *	v[1] != 0
 127.228 -	 *	1 < n <= 4 (if n = 1, we use a different division algorithm)
 127.229 -	 *	m >= 0 (otherwise u < v, which we already checked)
 127.230 -	 *	m + n = 4
 127.231 -	 * and thus
 127.232 -	 *	m = 4 - n <= 2
 127.233 -	 */
 127.234 -	tmp.uq = uq;
 127.235 -	u[0] = 0;
 127.236 -	u[1] = HHALF(tmp.ul[H]);
 127.237 -	u[2] = LHALF(tmp.ul[H]);
 127.238 -	u[3] = HHALF(tmp.ul[L]);
 127.239 -	u[4] = LHALF(tmp.ul[L]);
 127.240 -	tmp.uq = vq;
 127.241 -	v[1] = HHALF(tmp.ul[H]);
 127.242 -	v[2] = LHALF(tmp.ul[H]);
 127.243 -	v[3] = HHALF(tmp.ul[L]);
 127.244 -	v[4] = LHALF(tmp.ul[L]);
 127.245 -	for (n = 4; v[1] == 0; v++) {
 127.246 -		if (--n == 1) {
 127.247 -			u_long rbj;	/* r*B+u[j] (not root boy jim) */
 127.248 -			digit q1, q2, q3, q4;
 127.249 +    /*
 127.250 +     * Break dividend and divisor into digits in base B, then
 127.251 +     * count leading zeros to determine m and n.  When done, we
 127.252 +     * will have:
 127.253 +     * u = (u[1]u[2]...u[m+n]) sub B
 127.254 +     * v = (v[1]v[2]...v[n]) sub B
 127.255 +     * v[1] != 0
 127.256 +     * 1 < n <= 4 (if n = 1, we use a different division algorithm)
 127.257 +     * m >= 0 (otherwise u < v, which we already checked)
 127.258 +     * m + n = 4
 127.259 +     * and thus
 127.260 +     * m = 4 - n <= 2
 127.261 +     */
 127.262 +    tmp.uq = uq;
 127.263 +    u[0] = 0;
 127.264 +    u[1] = HHALF(tmp.ul[H]);
 127.265 +    u[2] = LHALF(tmp.ul[H]);
 127.266 +    u[3] = HHALF(tmp.ul[L]);
 127.267 +    u[4] = LHALF(tmp.ul[L]);
 127.268 +    tmp.uq = vq;
 127.269 +    v[1] = HHALF(tmp.ul[H]);
 127.270 +    v[2] = LHALF(tmp.ul[H]);
 127.271 +    v[3] = HHALF(tmp.ul[L]);
 127.272 +    v[4] = LHALF(tmp.ul[L]);
 127.273 +    for (n = 4; v[1] == 0; v++) {
 127.274 +        if (--n == 1) {
 127.275 +            u_long rbj; /* r*B+u[j] (not root boy jim) */
 127.276 +            digit q1, q2, q3, q4;
 127.277  
 127.278 -			/*
 127.279 -			 * Change of plan, per exercise 16.
 127.280 -			 *	r = 0;
 127.281 -			 *	for j = 1..4:
 127.282 -			 *		q[j] = floor((r*B + u[j]) / v),
 127.283 -			 *		r = (r*B + u[j]) % v;
 127.284 -			 * We unroll this completely here.
 127.285 -			 */
 127.286 -			t = v[2];	/* nonzero, by definition */
 127.287 -			q1 = u[1] / t;
 127.288 -			rbj = COMBINE(u[1] % t, u[2]);
 127.289 -			q2 = rbj / t;
 127.290 -			rbj = COMBINE(rbj % t, u[3]);
 127.291 -			q3 = rbj / t;
 127.292 -			rbj = COMBINE(rbj % t, u[4]);
 127.293 -			q4 = rbj / t;
 127.294 -			if (arq)
 127.295 -				*arq = rbj % t;
 127.296 -			tmp.ul[H] = COMBINE(q1, q2);
 127.297 -			tmp.ul[L] = COMBINE(q3, q4);
 127.298 -			return (tmp.q);
 127.299 -		}
 127.300 -	}
 127.301 +            /*
 127.302 +             * Change of plan, per exercise 16.
 127.303 +             * r = 0;
 127.304 +             * for j = 1..4:
 127.305 +             *  q[j] = floor((r*B + u[j]) / v),
 127.306 +             *  r = (r*B + u[j]) % v;
 127.307 +             * We unroll this completely here.
 127.308 +             */
 127.309 +            t = v[2]; /* nonzero, by definition */
 127.310 +            q1 = u[1] / t;
 127.311 +            rbj = COMBINE(u[1] % t, u[2]);
 127.312 +            q2 = rbj / t;
 127.313 +            rbj = COMBINE(rbj % t, u[3]);
 127.314 +            q3 = rbj / t;
 127.315 +            rbj = COMBINE(rbj % t, u[4]);
 127.316 +            q4 = rbj / t;
 127.317 +            if (arq)
 127.318 +                *arq = rbj % t;
 127.319 +            tmp.ul[H] = COMBINE(q1, q2);
 127.320 +            tmp.ul[L] = COMBINE(q3, q4);
 127.321 +            return (tmp.q);
 127.322 +        }
 127.323 +    }
 127.324  
 127.325 -	/*
 127.326 -	 * By adjusting q once we determine m, we can guarantee that
 127.327 -	 * there is a complete four-digit quotient at &qspace[1] when
 127.328 -	 * we finally stop.
 127.329 -	 */
 127.330 -	for (m = 4 - n; u[1] == 0; u++)
 127.331 -		m--;
 127.332 -	for (i = 4 - m; --i >= 0;)
 127.333 -		q[i] = 0;
 127.334