ia64/xen-unstable
changeset 13527:8475a4e0425e
[merge] with xen-unstable
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 = ®s; 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 - ¤t->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 = ¤t->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