diff --git a/Makefile b/Makefile index c7004c0ae2..cac9547a3d 100644 --- a/Makefile +++ b/Makefile @@ -2,18 +2,15 @@ # Grand Unified Makefile for Xen. # -# Export target architecture overrides to Xen and Linux sub-trees. -ifneq ($(XEN_TARGET_ARCH),) -SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH)) -export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE -endif - # Default target must appear before any include lines .PHONY: all all: dist export XEN_ROOT=$(CURDIR) include Config.mk + +SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH)) +export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE include buildconfigs/Rules.mk ifeq ($(XEN_TARGET_X86_PAE),y) diff --git a/docs/man/xm.pod.1 b/docs/man/xm.pod.1 index b0ba7f8fb2..3cd8b80ac6 100644 --- a/docs/man/xm.pod.1 +++ b/docs/man/xm.pod.1 @@ -451,6 +451,7 @@ make the man page more readable): xen_minor : 0 xen_extra : -devel xen_caps : xen-3.0-x86_32 + xen_scheduler : credit xen_pagesize : 4096 platform_params : virt_start=0xfc000000 xen_changeset : Mon Nov 14 18:13:38 2005 +0100 @@ -460,7 +461,7 @@ make the man page more readable): cc_compile_by : sdague cc_compile_domain : (none) cc_compile_date : Mon Nov 14 14:16:48 EST 2005 - xend_config_format : 2 + xend_config_format : 3 B diff --git a/docs/man/xmdomain.cfg.pod.5 b/docs/man/xmdomain.cfg.pod.5 index 03faf68caf..6fe1da79f7 100644 --- a/docs/man/xmdomain.cfg.pod.5 +++ b/docs/man/xmdomain.cfg.pod.5 @@ -135,6 +135,55 @@ one will be randomly chosen by xen with the 00:16:3e vendor id prefix. =back +=item B + +A virtual frame buffer stanza in the form: + + vfb = [ "stanza" ] + +The stanza specifies a set of I options separated by +commas, in the form: "name1=value1, name2=value2, ..." + +B + +=over 4 + +=item I + +There are currently two valid options: I starts a VNC server that +lets you connect an external VNC viewer, and I starts an internal +viewer. + +=item I + +The VNC display number to use, defaults to the domain ID. The +VNC server listens on port 5900 + display number. + +=item I + +The listening address for the VNC server, default 127.0.0.1. + +=item I + +If non-zero, the VNC server listens on the first unused port above +5900. + +=item I + +Overrides the XenD configured default password. + +=item I + +Display to use for the internal viewer, defaults to environment +variable I. + +=item I + +Authority file to use for the internal viewer, defaults to environment +variable I. + +=back + =back =head1 ADDITIONAL OPTIONS diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index 0fa1baccd5..ad4ff8d910 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -1,112 +1,88 @@ -debug ?= y +# Common Makefile for mini-os. +# +# Every architecture directory below mini-os/arch has to have a +# Makefile and a arch.mk. +# + pae ?= n XEN_ROOT = ../.. include $(XEN_ROOT)/Config.mk -# Set TARGET_ARCH -override TARGET_ARCH := $(XEN_TARGET_ARCH) - XEN_INTERFACE_VERSION := 0x00030204 +export XEN_INTERFACE_VERSION -# NB. '-Wcast-qual' is nasty, so I omitted it. -CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format -CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline -CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION) +# Set TARGET_ARCH +override TARGET_ARCH := $(XEN_TARGET_ARCH) -ASFLAGS = -D__ASSEMBLY__ +# Set mini-os root path, used in mini-os.mk. +MINI-OS_ROOT=$(PWD) +export MINI-OS_ROOT -LDLIBS = -L. -lminios -LDFLAGS_FINAL := -N -T minios-$(TARGET_ARCH).lds -LDFLAGS := +# Try to find out the architecture family TARGET_ARCH_FAM. +# First check whether x86_... is contained (for x86_32, x86_32y, x86_64). +# If not x86 then use $(TARGET_ARCH) -> for ia64, ... +ifeq ($(findstring x86_,$(TARGET_ARCH)),x86_) +TARGET_ARCH_FAM = x86 +else +TARGET_ARCH_FAM = $(TARGET_ARCH) +endif + +# The architecture family directory below mini-os. +TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM) + +# Export these variables for possible use in architecture dependent makefiles. +export TARGET_ARCH +export TARGET_ARCH_DIR +export TARGET_ARCH_FAM + +# This is used for architecture specific links. +# This can be overwritten from arch specific rules. +ARCH_LINKS = + +# For possible special header directories. +# This can be overwritten from arch specific rules. +EXTRA_INC = + +# Special build dependencies. +# Build all after touching this/these file(s) (see minios.mk) +SPEC_DEPENDS = minios.mk + +# Include the architecture family's special makerules. +# This must be before include minios.mk! +include $(TARGET_ARCH_DIR)/arch.mk + +# Include common mini-os makerules. +include minios.mk + +# Define some default flags for linking. +LDLIBS := +LDFLAGS := +LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME) +LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds # Prefix for global API names. All other symbols are localised before # linking with EXTRA_OBJS. GLOBAL_PREFIX := xenos_ EXTRA_OBJS = -# For possible special source directories. -EXTRA_SRC = -# For possible special header directories. -EXTRA_INC = - -# Standard name for architecture specific subdirectories. -TARGET_ARCH_DIR = $(TARGET_ARCH) -# This is used for architecture specific links. -ARCH_LINKS = - -ifeq ($(TARGET_ARCH),x86_32) -CFLAGS += -m32 -march=i686 -LDFLAGS += -m elf_i386 -TARGET_ARCH_DIR = x86 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH) -EXTRA_SRC += arch/$(EXTRA_INC) -endif - -ifeq ($(TARGET_ARCH)$(pae),x86_32y) -CFLAGS += -DCONFIG_X86_PAE=1 -ASFLAGS += -DCONFIG_X86_PAE=1 -TARGET_ARCH_DIR = x86 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH) -EXTRA_SRC += arch/$(EXTRA_INC) -endif - -ifeq ($(TARGET_ARCH),x86_64) -CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks -CFLAGS += -fno-asynchronous-unwind-tables -LDFLAGS += -m elf_x86_64 -TARGET_ARCH_DIR = x86 -EXTRA_INC += $(TARGET_ARCH_DIR)/$(TARGET_ARCH) -EXTRA_SRC += arch/$(EXTRA_INC) -endif - -ifeq ($(TARGET_ARCH),ia64) -CFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -mconstant-gp -ASFLAGS += -x assembler-with-cpp -Wall -ASFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -fomit-frame-pointer -ASFLAGS += -fno-builtin -fno-common -fno-strict-aliasing -mconstant-gp -ARCH_LINKS = IA64_LINKS # Special link on ia64 needed -define arch_links -[ -e include/ia64/asm-xsi-offsets.h ] || ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/ia64/asm-xsi-offsets.h -endef -endif - -ifeq ($(debug),y) -CFLAGS += -g -else -CFLAGS += -O3 -endif - -# Add the special header directories to the include paths. -extra_incl := $(foreach dir,$(EXTRA_INC),-Iinclude/$(dir)) -override CPPFLAGS := -Iinclude $(CPPFLAGS) -Iinclude/$(TARGET_ARCH_DIR) $(extra_incl) - TARGET := mini-os -HEAD := $(TARGET_ARCH).o +# Subdirectories common to mini-os +SUBDIRS := lib xenbus console + +# The common mini-os objects to build. OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c)) -OBJS += $(patsubst %.S,%.o,$(wildcard arch/$(TARGET_ARCH_DIR)/*.S)) -OBJS += $(patsubst %.c,%.o,$(wildcard arch/$(TARGET_ARCH_DIR)/*.c)) -# For special wanted source directories. -extra_objs := $(foreach dir,$(EXTRA_SRC),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c))) -OBJS += $(extra_objs) -extra_objs := $(foreach dir,$(EXTRA_SRC),$(patsubst %.S,%.o,$(wildcard $(dir)/*.S))) -OBJS += $(extra_objs) -HDRS := $(wildcard include/*.h) -HDRS += $(wildcard include/xen/*.h) -HDRS += $(wildcard include/$(TARGET_ARCH_DIR)/*.h) -# For special wanted header directories. -extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h)) -HDRS += $(extra_heads) .PHONY: default default: $(TARGET) -# Create special architecture specific links. +# Create special architecture specific links. The function arch_links +# has to be defined in arch.mk (see include above). ifneq ($(ARCH_LINKS),) $(ARCH_LINKS): $(arch_links) @@ -116,24 +92,29 @@ endif links: $(ARCH_LINKS) [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen -$(TARGET): links $(OBJS) $(HEAD) - $(LD) -r $(LDFLAGS) $(HEAD) $(OBJS) -o $@.o +.PHONY: arch_lib +arch_lib: + $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1; + +$(TARGET): links $(OBJS) arch_lib + $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@ gzip -f -9 -c $@ >$@.gz -.PHONY: clean -clean: - find . -type f -name '*.o' | xargs rm -f - rm -f *.o *~ core $(TARGET) $(TARGET).gz +.PHONY: clean arch_clean + +arch_clean: + $(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1; + +clean: arch_clean + for dir in $(SUBDIRS); do \ + rm -f $$dir/*.o; \ + done + rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz find . -type l | xargs rm -f rm -f tags TAGS -%.o: %.c $(HDRS) Makefile - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ - -%.o: %.S $(HDRS) Makefile - $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@ define all_sources ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print ) @@ -147,3 +128,4 @@ cscope: .PHONY: tags tags: $(all_sources) | xargs ctags + diff --git a/extras/mini-os/arch/x86/Makefile b/extras/mini-os/arch/x86/Makefile new file mode 100644 index 0000000000..45cfe19136 --- /dev/null +++ b/extras/mini-os/arch/x86/Makefile @@ -0,0 +1,29 @@ +# +# x86 architecture specific makefiles. +# It's is used for x86_32, x86_32y and x86_64 +# + +# Rebuild all after touching this/these extra file(s) (see mini-os.mk) +SPEC_DEP = arch.mk + +# include arch.mk has to be before mini-os.mk! +include arch.mk +include ../../minios.mk + +# Sources here are all *.c *.S without $(TARGET_ARCH).S +# This is handled in $(HEAD_ARCH_OBJ) +ARCH_SRCS := $(wildcard *.c) + +# The objects built from the sources. +ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS)) + +all: $(ARCH_LIB) + +# $(HEAD_ARCH_OBJ) is only build here, needed on linking +# in ../../Makefile. +$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ) + $(AR) rv $(ARCH_LIB) $(ARCH_OBJS) + +clean: + rm -f $(ARCH_LIB) $(ARCH_OBJS) + diff --git a/extras/mini-os/arch/x86/arch.mk b/extras/mini-os/arch/x86/arch.mk new file mode 100644 index 0000000000..5d0ee4add7 --- /dev/null +++ b/extras/mini-os/arch/x86/arch.mk @@ -0,0 +1,28 @@ +# +# Architecture special makerules for x86 family +# (including x86_32, x86_32y and x86_64). +# + +ifeq ($(TARGET_ARCH),x86_32) +ARCH_CFLAGS := -m32 -march=i686 +ARCH_LDFLAGS := -m elf_i386 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) +EXTRA_SRC += arch/$(EXTRA_INC) +endif + +ifeq ($(TARGET_ARCH)$(pae),x86_32y) +ARCH_CFLAGS := -DCONFIG_X86_PAE=1 +ARCH_ASFLAGS := -DCONFIG_X86_PAE=1 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) +EXTRA_SRC += arch/$(EXTRA_INC) +endif + +ifeq ($(TARGET_ARCH),x86_64) +ARCH_CFLAGS := -m64 -mno-red-zone -fpic -fno-reorder-blocks +ARCH_CFLAGS := -fno-asynchronous-unwind-tables +ARCH_LDFLAGS := -m elf_x86_64 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) +EXTRA_SRC += arch/$(EXTRA_INC) +endif + + diff --git a/extras/mini-os/minios-x86_32.lds b/extras/mini-os/arch/x86/minios-x86_32.lds similarity index 100% rename from extras/mini-os/minios-x86_32.lds rename to extras/mini-os/arch/x86/minios-x86_32.lds diff --git a/extras/mini-os/minios-x86_64.lds b/extras/mini-os/arch/x86/minios-x86_64.lds similarity index 100% rename from extras/mini-os/minios-x86_64.lds rename to extras/mini-os/arch/x86/minios-x86_64.lds diff --git a/extras/mini-os/x86_32.S b/extras/mini-os/arch/x86/x86_32.S similarity index 100% rename from extras/mini-os/x86_32.S rename to extras/mini-os/arch/x86/x86_32.S diff --git a/extras/mini-os/x86_64.S b/extras/mini-os/arch/x86/x86_64.S similarity index 100% rename from extras/mini-os/x86_64.S rename to extras/mini-os/arch/x86/x86_64.S diff --git a/extras/mini-os/minios.mk b/extras/mini-os/minios.mk new file mode 100644 index 0000000000..47542a5852 --- /dev/null +++ b/extras/mini-os/minios.mk @@ -0,0 +1,62 @@ +# +# The file contains the common make rules for building mini-os. +# + +debug = y + +# Define some default flags. +# NB. '-Wcast-qual' is nasty, so I omitted it. +DEF_CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format +DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline +DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION) + +DEF_ASFLAGS = -D__ASSEMBLY__ + +ifeq ($(debug),y) +DEF_CFLAGS += -g +else +DEF_CFLAGS += -O3 +endif + +# Build the CFLAGS and ASFLAGS for compiling and assembling. +# DEF_... flags are the common mini-os flags, +# ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk +CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS) +ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS) + +# The path pointing to the architecture specific header files. +ARCH_SPEC_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM) + +# Find all header files for checking dependencies. +HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h) +HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h) +HDRS += $(wildcard $(ARCH_SPEC_INC)/*.h) +# For special wanted header directories. +extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h)) +HDRS += $(extra_heads) + +# Add the special header directories to the include paths. +extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir)) +override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_SPEC_INC) $(extra_incl) + +# The name of the architecture specific library. +# This is on x86_32: libx86_32.a +# $(ARCH_LIB) has to built in the architecture specific directory. +ARCH_LIB_NAME = $(TARGET_ARCH) +ARCH_LIB := lib$(ARCH_LIB_NAME).a + +# This object contains the entrypoint for startup from Xen. +# $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory. +HEAD_ARCH_OBJ := $(TARGET_ARCH).o +HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ) + + +%.o: %.c $(HDRS) Makefile $(SPEC_DEPENDS) + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.o: %.S $(HDRS) Makefile $(SPEC_DEPENDS) + $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@ + + + + diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c index 926ba175c3..756c13e586 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c @@ -85,7 +85,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ { ssize_t ret; - if (len < DEFAULT_UCODE_TOTALSIZE) { + if (len < MC_HEADER_SIZE) { printk(KERN_ERR "microcode: not enough data\n"); return -EINVAL; } diff --git a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c index cd40fabc08..7e52b47b04 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c @@ -232,9 +232,12 @@ static void dump_fault_path(unsigned long address) p += (address >> 21) * 2; printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", page, p[1], p[0]); -#ifndef CONFIG_HIGHPTE + mfn = (p[0] >> PAGE_SHIFT) | (p[1] << 20); +#ifdef CONFIG_HIGHPTE + if (mfn_to_pfn(mfn) >= highstart_pfn) + return; +#endif if (p[0] & 1) { - mfn = (p[0] >> PAGE_SHIFT) | (p[1] << 20); page = mfn_to_pfn(mfn) << PAGE_SHIFT; p = (unsigned long *) __va(page); address &= 0x001fffff; @@ -242,7 +245,6 @@ static void dump_fault_path(unsigned long address) printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n", page, p[1], p[0]); } -#endif } } #else @@ -254,13 +256,16 @@ static void dump_fault_path(unsigned long address) page = ((unsigned long *) __va(page))[address >> 22]; printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page, machine_to_phys(page)); +#ifdef CONFIG_HIGHPTE /* * We must not directly access the pte in the highpte - * case, the page table might be allocated in highmem. + * case if the page table is located in highmem. * And lets rather not kmap-atomic the pte, just in case * it's allocated already. */ -#ifndef CONFIG_HIGHPTE + if ((page >> PAGE_SHIFT) >= highstart_pfn) + return; +#endif if (page & 1) { page &= PAGE_MASK; address &= 0x003ff000; @@ -269,7 +274,6 @@ static void dump_fault_path(unsigned long address) printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page, machine_to_phys(page)); } -#endif } #endif diff --git a/tools/libfsimage/common/Makefile b/tools/libfsimage/common/Makefile index 6efce44f02..9a62e9bbb5 100644 --- a/tools/libfsimage/common/Makefile +++ b/tools/libfsimage/common/Makefile @@ -1,7 +1,7 @@ XEN_ROOT = ../../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 1.0 +MAJOR = 1.1 MINOR = 0 CFLAGS += -Werror -Wp,-MD,.$(@F).d diff --git a/tools/libfsimage/common/fsimage.c b/tools/libfsimage/common/fsimage.c index a326fd7644..08262f81ce 100644 --- a/tools/libfsimage/common/fsimage.c +++ b/tools/libfsimage/common/fsimage.c @@ -74,7 +74,7 @@ void fsi_close_fsimage(fsi_t *fsi) pthread_mutex_lock(&fsi_lock); fsi->f_plugin->fp_ops->fpo_umount(fsi); (void) close(fsi->f_fd); - fsip_fs_free(fsi); + free(fsi); pthread_mutex_unlock(&fsi_lock); } diff --git a/tools/libfsimage/common/fsimage_grub.c b/tools/libfsimage/common/fsimage_grub.c index 252445f58e..99481064a9 100644 --- a/tools/libfsimage/common/fsimage_grub.c +++ b/tools/libfsimage/common/fsimage_grub.c @@ -193,6 +193,7 @@ fsig_mount(fsi_t *fsi, const char *path) static int fsig_umount(fsi_t *fsi) { + free(fsi->f_data); return (0); } @@ -250,6 +251,7 @@ fsig_read(fsi_file_t *ffi, void *buf, size_t nbytes) static int fsig_close(fsi_file_t *ffi) { + free(ffi->ff_data); fsip_file_free(ffi); return (0); } diff --git a/tools/libfsimage/common/fsimage_plugin.c b/tools/libfsimage/common/fsimage_plugin.c index 71099ba2ff..f961648164 100644 --- a/tools/libfsimage/common/fsimage_plugin.c +++ b/tools/libfsimage/common/fsimage_plugin.c @@ -40,13 +40,6 @@ fsip_fs_set_data(fsi_t *fsi, void *data) fsi->f_data = data; } -void -fsip_fs_free(fsi_t *fsi) -{ - free(fsi->f_data); - free(fsi); -} - fsi_file_t * fsip_file_alloc(fsi_t *fsi, void *data) { @@ -64,7 +57,6 @@ fsip_file_alloc(fsi_t *fsi, void *data) void fsip_file_free(fsi_file_t *ffi) { - free(ffi->ff_data); free(ffi); } diff --git a/tools/libfsimage/common/fsimage_plugin.h b/tools/libfsimage/common/fsimage_plugin.h index 4592e08be7..f1c83fab95 100644 --- a/tools/libfsimage/common/fsimage_plugin.h +++ b/tools/libfsimage/common/fsimage_plugin.h @@ -50,11 +50,10 @@ typedef fsi_plugin_ops_t * (*fsi_plugin_init_t)(int, fsi_plugin_t *, const char **); void fsip_fs_set_data(fsi_t *, void *); -void fsip_fs_free(fsi_t *); fsi_file_t *fsip_file_alloc(fsi_t *, void *); void fsip_file_free(fsi_file_t *); -fsi_t * fsip_fs(fsi_file_t *ffi); -uint64_t fsip_fs_offset(fsi_t *fsi); +fsi_t *fsip_fs(fsi_file_t *); +uint64_t fsip_fs_offset(fsi_t *); void *fsip_fs_data(fsi_t *); void *fsip_file_data(fsi_file_t *); diff --git a/tools/libfsimage/common/mapfile-GNU b/tools/libfsimage/common/mapfile-GNU index f15060cba4..4bffdeafb0 100644 --- a/tools/libfsimage/common/mapfile-GNU +++ b/tools/libfsimage/common/mapfile-GNU @@ -1,5 +1,5 @@ VERSION { - libfsimage.so.1.1 { + libfsimage.so.1.0 { global: fsi_open_fsimage; fsi_close_fsimage; @@ -10,7 +10,6 @@ VERSION { fsi_pread_file; fsip_fs_set_data; - fsip_fs_free; fsip_file_alloc; fsip_file_free; fsip_fs; diff --git a/tools/libfsimage/common/mapfile-SunOS b/tools/libfsimage/common/mapfile-SunOS index 1ea38bed04..63f17e1832 100644 --- a/tools/libfsimage/common/mapfile-SunOS +++ b/tools/libfsimage/common/mapfile-SunOS @@ -1,4 +1,4 @@ -libfsimage.so.1.1 { +libfsimage.so.1.0 { global: fsi_open_fsimage; fsi_close_fsimage; @@ -9,7 +9,6 @@ libfsimage.so.1.1 { fsi_pread_file; fsip_fs_set_data; - fsip_fs_free; fsip_file_alloc; fsip_file_free; fsip_fs; diff --git a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c index b6f60ce65f..aa8e7a63f4 100644 --- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c +++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c @@ -58,9 +58,11 @@ ext2lib_umount(fsi_t *fsi) { ext2_filsys *fs = fsip_fs_data(fsi); if (ext2fs_close(*fs) != 0) { + free(fs); errno = EINVAL; return (-1); } + free(fs); return (0); } diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 8066d5a047..a92e77a8a6 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -741,7 +741,7 @@ static int setup_guest(int xc_handle, /* * Enable shadow translate mode. This must happen after * populate physmap because the p2m reservation is based on - * the domains current memory allocation. + * the domain's current memory allocation. */ if ( xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE, diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 827c45693e..10e03971ab 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -12,7 +12,7 @@ #include "xg_private.h" #include "xg_save_restore.h" -/* max mfn of the whole machine */ +/* max mfn of the current host machine */ static unsigned long max_mfn; /* virtual starting address of the hypervisor */ @@ -30,6 +30,9 @@ static xen_pfn_t *live_p2m = NULL; /* A table mapping each PFN to its new MFN. */ static xen_pfn_t *p2m = NULL; +/* A table of P2M mappings in the current region */ +static xen_pfn_t *p2m_batch = NULL; + static ssize_t read_exact(int fd, void *buf, size_t count) @@ -57,46 +60,78 @@ read_exact(int fd, void *buf, size_t count) ** This function inverts that operation, replacing the pfn values with ** the (now known) appropriate mfn values. */ -static int uncanonicalize_pagetable(unsigned long type, void *page) +static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, + unsigned long type, void *page) { int i, pte_last; unsigned long pfn; uint64_t pte; + int nr_mfns = 0; pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8); - /* Now iterate through the page table, uncanonicalizing each PTE */ + /* First pass: work out how many (if any) MFNs we need to alloc */ + for(i = 0; i < pte_last; i++) { + + if(pt_levels == 2) + pte = ((uint32_t *)page)[i]; + else + pte = ((uint64_t *)page)[i]; + + /* XXX SMH: below needs fixing for PROT_NONE etc */ + if(!(pte & _PAGE_PRESENT)) + continue; + + pfn = (pte >> PAGE_SHIFT) & 0xffffffff; + + if(pfn >= max_pfn) { + /* This "page table page" is probably not one; bail. */ + ERROR("Frame number in type %lu page table is out of range: " + "i=%d pfn=0x%lx max_pfn=%lu", + type >> 28, i, pfn, max_pfn); + return 0; + } + + if(p2m[pfn] == INVALID_P2M_ENTRY) { + /* Have a 'valid' PFN without a matching MFN - need to alloc */ + p2m_batch[nr_mfns++] = pfn; + } + } + + + /* Alllocate the requistite number of mfns */ + if (nr_mfns && xc_domain_memory_populate_physmap( + xc_handle, dom, nr_mfns, 0, 0, p2m_batch) != 0) { + ERROR("Failed to allocate memory for batch.!\n"); + errno = ENOMEM; + return 0; + } + + /* Second pass: uncanonicalize each present PTE */ + nr_mfns = 0; for(i = 0; i < pte_last; i++) { if(pt_levels == 2) pte = ((uint32_t *)page)[i]; else pte = ((uint64_t *)page)[i]; + + /* XXX SMH: below needs fixing for PROT_NONE etc */ + if(!(pte & _PAGE_PRESENT)) + continue; + + pfn = (pte >> PAGE_SHIFT) & 0xffffffff; + + if(p2m[pfn] == INVALID_P2M_ENTRY) + p2m[pfn] = p2m_batch[nr_mfns++]; - if(pte & _PAGE_PRESENT) { + pte &= 0xffffff0000000fffULL; + pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT; - pfn = (pte >> PAGE_SHIFT) & 0xffffffff; - - if(pfn >= max_pfn) { - /* This "page table page" is probably not one; bail. */ - ERROR("Frame number in type %lu page table is out of range: " - "i=%d pfn=0x%lx max_pfn=%lu", - type >> 28, i, pfn, max_pfn); - return 0; - } - - - pte &= 0xffffff0000000fffULL; - pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT; - - if(pt_levels == 2) - ((uint32_t *)page)[i] = (uint32_t)pte; - else - ((uint64_t *)page)[i] = (uint64_t)pte; - - - - } + if(pt_levels == 2) + ((uint32_t *)page)[i] = (uint32_t)pte; + else + ((uint64_t *)page)[i] = (uint64_t)pte; } return 1; @@ -140,6 +175,7 @@ int xc_linux_restore(int xc_handle, int io_fd, /* A temporary mapping of the guest's start_info page. */ start_info_t *start_info; + /* Our mapping of the current region (batch) */ char *region_base; xc_mmu_t *mmu = NULL; @@ -244,8 +280,10 @@ int xc_linux_restore(int xc_handle, int io_fd, p2m = calloc(max_pfn, sizeof(xen_pfn_t)); pfn_type = calloc(max_pfn, sizeof(unsigned long)); region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t)); + p2m_batch = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t)); - if ((p2m == NULL) || (pfn_type == NULL) || (region_mfn == NULL)) { + if ((p2m == NULL) || (pfn_type == NULL) || + (region_mfn == NULL) || (p2m_batch == NULL)) { ERROR("memory alloc failed"); errno = ENOMEM; goto out; @@ -256,6 +294,11 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } + if (lock_pages(p2m_batch, sizeof(xen_pfn_t) * MAX_BATCH_SIZE)) { + ERROR("Could not lock p2m_batch"); + goto out; + } + /* Get the domain's shared-info frame. */ domctl.cmd = XEN_DOMCTL_getdomaininfo; domctl.domain = (domid_t)dom; @@ -270,17 +313,9 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } + /* Mark all PFNs as invalid; we allocate on demand */ for ( pfn = 0; pfn < max_pfn; pfn++ ) - p2m[pfn] = pfn; - - if (xc_domain_memory_populate_physmap(xc_handle, dom, max_pfn, - 0, 0, p2m) != 0) { - ERROR("Failed to increase reservation by %lx KB", PFN_TO_KB(max_pfn)); - errno = ENOMEM; - goto out; - } - - DPRINTF("Increased domain reservation by %lx KB\n", PFN_TO_KB(max_pfn)); + p2m[pfn] = INVALID_P2M_ENTRY; if(!(mmu = xc_init_mmu_updates(xc_handle, dom))) { ERROR("Could not initialise for MMU updates"); @@ -298,7 +333,7 @@ int xc_linux_restore(int xc_handle, int io_fd, n = 0; while (1) { - int j; + int j, nr_mfns = 0; this_pc = (n * 100) / max_pfn; if ( (this_pc - prev_pc) >= 5 ) @@ -333,6 +368,33 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } + /* First pass for this batch: work out how much memory to alloc */ + nr_mfns = 0; + for ( i = 0; i < j; i++ ) + { + unsigned long pfn, pagetype; + pfn = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK; + pagetype = region_pfn_type[i] & XEN_DOMCTL_PFINFO_LTAB_MASK; + + if ( (pagetype != XEN_DOMCTL_PFINFO_XTAB) && + (p2m[pfn] == INVALID_P2M_ENTRY) ) + { + /* Have a live PFN which hasn't had an MFN allocated */ + p2m_batch[nr_mfns++] = pfn; + } + } + + + /* Now allocate a bunch of mfns for this batch */ + if (nr_mfns && xc_domain_memory_populate_physmap( + xc_handle, dom, nr_mfns, 0, 0, p2m_batch) != 0) { + ERROR("Failed to allocate memory for batch.!\n"); + errno = ENOMEM; + goto out; + } + + /* Second pass for this batch: update p2m[] and region_mfn[] */ + nr_mfns = 0; for ( i = 0; i < j; i++ ) { unsigned long pfn, pagetype; @@ -340,13 +402,23 @@ int xc_linux_restore(int xc_handle, int io_fd, pagetype = region_pfn_type[i] & XEN_DOMCTL_PFINFO_LTAB_MASK; if ( pagetype == XEN_DOMCTL_PFINFO_XTAB) - region_mfn[i] = 0; /* we know map will fail, but don't care */ - else - region_mfn[i] = p2m[pfn]; - } + region_mfn[i] = ~0UL; /* map will fail but we don't care */ + else + { + if (p2m[pfn] == INVALID_P2M_ENTRY) { + /* We just allocated a new mfn above; update p2m */ + p2m[pfn] = p2m_batch[nr_mfns++]; + } + /* setup region_mfn[] for batch map */ + region_mfn[i] = p2m[pfn]; + } + } + + /* Map relevant mfns */ region_base = xc_map_foreign_batch( xc_handle, dom, PROT_WRITE, region_mfn, j); + if ( region_base == NULL ) { ERROR("map batch failed"); @@ -401,7 +473,8 @@ int xc_linux_restore(int xc_handle, int io_fd, pae_extended_cr3 || (pagetype != XEN_DOMCTL_PFINFO_L1TAB)) { - if (!uncanonicalize_pagetable(pagetype, page)) { + if (!uncanonicalize_pagetable(xc_handle, dom, + pagetype, page)) { /* ** Failing to uncanonicalize a page table can be ok ** under live migration since the pages type may have @@ -411,10 +484,8 @@ int xc_linux_restore(int xc_handle, int io_fd, pagetype >> 28, pfn, mfn); nraces++; continue; - } - + } } - } else if ( pagetype != XEN_DOMCTL_PFINFO_NOTAB ) { @@ -486,7 +557,7 @@ int xc_linux_restore(int xc_handle, int io_fd, */ int j, k; - + /* First pass: find all L3TABs current in > 4G mfns and get new mfns */ for ( i = 0; i < max_pfn; i++ ) { @@ -555,7 +626,8 @@ int xc_linux_restore(int xc_handle, int io_fd, } for(k = 0; k < j; k++) { - if(!uncanonicalize_pagetable(XEN_DOMCTL_PFINFO_L1TAB, + if(!uncanonicalize_pagetable(xc_handle, dom, + XEN_DOMCTL_PFINFO_L1TAB, region_base + k*PAGE_SIZE)) { ERROR("failed uncanonicalize pt!"); goto out; @@ -631,7 +703,7 @@ int xc_linux_restore(int xc_handle, int io_fd, { unsigned int count; unsigned long *pfntab; - int rc; + int nr_frees, rc; if (!read_exact(io_fd, &count, sizeof(count))) { ERROR("Error when reading pfn count"); @@ -648,29 +720,30 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } + nr_frees = 0; for (i = 0; i < count; i++) { unsigned long pfn = pfntab[i]; - if(pfn > max_pfn) - /* shouldn't happen - continue optimistically */ - continue; - - pfntab[i] = p2m[pfn]; - p2m[pfn] = INVALID_P2M_ENTRY; // not in pseudo-physical map + if(p2m[pfn] != INVALID_P2M_ENTRY) { + /* pfn is not in physmap now, but was at some point during + the save/migration process - need to free it */ + pfntab[nr_frees++] = p2m[pfn]; + p2m[pfn] = INVALID_P2M_ENTRY; // not in pseudo-physical map + } } - if (count > 0) { + if (nr_frees > 0) { struct xen_memory_reservation reservation = { - .nr_extents = count, + .nr_extents = nr_frees, .extent_order = 0, .domid = dom }; set_xen_guest_handle(reservation.extent_start, pfntab); if ((rc = xc_memory_op(xc_handle, XENMEM_decrease_reservation, - &reservation)) != count) { + &reservation)) != nr_frees) { ERROR("Could not decrease reservation : %d", rc); goto out; } else @@ -791,6 +864,6 @@ int xc_linux_restore(int xc_handle, int io_fd, free(pfn_type); DPRINTF("Restore exit with rc=%d\n", rc); - + return rc; } diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index 7ca8453848..ef64d1ef50 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -660,13 +660,6 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - /* cheesy sanity check */ - if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) { - ERROR("Invalid state record -- pfn count out of range: %lu", - (info.max_memkb >> (PAGE_SHIFT - 10))); - goto out; - } - /* Map the shared info frame */ if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, shared_info_frame))) { diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index 13b05d9a67..a0de67df67 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -405,6 +405,9 @@ class Grub: c = self.screen.getch() if mytime != -1: mytime += 1 + if mytime >= int(timeout): + self.isdone = True + break # handle keypresses if c == ord('c'): diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index 85a59e5d22..106e20fb3d 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -147,18 +147,20 @@ def restore(xd, fd, dominfo = None, paused = False): assert store_port assert console_port + nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 + try: l = read_exact(fd, sizeof_unsigned_long, "not a valid guest state file: pfn count read") - nr_pfns = unpack("L", l)[0] # native sizeof long - if nr_pfns > 16*1024*1024: # XXX + max_pfn = unpack("L", l)[0] # native sizeof long + if max_pfn > 16*1024*1024: # XXX raise XendError( "not a valid guest state file: pfn count out of range") balloon.free(xc.pages_to_kib(nr_pfns)) cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE), - fd, dominfo.getDomid(), nr_pfns, + fd, dominfo.getDomid(), max_pfn, store_port, console_port]) log.debug("[xc_restore]: %s", string.join(cmd)) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index b264b79f32..fd9afb0b3a 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -126,6 +126,7 @@ XENAPI_CFG_TYPES = { 'memory_dynamic_min': int, 'memory_dynamic_max': int, 'memory_actual': int, + 'cpus': list, 'vcpus_policy': str, 'vcpus_params': str, 'vcpus_number': int, diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 117ca3d25d..932c05d207 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -365,14 +365,24 @@ class XendNode: return [[k, info[k]] for k in ITEM_ORDER] + def xenschedinfo(self): + sched_id = self.xc.sched_id_get() + if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF: + return 'sedf' + elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT: + return 'credit' + else: + return 'unknown' def xeninfo(self): info = self.xc.xeninfo() + info['xen_scheduler'] = self.xenschedinfo() ITEM_ORDER = ['xen_major', 'xen_minor', 'xen_extra', 'xen_caps', + 'xen_scheduler', 'xen_pagesize', 'platform_params', 'xen_changeset', diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index 1ebe2bb6dd..2d8d49e43f 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -118,7 +118,8 @@ int main(int argc, char **argv) #endif ctxt.regs = ®s; - ctxt.address_bytes = 4; + ctxt.addr_size = 32; + ctxt.sp_size = 32; res = mmap((void *)0x100000, MMAP_SZ, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c index a81ae57722..1ab512d2ee 100644 --- a/xen/arch/x86/hvm/i8254.c +++ b/xen/arch/x86/hvm/i8254.c @@ -182,11 +182,9 @@ void pit_time_fired(struct vcpu *v, void *priv) s->count_load_time = hvm_get_guest_time(v); } -static inline void pit_load_count(PITChannelState *s, int val) +static inline void pit_load_count(PITChannelState *s, int channel, int val) { u32 period; - PITChannelState *ch0 = - ¤t->domain->arch.hvm_domain.pl_time.vpit.channels[0]; if (val == 0) val = 0x10000; @@ -194,7 +192,7 @@ static inline void pit_load_count(PITChannelState *s, int val) s->count = val; period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ); - if (s != ch0) + if (channel != 0) return; #ifdef DEBUG_PIT @@ -282,17 +280,17 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) switch(s->write_state) { default: case RW_STATE_LSB: - pit_load_count(s, val); + pit_load_count(s, addr, val); break; case RW_STATE_MSB: - pit_load_count(s, val << 8); + pit_load_count(s, addr, val << 8); break; case RW_STATE_WORD0: s->write_latch = val; s->write_state = RW_STATE_WORD1; break; case RW_STATE_WORD1: - pit_load_count(s, s->write_latch | (val << 8)); + pit_load_count(s, addr, s->write_latch | (val << 8)); s->write_state = RW_STATE_WORD0; break; } @@ -369,7 +367,7 @@ static void pit_reset(void *opaque) destroy_periodic_time(&s->pt); s->mode = 0xff; /* the init mode */ s->gate = (i != 2); - pit_load_count(s, 0); + pit_load_count(s, i, 0); } } diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2a3e6370d6..ba3121618e 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -482,8 +482,8 @@ static int svm_guest_x86_mode(struct vcpu *v) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - if ( vmcb->efer & EFER_LMA ) - return (vmcb->cs.attr.fields.l ? 8 : 4); + if ( (vmcb->efer & EFER_LMA) && vmcb->cs.attr.fields.l ) + return 8; if ( svm_realmode(v) ) return 2; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 74e0776016..a665367c6d 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -491,8 +491,7 @@ static unsigned long vmx_get_segment_base(struct vcpu *v, enum x86_segment seg) ASSERT(v == current); #ifdef __x86_64__ - if ( vmx_long_mode_enabled(v) && - (__vmread(GUEST_CS_AR_BYTES) & (1u<<13)) ) + if ( vmx_long_mode_enabled(v) && (__vmread(GUEST_CS_AR_BYTES) & (1u<<13)) ) long_mode = 1; #endif @@ -667,8 +666,8 @@ static int vmx_guest_x86_mode(struct vcpu *v) cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES); - if ( vmx_long_mode_enabled(v) ) - return ((cs_ar_bytes & (1u<<13)) ? 8 : 4); + if ( vmx_long_mode_enabled(v) && (cs_ar_bytes & (1u<<13)) ) + return 8; if ( vmx_realmode(v) ) return 2; diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index 3dcac7d124..89138c9a79 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -249,14 +249,14 @@ static int find_matching_ucodes (void) } total_size = get_totalsize(&mc_header); - if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { + if (cursor + total_size > user_buffer_size) { printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); error = -EINVAL; goto out; } data_size = get_datasize(&mc_header); - if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { + if (data_size + MC_HEADER_SIZE > total_size) { printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); error = -EINVAL; goto out; @@ -459,11 +459,6 @@ int microcode_update(XEN_GUEST_HANDLE(void) buf, unsigned long len) { int ret; - if (len < DEFAULT_UCODE_TOTALSIZE) { - printk(KERN_ERR "microcode: not enough data\n"); - return -EINVAL; - } - if (len != (typeof(user_buffer_size))len) { printk(KERN_ERR "microcode: too much data\n"); return -E2BIG; diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index a4b93f2b70..406941516d 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3236,15 +3236,14 @@ static int ptwr_emulated_update( if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) ) { if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) && - (bytes == 4) && - !do_cmpxchg && + (bytes == 4) && (addr & 4) && !do_cmpxchg && (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) { /* - * If this is a half-write to a PAE PTE then we assume that the - * guest has simply got the two writes the wrong way round. We - * zap the PRESENT bit on the assumption the bottom half will be - * written immediately after we return to the guest. + * If this is an upper-half write to a PAE PTE then we assume that + * the guest has simply got the two writes the wrong way round. We + * zap the PRESENT bit on the assumption that the bottom half will + * be written immediately after we return to the guest. */ MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte, l1e_get_intpte(nl1e)); @@ -3375,8 +3374,9 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, (page_get_owner(page) != d) ) goto bail; - ptwr_ctxt.ctxt.regs = guest_cpu_user_regs(); - ptwr_ctxt.ctxt.address_bytes = IS_COMPAT(d) ? 4 : sizeof(long); + ptwr_ctxt.ctxt.regs = regs; + ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size = + IS_COMPAT(d) ? 32 : BITS_PER_LONG; ptwr_ctxt.cr2 = addr; ptwr_ctxt.pte = pte; if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 8cee158842..115ad74d72 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -110,7 +110,7 @@ static int hvm_translate_linear_addr( unsigned long limit, addr = offset; uint32_t last_byte; - if ( sh_ctxt->ctxt.address_bytes != 8 ) + if ( sh_ctxt->ctxt.addr_size != 64 ) { /* * COMPATIBILITY MODE: Apply segment checks and add base. @@ -399,7 +399,7 @@ static struct x86_emulate_ops pv_shadow_emulator_ops = { struct x86_emulate_ops *shadow_init_emulation( struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs) { - struct segment_register *creg; + struct segment_register *creg, *sreg; struct vcpu *v = current; unsigned long addr; @@ -407,7 +407,7 @@ struct x86_emulate_ops *shadow_init_emulation( if ( !is_hvm_vcpu(v) ) { - sh_ctxt->ctxt.address_bytes = sizeof(long); + sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = BITS_PER_LONG; return &pv_shadow_emulator_ops; } @@ -416,12 +416,20 @@ struct x86_emulate_ops *shadow_init_emulation( creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt); /* Work out the emulation mode. */ - if ( hvm_long_mode_enabled(v) ) - sh_ctxt->ctxt.address_bytes = creg->attr.fields.l ? 8 : 4; + if ( hvm_long_mode_enabled(v) && creg->attr.fields.l ) + { + sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = 64; + } else if ( regs->eflags & X86_EFLAGS_VM ) - sh_ctxt->ctxt.address_bytes = 2; + { + sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = 16; + } else - sh_ctxt->ctxt.address_bytes = creg->attr.fields.db ? 4 : 2; + { + sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt); + sh_ctxt->ctxt.addr_size = creg->attr.fields.db ? 32 : 16; + sh_ctxt->ctxt.sp_size = sreg->attr.fields.db ? 32 : 16; + } /* Attempt to prefetch whole instruction. */ sh_ctxt->insn_buf_bytes = diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index e040e60e71..0546cb1a66 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -3944,7 +3944,7 @@ sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src, if ( !skip ) sh_validate_guest_pt_write(v, mfn, addr, bytes); /* If we are writing zeros to this page, might want to unshadow */ - if ( likely(bytes >= 4) && (*(u32 *)addr == 0) ) + if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) ) check_for_early_unshadow(v, mfn); sh_unmap_domain_page(addr); @@ -3996,7 +3996,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, unsigned long vaddr, vaddr, prev, old, new, *(unsigned long *)addr, bytes); /* If we are writing zeros to this page, might want to unshadow */ - if ( likely(bytes >= 4) && (*(u32 *)addr == 0) ) + if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) ) check_for_early_unshadow(v, mfn); sh_unmap_domain_page(addr); diff --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h index 913fa43770..21d78eb2de 100644 --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -427,6 +427,11 @@ extern int sh_remove_write_access(struct vcpu *v, mfn_t readonly_mfn, #undef mfn_valid #define mfn_valid(_mfn) (mfn_x(_mfn) < max_page) +#if GUEST_PAGING_LEVELS >= 3 +# define is_lo_pte(_vaddr) (((_vaddr)&0x4)==0) +#else +# define is_lo_pte(_vaddr) (1) +#endif static inline int sh_mfn_is_a_page_table(mfn_t gmfn) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index de5c35287c..7788961f36 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -443,10 +443,11 @@ do{ __asm__ __volatile__ ( \ }) #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type))) -#define _truncate_ea(ea, byte_width) \ -({ unsigned long __ea = (ea); \ - (((byte_width) == sizeof(unsigned long)) ? __ea : \ - (__ea & ((1UL << ((byte_width) << 3)) - 1))); \ +#define _truncate_ea(ea, byte_width) \ +({ unsigned long __ea = (ea); \ + unsigned int _width = (byte_width); \ + ((_width == sizeof(unsigned long)) ? __ea : \ + (__ea & ((1UL << (_width << 3)) - 1))); \ }) #define truncate_ea(ea) _truncate_ea((ea), ad_bytes) @@ -473,17 +474,28 @@ static int even_parity(uint8_t v) #define _register_address_increment(reg, inc, byte_width) \ do { \ int _inc = (inc); /* signed type ensures sign extension to long */ \ - if ( (byte_width) == sizeof(unsigned long) ) \ + unsigned int _width = (byte_width); \ + if ( _width == sizeof(unsigned long) ) \ (reg) += _inc; \ else if ( mode_64bit() ) \ - (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1); \ + (reg) = ((reg) + _inc) & ((1UL << (_width << 3)) - 1); \ else \ - (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) | \ - (((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1)); \ + (reg) = ((reg) & ~((1UL << (_width << 3)) - 1)) | \ + (((reg) + _inc) & ((1UL << (_width << 3)) - 1)); \ } while (0) #define register_address_increment(reg, inc) \ _register_address_increment((reg), (inc), ad_bytes) +#define sp_pre_dec(dec) ({ \ + _register_address_increment(_regs.esp, -(dec), ctxt->sp_size/8); \ + _truncate_ea(_regs.esp, ctxt->sp_size/8); \ +}) +#define sp_post_inc(inc) ({ \ + unsigned long __esp = _truncate_ea(_regs.esp, ctxt->sp_size/8); \ + _register_address_increment(_regs.esp, (inc), ctxt->sp_size/8); \ + __esp; \ +}) + #define jmp_rel(rel) \ do { \ _regs.eip += (int)(rel); \ @@ -679,7 +691,7 @@ x86_emulate( ea.mem.seg = x86_seg_ds; ea.mem.off = 0; - op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes; + op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8; if ( op_bytes == 8 ) { op_bytes = def_op_bytes = 4; @@ -1144,7 +1156,9 @@ x86_emulate( break; } - case 0x80 ... 0x83: /* Grp1 */ + case 0x82: /* Grp1 (x86/32 only) */ + generate_exception_if(mode_64bit(), EXC_UD); + case 0x80: case 0x81: case 0x83: /* Grp1 */ switch ( modrm_reg & 7 ) { case 0: goto add; @@ -1194,10 +1208,9 @@ x86_emulate( /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; - if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes), &dst.val, dst.bytes, ctxt)) != 0 ) goto done; - register_address_increment(_regs.esp, dst.bytes); break; case 0xb0 ... 0xb7: /* mov imm8,r8 */ @@ -1466,7 +1479,7 @@ x86_emulate( emulate_1op("dec", dst, _regs.eflags); break; case 2: /* call (near) */ - case 3: /* jmp (near) */ + case 4: /* jmp (near) */ if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() ) { dst.bytes = op_bytes = 8; @@ -1488,8 +1501,7 @@ x86_emulate( &dst.val, 8, ctxt)) != 0 ) goto done; } - register_address_increment(_regs.esp, -dst.bytes); - if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp), + if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes), dst.val, dst.bytes, ctxt)) != 0 ) goto done; dst.type = OP_NONE; @@ -1644,10 +1656,9 @@ x86_emulate( dst.bytes = op_bytes; if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; - if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes), &dst.val, dst.bytes, ctxt)) != 0 ) goto done; - register_address_increment(_regs.esp, dst.bytes); break; case 0x60: /* pusha */ { @@ -1657,11 +1668,9 @@ x86_emulate( _regs.esp, _regs.ebp, _regs.esi, _regs.edi }; generate_exception_if(mode_64bit(), EXC_UD); for ( i = 0; i < 8; i++ ) - if ( (rc = ops->write(x86_seg_ss, - truncate_ea(_regs.esp-(i+1)*op_bytes), + if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), regs[i], op_bytes, ctxt)) != 0 ) goto done; - register_address_increment(_regs.esp, -8*op_bytes); break; } @@ -1674,11 +1683,9 @@ x86_emulate( (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax }; generate_exception_if(mode_64bit(), EXC_UD); for ( i = 0; i < 8; i++ ) - if ( (rc = ops->read(x86_seg_ss, - truncate_ea(_regs.esp+i*op_bytes), + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), regs[i], op_bytes, ctxt)) != 0 ) goto done; - register_address_increment(_regs.esp, 8*op_bytes); break; } @@ -1697,9 +1704,8 @@ x86_emulate( if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; dst.val = src.val; - register_address_increment(_regs.esp, -dst.bytes); dst.mem.seg = x86_seg_ss; - dst.mem.off = truncate_ea(_regs.esp); + dst.mem.off = sp_pre_dec(dst.bytes); break; case 0x70 ... 0x7f: /* jcc (short) */ { @@ -1813,11 +1819,10 @@ x86_emulate( case 0xc3: /* ret (near) */ { int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0; op_bytes = mode_64bit() ? 8 : op_bytes; - if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes + offset), &dst.val, op_bytes, ctxt)) != 0 ) goto done; _regs.eip = dst.val; - register_address_increment(_regs.esp, op_bytes + offset); break; } @@ -2019,7 +2024,7 @@ x86_emulate( case 0xbc: /* bsf */ { int zf; - asm ( "bsf %2,%0; setc %b1" + asm ( "bsf %2,%0; setz %b1" : "=r" (dst.val), "=q" (zf) : "r" (src.val), "1" (0) ); _regs.eflags &= ~EFLG_ZF; @@ -2029,7 +2034,7 @@ x86_emulate( case 0xbd: /* bsr */ { int zf; - asm ( "bsr %2,%0; setc %b1" + asm ( "bsr %2,%0; setz %b1" : "=r" (dst.val), "=q" (zf) : "r" (src.val), "1" (0) ); _regs.eflags &= ~EFLG_ZF; @@ -2046,12 +2051,13 @@ x86_emulate( break; case 0xba: /* Grp8 */ - switch ( modrm_reg & 3 ) + switch ( modrm_reg & 7 ) { - case 0: goto bt; - case 1: goto bts; - case 2: goto btr; - case 3: goto btc; + case 4: goto bt; + case 5: goto bts; + case 6: goto btr; + case 7: goto btc; + default: generate_exception_if(1, EXC_UD); } break; @@ -2100,6 +2106,7 @@ x86_emulate( #if defined(__i386__) { unsigned long old_lo, old_hi; + generate_exception_if((modrm_reg & 7) != 1, EXC_UD); if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) || (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) ) goto done; @@ -2126,6 +2133,7 @@ x86_emulate( #elif defined(__x86_64__) { unsigned long old, new; + generate_exception_if((modrm_reg & 7) != 1, EXC_UD); if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 ) goto done; if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || diff --git a/xen/include/asm-powerpc/byteorder.h b/xen/include/asm-powerpc/byteorder.h new file mode 100644 index 0000000000..94bbea2929 --- /dev/null +++ b/xen/include/asm-powerpc/byteorder.h @@ -0,0 +1,80 @@ +#ifndef _ASM_POWERPC_BYTEORDER_H +#define _ASM_POWERPC_BYTEORDER_H + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + +static inline __u16 ld_le16(const volatile __u16 *addr) +{ + __u16 val; + + asm volatile ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); + return val; +} + +static inline void st_le16(volatile __u16 *addr, const __u16 val) +{ + asm volatile ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); +} + +static inline __u32 ld_le32(const volatile __u32 *addr) +{ + __u32 val; + + asm volatile ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); + return val; +} + +static inline void st_le32(volatile __u32 *addr, const __u32 val) +{ + asm volatile ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); +} + +static inline __attribute_const__ __u16 ___arch__swab16(__u16 value) +{ + __u16 result; + + asm("rlwimi %0,%1,8,16,23" + : "=r" (result) + : "r" (value), "0" (value >> 8)); + return result; +} + +static inline __attribute_const__ __u32 ___arch__swab32(__u32 value) +{ + __u32 result; + + asm("rlwimi %0,%1,24,16,23\n\t" + "rlwimi %0,%1,8,8,15\n\t" + "rlwimi %0,%1,24,0,7" + : "=r" (result) + : "r" (value), "0" (value >> 24)); + return result; +} + +#define __arch__swab16(x) ___arch__swab16(x) +#define __arch__swab32(x) ___arch__swab32(x) + +/* The same, but returns converted value from the location pointer by addr. */ +#define __arch__swab16p(addr) ld_le16(addr) +#define __arch__swab32p(addr) ld_le32(addr) + +/* The same, but do the conversion in situ, ie. put the value back to addr. */ +#define __arch__swab16s(addr) st_le16(addr,*addr) +#define __arch__swab32s(addr) st_le32(addr,*addr) + +#define __BYTEORDER_HAS_U64__ +#ifndef __powerpc64__ +#define __SWAB_64_THRU_32__ +#endif /* __powerpc64__ */ + +#include + +#endif /* _ASM_POWERPC_BYTEORDER_H */ diff --git a/xen/include/asm-x86/byteorder.h b/xen/include/asm-x86/byteorder.h new file mode 100644 index 0000000000..eb52ae2f11 --- /dev/null +++ b/xen/include/asm-x86/byteorder.h @@ -0,0 +1,36 @@ +#ifndef __ASM_X86_BYTEORDER_H__ +#define __ASM_X86_BYTEORDER_H__ + +#include +#include + +static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) +{ + asm("bswap %0" : "=r" (x) : "0" (x)); + return x; +} + +static inline __attribute_const__ __u64 ___arch__swab64(__u64 val) +{ + union { + struct { __u32 a,b; } s; + __u64 u; + } v; + v.u = val; + asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); + return v.u; +} + +/* Do not define swab16. Gcc is smart enough to recognize "C" version and + convert it into rotation or exhange. */ + +#define __arch__swab64(x) ___arch__swab64(x) +#define __arch__swab32(x) ___arch__swab32(x) + +#define __BYTEORDER_HAS_U64__ + +#include + +#endif /* __ASM_X86_BYTEORDER_H__ */ diff --git a/xen/include/asm-x86/x86_emulate.h b/xen/include/asm-x86/x86_emulate.h index 153bf14aac..45246b8044 100644 --- a/xen/include/asm-x86/x86_emulate.h +++ b/xen/include/asm-x86/x86_emulate.h @@ -150,8 +150,11 @@ struct x86_emulate_ctxt /* Register state before/after emulation. */ struct cpu_user_regs *regs; - /* Default address size in current execution mode (2, 4, or 8). */ - int address_bytes; + /* Default address size in current execution mode (16, 32, or 64). */ + unsigned int addr_size; + + /* Stack pointer width in bits (16, 32 or 64). */ + unsigned int sp_size; }; /* diff --git a/xen/include/xen/byteorder/big_endian.h b/xen/include/xen/byteorder/big_endian.h new file mode 100644 index 0000000000..8a815534e4 --- /dev/null +++ b/xen/include/xen/byteorder/big_endian.h @@ -0,0 +1,106 @@ +#ifndef __XEN_BYTEORDER_BIG_ENDIAN_H__ +#define __XEN_BYTEORDER_BIG_ENDIAN_H__ + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#include +#include + +#define __constant_htonl(x) ((__force __be32)(__u32)(x)) +#define __constant_ntohl(x) ((__force __u32)(__be32)(x)) +#define __constant_htons(x) ((__force __be16)(__u16)(x)) +#define __constant_ntohs(x) ((__force __u16)(__be16)(x)) +#define __constant_cpu_to_le64(x) ((__force __le64)___constant_swab64((x))) +#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64)(__le64)(x)) +#define __constant_cpu_to_le32(x) ((__force __le32)___constant_swab32((x))) +#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32)(__le32)(x)) +#define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x))) +#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16)(__le16)(x)) +#define __constant_cpu_to_be64(x) ((__force __be64)(__u64)(x)) +#define __constant_be64_to_cpu(x) ((__force __u64)(__be64)(x)) +#define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x)) +#define __constant_be32_to_cpu(x) ((__force __u32)(__be32)(x)) +#define __constant_cpu_to_be16(x) ((__force __be16)(__u16)(x)) +#define __constant_be16_to_cpu(x) ((__force __u16)(__be16)(x)) +#define __cpu_to_le64(x) ((__force __le64)__swab64((x))) +#define __le64_to_cpu(x) __swab64((__force __u64)(__le64)(x)) +#define __cpu_to_le32(x) ((__force __le32)__swab32((x))) +#define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) +#define __cpu_to_le16(x) ((__force __le16)__swab16((x))) +#define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x)) +#define __cpu_to_be64(x) ((__force __be64)(__u64)(x)) +#define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) +#define __cpu_to_be32(x) ((__force __be32)(__u32)(x)) +#define __be32_to_cpu(x) ((__force __u32)(__be32)(x)) +#define __cpu_to_be16(x) ((__force __be16)(__u16)(x)) +#define __be16_to_cpu(x) ((__force __u16)(__be16)(x)) + +static inline __le64 __cpu_to_le64p(const __u64 *p) +{ + return (__force __le64)__swab64p(p); +} +static inline __u64 __le64_to_cpup(const __le64 *p) +{ + return __swab64p((__u64 *)p); +} +static inline __le32 __cpu_to_le32p(const __u32 *p) +{ + return (__force __le32)__swab32p(p); +} +static inline __u32 __le32_to_cpup(const __le32 *p) +{ + return __swab32p((__u32 *)p); +} +static inline __le16 __cpu_to_le16p(const __u16 *p) +{ + return (__force __le16)__swab16p(p); +} +static inline __u16 __le16_to_cpup(const __le16 *p) +{ + return __swab16p((__u16 *)p); +} +static inline __be64 __cpu_to_be64p(const __u64 *p) +{ + return (__force __be64)*p; +} +static inline __u64 __be64_to_cpup(const __be64 *p) +{ + return (__force __u64)*p; +} +static inline __be32 __cpu_to_be32p(const __u32 *p) +{ + return (__force __be32)*p; +} +static inline __u32 __be32_to_cpup(const __be32 *p) +{ + return (__force __u32)*p; +} +static inline __be16 __cpu_to_be16p(const __u16 *p) +{ + return (__force __be16)*p; +} +static inline __u16 __be16_to_cpup(const __be16 *p) +{ + return (__force __u16)*p; +} +#define __cpu_to_le64s(x) __swab64s((x)) +#define __le64_to_cpus(x) __swab64s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) +#define __le32_to_cpus(x) __swab32s((x)) +#define __cpu_to_le16s(x) __swab16s((x)) +#define __le16_to_cpus(x) __swab16s((x)) +#define __cpu_to_be64s(x) do {} while (0) +#define __be64_to_cpus(x) do {} while (0) +#define __cpu_to_be32s(x) do {} while (0) +#define __be32_to_cpus(x) do {} while (0) +#define __cpu_to_be16s(x) do {} while (0) +#define __be16_to_cpus(x) do {} while (0) + +#include + +#endif /* __XEN_BYTEORDER_BIG_ENDIAN_H__ */ diff --git a/xen/include/xen/byteorder/generic.h b/xen/include/xen/byteorder/generic.h new file mode 100644 index 0000000000..8a0006b755 --- /dev/null +++ b/xen/include/xen/byteorder/generic.h @@ -0,0 +1,68 @@ +#ifndef __XEN_BYTEORDER_GENERIC_H__ +#define __XEN_BYTEORDER_GENERIC_H__ + +/* + * Generic Byte-reordering support + * + * The "... p" macros, like le64_to_cpup, can be used with pointers + * to unaligned data, but there will be a performance penalty on + * some architectures. Use get_unaligned for unaligned data. + * + * The following macros are to be defined by : + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + */ + +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus + +#endif /* __XEN_BYTEORDER_GENERIC_H__ */ diff --git a/xen/include/xen/byteorder/little_endian.h b/xen/include/xen/byteorder/little_endian.h new file mode 100644 index 0000000000..24ac42701e --- /dev/null +++ b/xen/include/xen/byteorder/little_endian.h @@ -0,0 +1,106 @@ +#ifndef __XEN_BYTEORDER_LITTLE_ENDIAN_H__ +#define __XEN_BYTEORDER_LITTLE_ENDIAN_H__ + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +#include +#include + +#define __constant_htonl(x) ((__force __be32)___constant_swab32((x))) +#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x)) +#define __constant_htons(x) ((__force __be16)___constant_swab16((x))) +#define __constant_ntohs(x) ___constant_swab16((__force __be16)(x)) +#define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x)) +#define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x)) +#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x)) +#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x)) +#define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x)) +#define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x)) +#define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x))) +#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x)) +#define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x))) +#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x)) +#define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x))) +#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x)) +#define __cpu_to_le64(x) ((__force __le64)(__u64)(x)) +#define __le64_to_cpu(x) ((__force __u64)(__le64)(x)) +#define __cpu_to_le32(x) ((__force __le32)(__u32)(x)) +#define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) +#define __cpu_to_le16(x) ((__force __le16)(__u16)(x)) +#define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) +#define __cpu_to_be64(x) ((__force __be64)__swab64((x))) +#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x)) +#define __cpu_to_be32(x) ((__force __be32)__swab32((x))) +#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x)) +#define __cpu_to_be16(x) ((__force __be16)__swab16((x))) +#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x)) + +static inline __le64 __cpu_to_le64p(const __u64 *p) +{ + return (__force __le64)*p; +} +static inline __u64 __le64_to_cpup(const __le64 *p) +{ + return (__force __u64)*p; +} +static inline __le32 __cpu_to_le32p(const __u32 *p) +{ + return (__force __le32)*p; +} +static inline __u32 __le32_to_cpup(const __le32 *p) +{ + return (__force __u32)*p; +} +static inline __le16 __cpu_to_le16p(const __u16 *p) +{ + return (__force __le16)*p; +} +static inline __u16 __le16_to_cpup(const __le16 *p) +{ + return (__force __u16)*p; +} +static inline __be64 __cpu_to_be64p(const __u64 *p) +{ + return (__force __be64)__swab64p(p); +} +static inline __u64 __be64_to_cpup(const __be64 *p) +{ + return __swab64p((__u64 *)p); +} +static inline __be32 __cpu_to_be32p(const __u32 *p) +{ + return (__force __be32)__swab32p(p); +} +static inline __u32 __be32_to_cpup(const __be32 *p) +{ + return __swab32p((__u32 *)p); +} +static inline __be16 __cpu_to_be16p(const __u16 *p) +{ + return (__force __be16)__swab16p(p); +} +static inline __u16 __be16_to_cpup(const __be16 *p) +{ + return __swab16p((__u16 *)p); +} +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) + +#include + +#endif /* __XEN_BYTEORDER_LITTLE_ENDIAN_H__ */ diff --git a/xen/include/xen/byteorder/swab.h b/xen/include/xen/byteorder/swab.h new file mode 100644 index 0000000000..0193ff83e7 --- /dev/null +++ b/xen/include/xen/byteorder/swab.h @@ -0,0 +1,185 @@ +#ifndef __XEN_BYTEORDER_SWAB_H__ +#define __XEN_BYTEORDER_SWAB_H__ + +/* + * Byte-swapping, independently from CPU endianness + * swabXX[ps]?(foo) + * + * Francois-Rene Rideau 19971205 + * separated swab functions from cpu_to_XX, + * to clean up support for bizarre-endian architectures. + */ + +#include + +/* casts are necessary for constants, because we never know how for sure + * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. + */ +#define ___swab16(x) \ +({ \ + __u16 __x = (x); \ + ((__u16)( \ + (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ +}) + +#define ___swab32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ +}) + +#define ___swab64(x) \ +({ \ + __u64 __x = (x); \ + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +}) + +#define ___constant_swab16(x) \ + ((__u16)( \ + (((__u16)(x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(x) & (__u16)0xff00U) >> 8) )) +#define ___constant_swab32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +#define ___constant_swab64(x) \ + ((__u64)( \ + (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) )) + +/* + * provide defaults when no architecture-specific optimization is detected + */ +#ifndef __arch__swab16 +# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); }) +#endif +#ifndef __arch__swab32 +# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); }) +#endif +#ifndef __arch__swab64 +# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); }) +#endif + +#ifndef __arch__swab16p +# define __arch__swab16p(x) __arch__swab16(*(x)) +#endif +#ifndef __arch__swab32p +# define __arch__swab32p(x) __arch__swab32(*(x)) +#endif +#ifndef __arch__swab64p +# define __arch__swab64p(x) __arch__swab64(*(x)) +#endif + +#ifndef __arch__swab16s +# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0) +#endif +#ifndef __arch__swab32s +# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0) +#endif +#ifndef __arch__swab64s +# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0) +#endif + + +/* + * Allow constant folding + */ +#if defined(__GNUC__) && defined(__OPTIMIZE__) +# define __swab16(x) \ +(__builtin_constant_p((__u16)(x)) ? \ + ___swab16((x)) : \ + __fswab16((x))) +# define __swab32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swab32((x)) : \ + __fswab32((x))) +# define __swab64(x) \ +(__builtin_constant_p((__u64)(x)) ? \ + ___swab64((x)) : \ + __fswab64((x))) +#else +# define __swab16(x) __fswab16(x) +# define __swab32(x) __fswab32(x) +# define __swab64(x) __fswab64(x) +#endif /* OPTIMIZE */ + + +static inline __attribute_const__ __u16 __fswab16(__u16 x) +{ + return __arch__swab16(x); +} +static inline __u16 __swab16p(const __u16 *x) +{ + return __arch__swab16p(x); +} +static inline void __swab16s(__u16 *addr) +{ + __arch__swab16s(addr); +} + +static inline __attribute_const__ __u32 __fswab32(__u32 x) +{ + return __arch__swab32(x); +} +static inline __u32 __swab32p(const __u32 *x) +{ + return __arch__swab32p(x); +} +static inline void __swab32s(__u32 *addr) +{ + __arch__swab32s(addr); +} + +#ifdef __BYTEORDER_HAS_U64__ +static inline __attribute_const__ __u64 __fswab64(__u64 x) +{ +# ifdef __SWAB_64_THRU_32__ + __u32 h = x >> 32; + __u32 l = x & ((1ULL<<32)-1); + return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h))); +# else + return __arch__swab64(x); +# endif +} +static inline __u64 __swab64p(const __u64 *x) +{ + return __arch__swab64p(x); +} +static inline void __swab64s(__u64 *addr) +{ + __arch__swab64s(addr); +} +#endif /* __BYTEORDER_HAS_U64__ */ + +#define swab16 __swab16 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab32s __swab32s +#define swab64s __swab64s + +#endif /* __XEN_BYTEORDER_SWAB_H__ */ diff --git a/xen/include/xen/config.h b/xen/include/xen/config.h index 068a550078..02e292b6d7 100644 --- a/xen/include/xen/config.h +++ b/xen/include/xen/config.h @@ -63,6 +63,8 @@ /* Linux 'checker' project. */ #define __iomem #define __user +#define __force +#define __bitwise #ifndef __ASSEMBLY__ diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h index 8bafc73156..fd89c98427 100644 --- a/xen/include/xen/types.h +++ b/xen/include/xen/types.h @@ -51,4 +51,11 @@ typedef __s64 int64_t; struct domain; struct vcpu; +typedef __u16 __le16; +typedef __u16 __be16; +typedef __u32 __le32; +typedef __u32 __be32; +typedef __u64 __le64; +typedef __u64 __be64; + #endif /* __TYPES_H__ */