diff --git a/.rootkeys b/.rootkeys index fbd8a2f9d4..ecf9e91ace 100644 --- a/.rootkeys +++ b/.rootkeys @@ -469,6 +469,7 @@ 413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.11/agpgart.patch 427261074Iy1MkbbqIV6zdZDWWx_Jg patches/linux-2.6.11/i386-cpu-hotplug-updated-for-mm.patch 42372652KCUP-IOH9RN19YQmGhs4aA patches/linux-2.6.11/iomap.patch +428359d4b3fDYtazwXi4UUmSWaOUew patches/linux-2.6.11/linux-2.6.11.8.patch 424f001e_M1Tnxc52rDrmCLelnDWMQ patches/linux-2.6.11/x86_64-linux.patch 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile 40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Rules.mk diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index 3f65adddad..723303c1ba 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -62,6 +62,7 @@ patches/ebtables-brnf-5_vs_2.4.25.diff patches/ebtables.diff patches/tmp/* pristine-* +ref-* tools/*/build/lib*/*.py tools/Makefile.smh tools/balloon/balloon @@ -89,8 +90,8 @@ tools/blktap/xen/* tools/check/.* tools/cmdline/* tools/cmdline/xen/* -tools/gdb/gdb-6.2.1/* tools/gdb/gdb-6.2.1-linux-i386-xen/* +tools/gdb/gdb-6.2.1/* tools/ioemu/iodev/device-model tools/libxc/xen/* tools/misc/cpuperf/cpuperf-perfcntr diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 379ce87a72..3cdc0126d1 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -80,6 +80,7 @@ rn@wyvis.camb.intel-research.net rn@wyvis.research.intel-research.net rneugeba@wyvis.research rneugeba@wyvis.research.intel-research.net +rusty@rustcorp.com.au ryanh@us.ibm.com sd386@font.cl.cam.ac.uk shand@spidean.research.intel-research.net diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index 58109fd619..11f4009525 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -43,6 +43,12 @@ netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2: netbsd-%.tar.bz2: netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2 ln -fs $< $@ +ifeq ($(OS),linux) +OS_VER = $(LINUX_VER) +else +OS_VER = $(NETBSD_VER) +endif + pristine-%: %.tar.bz2 rm -rf tmp-$(@F) $@ mkdir -p tmp-$(@F) @@ -51,9 +57,17 @@ pristine-%: %.tar.bz2 touch $@ # update timestamp to avoid rebuild touch $@/.bk_skip @rm -rf tmp-$(@F) + +OS_PATCHES = $(shell echo patches/$(OS)-$(OS_VER)/*.patch) + +ref-%: pristine-% $(OS_PATCHES) + rm -rf $@ + cp -al $< tmp-$(@F) [ -d patches/$* ] && \ - for i in patches/$*/*.patch ; do ( cd $@ ; patch -p1 <../$$i ) ; done || \ + for i in patches/$*/*.patch ; do ( cd tmp-$(@F) ; patch -p1 <../$$i ) ; done || \ true + mv tmp-$(@F) $@ + touch $@ # update timestamp to avoid rebuild %-build: $(MAKE) -f buildconfigs/mk.$* build @@ -67,7 +81,7 @@ pristine-%: %.tar.bz2 %-config: $(MAKE) -f buildconfigs/mk.$* config -%-xen.patch: pristine-% +%-xen.patch: ref-% rm -rf tmp-$@ cp -al $< tmp-$@ ( cd $*-xen-sparse && ./mkbuildtree ../tmp-$@ ) @@ -75,7 +89,7 @@ pristine-%: %.tar.bz2 rm -rf tmp-$@ %-mrproper: %-mrproper-extra - rm -rf pristine-$* $*.tar.bz2 + rm -rf pristine-$* ref-$* $*.tar.bz2 rm -rf $*-xen.patch netbsd-%-mrproper-extra: diff --git a/buildconfigs/mk.linux-2.4-xen0 b/buildconfigs/mk.linux-2.4-xen0 index 130cffba14..f48c27aec5 100644 --- a/buildconfigs/mk.linux-2.4-xen0 +++ b/buildconfigs/mk.linux-2.4-xen0 @@ -1,11 +1,13 @@ +OS = linux + LINUX_SERIES = 2.4 EXTRAVERSION = xen0 FULLVERSION = $(LINUX_VER)-$(EXTRAVERSION) -LINUX_DIR = linux-$(FULLVERSION) +LINUX_DIR = $(OS)-$(FULLVERSION) include buildconfigs/Rules.mk @@ -24,7 +26,7 @@ patches/tmp/ebtables.diff: wget http://www.cl.cam.ac.uk/netos/xen/downloads/ebtables-brnf-5_vs_2.4.27.diff.gz -O- | gunzip -c > $@ $(LINUX_DIR)/include/linux/autoconf.h: patches/tmp/ebtables.diff -$(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) +$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER) rm -rf $(LINUX_DIR) cp -al $< $(LINUX_DIR) # Apply arch-xen patches @@ -53,4 +55,4 @@ clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean delete: - rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) + rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) diff --git a/buildconfigs/mk.linux-2.4-xenU b/buildconfigs/mk.linux-2.4-xenU index 051f071cb0..e2fed22df3 100644 --- a/buildconfigs/mk.linux-2.4-xenU +++ b/buildconfigs/mk.linux-2.4-xenU @@ -1,11 +1,13 @@ +OS = linux + LINUX_SERIES = 2.4 EXTRAVERSION = xenU FULLVERSION = $(LINUX_VER)-$(EXTRAVERSION) -LINUX_DIR = linux-$(FULLVERSION) +LINUX_DIR = $(OS)-$(FULLVERSION) include buildconfigs/Rules.mk @@ -19,7 +21,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h fi $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install -$(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) +$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER) rm -rf $(LINUX_DIR) cp -al $< $(LINUX_DIR) # Apply arch-xen patches @@ -46,4 +48,4 @@ clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean delete: - rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) + rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) diff --git a/buildconfigs/mk.linux-2.6-xen0 b/buildconfigs/mk.linux-2.6-xen0 index c6992c96f1..4307b1ce37 100644 --- a/buildconfigs/mk.linux-2.6-xen0 +++ b/buildconfigs/mk.linux-2.6-xen0 @@ -1,11 +1,13 @@ +OS = linux + LINUX_SERIES = 2.6 EXTRAVERSION = xen0 FULLVERSION = $(LINUX_VER)-$(EXTRAVERSION) -LINUX_DIR = linux-$(FULLVERSION) +LINUX_DIR = $(OS)-$(FULLVERSION) include buildconfigs/Rules.mk @@ -19,7 +21,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h fi $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install -$(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) +$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER) rm -rf $(LINUX_DIR) cp -al $< $(LINUX_DIR) # Apply arch-xen patches @@ -44,4 +46,4 @@ clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean delete: - rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) + rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) diff --git a/buildconfigs/mk.linux-2.6-xenU b/buildconfigs/mk.linux-2.6-xenU index 9a600170f8..84375b6d96 100644 --- a/buildconfigs/mk.linux-2.6-xenU +++ b/buildconfigs/mk.linux-2.6-xenU @@ -1,11 +1,13 @@ +OS = linux + LINUX_SERIES = 2.6 EXTRAVERSION = xenU FULLVERSION = $(LINUX_VER)-$(EXTRAVERSION) -LINUX_DIR = linux-$(FULLVERSION) +LINUX_DIR = $(OS)-$(FULLVERSION) include buildconfigs/Rules.mk @@ -19,7 +21,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h fi $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install -$(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) +$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER) rm -rf $(LINUX_DIR) cp -al $< $(LINUX_DIR) # Apply arch-xen patches @@ -44,4 +46,4 @@ clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean delete: - rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) + rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) diff --git a/buildconfigs/mk.netbsd-2.0-xenU b/buildconfigs/mk.netbsd-2.0-xenU index 2e272aa6b3..bbe2e1fea9 100644 --- a/buildconfigs/mk.netbsd-2.0-xenU +++ b/buildconfigs/mk.netbsd-2.0-xenU @@ -1,4 +1,6 @@ +OS = netbsd + NETBSD_RELEASE ?= 2.0 NETBSD_CVSSNAP ?= 20050309 @@ -6,13 +8,13 @@ EXTRAVERSION = xenU FULLVERSION = $(NETBSD_VER)-$(EXTRAVERSION) -NETBSD_DIR = netbsd-$(FULLVERSION) +NETBSD_DIR = $(OS)-$(FULLVERSION) .PHONY: build clean mrproper mkpatch include buildconfigs/Rules.mk -build: netbsd-$(EXTRAVERSION) +build: $(OS)-$(EXTRAVERSION) netbsd-%-tools.tar.bz2: @echo "Cannot find netbsd-$(NETBSD_VER)-tools.tar.gz in path $(NETBSD_SRC_PATH)" @@ -22,7 +24,7 @@ netbsd-%-tools: netbsd-%-tools.tar.bz2 tar -jxf $< touch $@ # update timestamp to avoid rebuild -$(NETBSD_DIR)/.valid: pristine-netbsd-$(NETBSD_VER) +$(NETBSD_DIR)/.valid: ref-$(OS)-$(NETBSD_VER) $(RM) -rf $(NETBSD_DIR) cp -al $< $(NETBSD_DIR) # Apply arch-xen patches @@ -40,4 +42,4 @@ clean: $(MAKE) -C netbsd-$(FULLVERSION) clean delete: - rm -rf tmp-netbsd-$(NETBSD_VER) $(NETBSD_DIR) + rm -rf tmp-$(OS)-$(NETBSD_VER) $(NETBSD_DIR) diff --git a/docs/src/user.tex b/docs/src/user.tex index 0df10120bc..8ce88ae7fe 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -484,7 +484,7 @@ distribution. The entry should look something like the following: {\small \begin{verbatim} title Xen 2.0 / XenLinux 2.6.9 - kernel /boot/xen.gz dom0_mem=131072 + kernel /boot/xen.gz dom0_mem=128M module /boot/vmlinuz-2.6.9-xen0 root=/dev/sda4 ro console=tty0 \end{verbatim} } @@ -524,7 +524,7 @@ have problems. \subsection{Serial Console (optional)} -%% kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1 +%% kernel /boot/xen.gz dom0_mem=128M com1=115200,8n1 %% module /boot/vmlinuz-2.6.9-xen0 root=/dev/sda4 ro @@ -534,9 +534,9 @@ with: \begin{quote} {\small \begin{verbatim} - kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1 + kernel /boot/xen.gz dom0_mem=128M com1=115200,8n1 \end{verbatim}} -\end{quote} +\end{quote} This configures Xen to output on COM1 at 115,200 baud, 8 data bits, 1 stop bit and no parity. Modify these parameters for your set up. @@ -1680,12 +1680,6 @@ should be appended to Xen's command line, either manually or by editing \path{grub.conf}. \begin{description} -\item [ignorebiostables ] - Disable parsing of BIOS-supplied tables. This may help with some - chipsets that aren't fully supported by Xen. If you specify this - option then ACPI tables are also ignored, and SMP support is - disabled. - \item [noreboot ] Don't reboot the machine automatically on errors. This is useful to catch debug output if you aren't catching console messages @@ -1695,10 +1689,6 @@ editing \path{grub.conf}. Disable SMP support. This option is implied by `ignorebiostables'. -\item [noacpi ] - Disable ACPI tables, which confuse Xen on some chipsets. - This option is implied by `ignorebiostables'. - \item [watchdog ] Enable NMI watchdog which can report certain failures. @@ -1756,8 +1746,18 @@ editing \path{grub.conf}. `nmi=dom0': Inform DOM0 of the NMI. \\ `nmi=ignore': Ignore the NMI. +\item [mem=xxx ] + Set the physical RAM address limit. Any RAM appearing beyond this + physical address in the memory map will be ignored. This parameter + may be specified with a B, K, M or G suffix, representing bytes, + kilobytes, megabytes and gigabytes respectively. The + default unit, if no suffix is specified, is bytes. + \item [dom0\_mem=xxx ] - Set the amount of memory (in kB) to be allocated to domain0. + Set the amount of memory to be allocated to domain0. This parameter + may be specified with a B, K, M or G suffix, representing bytes, + kilobytes, megabytes and gigabytes respectively. The + default unit, if no suffix is specified, is kilobytes. \item [tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in pages @@ -1769,16 +1769,29 @@ editing \path{grub.conf}. Select the CPU scheduler Xen should use. The current possibilities are `bvt' (default), `atropos' and `rrobin'. For more information see Section~\ref{s:sched}. - -\item [physdev\_dom0\_hide=(xx:xx.x)(yy:yy.y)\ldots ] -Hide selected PCI devices from domain 0 (for instance, to stop it -taking ownership of them so that they can be driven by another -domain). Device IDs should be given in hex format. Bridge devices do -not need to be hidden --- they are hidden implicitly, since guest OSes -do not need to configure them. \end{description} +In addition, the following platform-specific options may be specified +on the Xen command line. Since domain 0 shares responsibility for +booting the platform, Xen will automatically propagate these options +to its command line. +These options are taken from Linux's command-line syntax with +unchanged semantics. + +\begin{description} +\item [acpi=off,force,strict,ht,noirq,\ldots ] + Modify how Xen (and domain 0) parses the BIOS ACPI tables. + +\item [acpi\_skip\_timer\_override ] + Instruct Xen (and domain 0) to ignore timer-interrupt override + instructions specified by the BIOS ACPI tables. + +\item [noapic ] + Instruct Xen (and domain 0) to ignore any IOAPICs that are present in + the system, and instead continue to use the legacy PIC. + +\end{description} \section{XenLinux Boot Options} diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c index 72b9206b75..c5f6c665fb 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c @@ -289,6 +289,10 @@ static void __init probe_roms(void) unsigned char *rom; int i; + /* Nothing to do if not running in dom0. */ + if (!(xen_start_info.flags & SIF_INITDOMAIN)) + return; + /* video rom */ upper = adapter_rom_resources[0].start; for (start = video_rom_resource.start; start < upper; start += 2048) { @@ -1213,8 +1217,9 @@ static void __init register_memory(void) else legacy_init_iomem_resources(&code_resource, &data_resource); - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_resource); + if (xen_start_info.flags & SIF_INITDOMAIN) + /* EFI systems may still have VGA */ + request_resource(&iomem_resource, &video_ram_resource); /* request I/O space for devices used on all i[345]86 PCs */ for (i = 0; i < STANDARD_IO_RESOURCES; i++) @@ -1571,6 +1576,14 @@ void __init setup_arch(char **cmdline_p) op.u.set_iopl.iopl = current->thread.io_pl = 1; HYPERVISOR_physdev_op(&op); +#ifdef CONFIG_ACPI_BOOT + if (!(xen_start_info.flags & SIF_INITDOMAIN)) { + printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); + acpi_disabled = 1; + acpi_ht = 0; + } +#endif + /* * Parse the ACPI tables for possible boot-time SMP configuration. */ diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c index 7c1ef78cd9..c1ca5c5c0e 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -54,7 +54,9 @@ #include #include -#include +#ifndef CONFIG_X86_IO_APIC +#define Dprintk(args...) +#endif #include #include @@ -1096,6 +1098,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) cpus_clear(cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]); +#ifdef CONFIG_X86_IO_APIC /* * If we couldn't find an SMP configuration at boot time, * get out of here now! @@ -1106,12 +1109,15 @@ static void __init smp_boot_cpus(unsigned int max_cpus) #if 0 phys_cpu_present_map = physid_mask_of_physid(0); #endif +#ifdef CONFIG_X86_LOCAL_APIC if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); +#endif map_cpu_to_logical_apicid(); return; } +#endif #if 0 /* diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c index 2554f999d7..b1acbcfc3a 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c @@ -486,12 +486,11 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) preq.nr_sects += seg[i].nsec; aop[i].u.map_grant_ref.host_virt_addr = MMAP_VADDR(pending_idx, i); - aop[i].u.map_grant_ref.dom = blkif->domid; aop[i].u.map_grant_ref.ref = blkif_gref_from_fas(fas); - aop[i].u.map_grant_ref.flags = ( GNTMAP_host_map | - ( ( operation == READ ) ? - 0 : GNTMAP_readonly ) ); + aop[i].u.map_grant_ref.flags = GNTMAP_host_map; + if ( operation == WRITE ) + aop[i].u.map_grant_ref.flags |= GNTMAP_readonly; } if ( unlikely(HYPERVISOR_grant_table_op( diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c index 311b8398ed..f15fcab014 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -824,7 +824,7 @@ static int blkif_queue_request(unsigned long id, buffer_ma >> PAGE_SHIFT, ( operation == BLKIF_OP_WRITE ? 1 : 0 ) ); - blk_shadow[id].frame[req->nr_segments] = + blk_shadow[req->id].frame[req->nr_segments] = buffer_ma >> PAGE_SHIFT; req->frame_and_sects[req->nr_segments] = diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h index 2bfd4df069..78886d339c 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h @@ -13,7 +13,12 @@ static char * __init machine_specific_memory_setup(void) who = "Xen"; - start_pfn = 0; + /* In dom0, we have to start the fake e820 map above the first + * 1MB, in other domains, it can start at 0. */ + if (xen_start_info.flags & SIF_INITDOMAIN) + start_pfn = 0x100; + else + start_pfn = 0; max_pfn = xen_start_info.nr_pages; e820.nr_map = 0; diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h index c2c211e5ea..28adeaf244 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h @@ -3,7 +3,9 @@ static inline void smpboot_clear_io_apic_irqs(void) { +#ifdef CONFIG_X86_IO_APIC io_apic_irqs = 0; +#endif } static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) @@ -39,12 +41,14 @@ static inline void smpboot_restore_warm_reset_vector(void) static inline void smpboot_setup_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); +#endif } diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h index c2c211e5ea..28adeaf244 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h @@ -3,7 +3,9 @@ static inline void smpboot_clear_io_apic_irqs(void) { +#ifdef CONFIG_X86_IO_APIC io_apic_irqs = 0; +#endif } static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) @@ -39,12 +41,14 @@ static inline void smpboot_restore_warm_reset_vector(void) static inline void smpboot_setup_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); +#endif } diff --git a/patches/linux-2.6.11/linux-2.6.11.8.patch b/patches/linux-2.6.11/linux-2.6.11.8.patch new file mode 100644 index 0000000000..781fe63284 --- /dev/null +++ b/patches/linux-2.6.11/linux-2.6.11.8.patch @@ -0,0 +1,1613 @@ +diff -Nru a/Makefile b/Makefile +--- a/Makefile 2005-04-29 18:34:28 -07:00 ++++ b/Makefile 2005-04-29 18:34:28 -07:00 +@@ -1,8 +1,8 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 11 +-EXTRAVERSION = +-NAME=Woozy Numbat ++EXTRAVERSION = .8 ++NAME=Woozy Beaver + + # *DOCUMENTATION* + # To see a list of typical targets execute "make help" +diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S +--- a/arch/ia64/kernel/fsys.S 2005-04-29 18:34:28 -07:00 ++++ b/arch/ia64/kernel/fsys.S 2005-04-29 18:34:28 -07:00 +@@ -611,8 +611,10 @@ + movl r2=ia64_ret_from_syscall + ;; + mov rp=r2 // set the real return addr +- tbit.z p8,p0=r3,TIF_SYSCALL_TRACE ++ and r3=_TIF_SYSCALL_TRACEAUDIT,r3 + ;; ++ cmp.eq p8,p0=r3,r0 ++ + (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 + (p8) br.call.sptk.many b6=b6 // ignore this return addr + br.cond.sptk ia64_trace_syscall +diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c +--- a/arch/ia64/kernel/signal.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/ia64/kernel/signal.c 2005-04-29 18:34:28 -07:00 +@@ -224,7 +224,8 @@ + * could be corrupted. + */ + retval = (long) &ia64_leave_kernel; +- if (test_thread_flag(TIF_SYSCALL_TRACE)) ++ if (test_thread_flag(TIF_SYSCALL_TRACE) ++ || test_thread_flag(TIF_SYSCALL_AUDIT)) + /* + * strace expects to be notified after sigreturn returns even though the + * context to which we return may not be in the middle of a syscall. +diff -Nru a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/ppc/oprofile/op_model_fsl_booke.c +--- a/arch/ppc/oprofile/op_model_fsl_booke.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/ppc/oprofile/op_model_fsl_booke.c 2005-04-29 18:34:28 -07:00 +@@ -150,7 +150,6 @@ + int is_kernel; + int val; + int i; +- unsigned int cpu = smp_processor_id(); + + /* set the PMM bit (see comment below) */ + mtmsr(mfmsr() | MSR_PMM); +@@ -162,7 +161,7 @@ + val = ctr_read(i); + if (val < 0) { + if (oprofile_running && ctr[i].enabled) { +- oprofile_add_sample(pc, is_kernel, i, cpu); ++ oprofile_add_pc(pc, is_kernel, i); + ctr_write(i, reset_value[i]); + } else { + ctr_write(i, 0); +diff -Nru a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h +--- a/arch/ppc/platforms/4xx/ebony.h 2005-04-29 18:34:28 -07:00 ++++ b/arch/ppc/platforms/4xx/ebony.h 2005-04-29 18:34:28 -07:00 +@@ -61,8 +61,8 @@ + */ + + /* OpenBIOS defined UART mappings, used before early_serial_setup */ +-#define UART0_IO_BASE (u8 *) 0xE0000200 +-#define UART1_IO_BASE (u8 *) 0xE0000300 ++#define UART0_IO_BASE 0xE0000200 ++#define UART1_IO_BASE 0xE0000300 + + /* external Epson SG-615P */ + #define BASE_BAUD 691200 +diff -Nru a/arch/ppc/platforms/4xx/luan.h b/arch/ppc/platforms/4xx/luan.h +--- a/arch/ppc/platforms/4xx/luan.h 2005-04-29 18:34:28 -07:00 ++++ b/arch/ppc/platforms/4xx/luan.h 2005-04-29 18:34:28 -07:00 +@@ -47,9 +47,9 @@ + #define RS_TABLE_SIZE 3 + + /* PIBS defined UART mappings, used before early_serial_setup */ +-#define UART0_IO_BASE (u8 *) 0xa0000200 +-#define UART1_IO_BASE (u8 *) 0xa0000300 +-#define UART2_IO_BASE (u8 *) 0xa0000600 ++#define UART0_IO_BASE 0xa0000200 ++#define UART1_IO_BASE 0xa0000300 ++#define UART2_IO_BASE 0xa0000600 + + #define BASE_BAUD 11059200 + #define STD_UART_OP(num) \ +diff -Nru a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h +--- a/arch/ppc/platforms/4xx/ocotea.h 2005-04-29 18:34:28 -07:00 ++++ b/arch/ppc/platforms/4xx/ocotea.h 2005-04-29 18:34:28 -07:00 +@@ -56,8 +56,8 @@ + #define RS_TABLE_SIZE 2 + + /* OpenBIOS defined UART mappings, used before early_serial_setup */ +-#define UART0_IO_BASE (u8 *) 0xE0000200 +-#define UART1_IO_BASE (u8 *) 0xE0000300 ++#define UART0_IO_BASE 0xE0000200 ++#define UART1_IO_BASE 0xE0000300 + + #define BASE_BAUD 11059200/16 + #define STD_UART_OP(num) \ +diff -Nru a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c +--- a/arch/sparc/kernel/ptrace.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/sparc/kernel/ptrace.c 2005-04-29 18:34:28 -07:00 +@@ -531,18 +531,6 @@ + pt_error_return(regs, EIO); + goto out_tsk; + } +- if (addr != 1) { +- if (addr & 3) { +- pt_error_return(regs, EINVAL); +- goto out_tsk; +- } +-#ifdef DEBUG_PTRACE +- printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc); +- printk ("Continuing with %08lx %08lx\n", addr, addr+4); +-#endif +- child->thread.kregs->pc = addr; +- child->thread.kregs->npc = addr + 4; +- } + + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); +diff -Nru a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c +--- a/arch/sparc64/kernel/ptrace.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/sparc64/kernel/ptrace.c 2005-04-29 18:34:28 -07:00 +@@ -514,25 +514,6 @@ + pt_error_return(regs, EIO); + goto out_tsk; + } +- if (addr != 1) { +- unsigned long pc_mask = ~0UL; +- +- if ((child->thread_info->flags & _TIF_32BIT) != 0) +- pc_mask = 0xffffffff; +- +- if (addr & 3) { +- pt_error_return(regs, EINVAL); +- goto out_tsk; +- } +-#ifdef DEBUG_PTRACE +- printk ("Original: %016lx %016lx\n", +- child->thread_info->kregs->tpc, +- child->thread_info->kregs->tnpc); +- printk ("Continuing with %016lx %016lx\n", addr, addr+4); +-#endif +- child->thread_info->kregs->tpc = (addr & pc_mask); +- child->thread_info->kregs->tnpc = ((addr + 4) & pc_mask); +- } + + if (request == PTRACE_SYSCALL) { + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); +diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c +--- a/arch/sparc64/kernel/signal32.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/sparc64/kernel/signal32.c 2005-04-29 18:34:28 -07:00 +@@ -192,9 +192,12 @@ + err |= __put_user(from->si_uid, &to->si_uid); + break; + case __SI_FAULT >> 16: +- case __SI_POLL >> 16: + err |= __put_user(from->si_trapno, &to->si_trapno); + err |= __put_user((unsigned long)from->si_addr, &to->si_addr); ++ break; ++ case __SI_POLL >> 16: ++ err |= __put_user(from->si_band, &to->si_band); ++ err |= __put_user(from->si_fd, &to->si_fd); + break; + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: +diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S +--- a/arch/sparc64/kernel/systbls.S 2005-04-29 18:34:27 -07:00 ++++ b/arch/sparc64/kernel/systbls.S 2005-04-29 18:34:27 -07:00 +@@ -75,7 +75,7 @@ + /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun + .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy + /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink +- .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid ++ .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid + /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl + + #endif /* CONFIG_COMPAT */ +diff -Nru a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h +--- a/arch/um/include/sysdep-i386/syscalls.h 2005-04-29 18:34:27 -07:00 ++++ b/arch/um/include/sysdep-i386/syscalls.h 2005-04-29 18:34:27 -07:00 +@@ -23,6 +23,9 @@ + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); + ++/* On i386 they choose a meaningless naming.*/ ++#define __NR_kexec_load __NR_sys_kexec_load ++ + #define ARCH_SYSCALLS \ + [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \ + [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \ +@@ -101,15 +104,12 @@ + [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \ + [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ + [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ +- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \ + [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \ +- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \ +- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \ +- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, +- ++ [ 285 ] = (syscall_handler_t *) sys_ni_syscall, ++ + /* 222 doesn't yet have a name in include/asm-i386/unistd.h */ + +-#define LAST_ARCH_SYSCALL __NR_vserver ++#define LAST_ARCH_SYSCALL 285 + + /* + * Overrides for Emacs so that we follow Linus's tabbing style. +diff -Nru a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h +--- a/arch/um/include/sysdep-x86_64/syscalls.h 2005-04-29 18:34:28 -07:00 ++++ b/arch/um/include/sysdep-x86_64/syscalls.h 2005-04-29 18:34:28 -07:00 +@@ -71,12 +71,7 @@ + [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \ + [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ + [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ +- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \ + [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \ +- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \ +- [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \ +- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \ +- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, \ + [ 251 ] = (syscall_handler_t *) sys_ni_syscall, + + #define LAST_ARCH_SYSCALL 251 +diff -Nru a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c +--- a/arch/um/kernel/skas/uaccess.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/um/kernel/skas/uaccess.c 2005-04-29 18:34:28 -07:00 +@@ -61,7 +61,8 @@ + void *arg; + int *res; + +- va_copy(args, *(va_list *)arg_ptr); ++ /* Some old gccs recognize __va_copy, but not va_copy */ ++ __va_copy(args, *(va_list *)arg_ptr); + addr = va_arg(args, unsigned long); + len = va_arg(args, int); + is_write = va_arg(args, int); +diff -Nru a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c +--- a/arch/um/kernel/sys_call_table.c 2005-04-29 18:34:28 -07:00 ++++ b/arch/um/kernel/sys_call_table.c 2005-04-29 18:34:28 -07:00 +@@ -48,7 +48,6 @@ + extern syscall_handler_t old_select; + extern syscall_handler_t sys_modify_ldt; + extern syscall_handler_t sys_rt_sigsuspend; +-extern syscall_handler_t sys_vserver; + extern syscall_handler_t sys_mbind; + extern syscall_handler_t sys_get_mempolicy; + extern syscall_handler_t sys_set_mempolicy; +@@ -242,6 +241,7 @@ + [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create, + [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl, + [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait, ++ [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, + [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address, + [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create, + [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime, +@@ -252,12 +252,10 @@ + [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime, + [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres, + [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep, +- [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, +- [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, + [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill, + [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, +- [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, +- [ __NR_vserver ] = (syscall_handler_t *) sys_vserver, ++ [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, ++ [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, + [ __NR_mbind ] = (syscall_handler_t *) sys_mbind, + [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy, + [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy, +@@ -267,9 +265,8 @@ + [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive, + [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify, + [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr, +- [ __NR_sys_kexec_load ] = (syscall_handler_t *) sys_ni_syscall, ++ [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall, + [ __NR_waitid ] = (syscall_handler_t *) sys_waitid, +- [ 285 ] = (syscall_handler_t *) sys_ni_syscall, + [ __NR_add_key ] = (syscall_handler_t *) sys_add_key, + [ __NR_request_key ] = (syscall_handler_t *) sys_request_key, + [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl, +diff -Nru a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c +--- a/drivers/char/drm/drm_ioctl.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/char/drm/drm_ioctl.c 2005-04-29 18:34:27 -07:00 +@@ -326,6 +326,8 @@ + + DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); + ++ memset(&version, 0, sizeof(version)); ++ + dev->driver->version(&version); + retv.drm_di_major = DRM_IF_MAJOR; + retv.drm_di_minor = DRM_IF_MINOR; +diff -Nru a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c +--- a/drivers/i2c/chips/eeprom.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/i2c/chips/eeprom.c 2005-04-29 18:34:27 -07:00 +@@ -130,7 +130,8 @@ + + /* Hide Vaio security settings to regular users (16 first bytes) */ + if (data->nature == VAIO && off < 16 && !capable(CAP_SYS_ADMIN)) { +- int in_row1 = 16 - off; ++ size_t in_row1 = 16 - off; ++ in_row1 = min(in_row1, count); + memset(buf, 0, in_row1); + if (count - in_row1 > 0) + memcpy(buf + in_row1, &data->data[16], count - in_row1); +diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c +--- a/drivers/i2c/chips/it87.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/i2c/chips/it87.c 2005-04-29 18:34:28 -07:00 +@@ -631,7 +631,7 @@ + struct it87_data *data = it87_update_device(dev); + return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms)); + } +-static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL); ++static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + + static ssize_t + show_vrm_reg(struct device *dev, char *buf) +diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c +--- a/drivers/i2c/chips/via686a.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/i2c/chips/via686a.c 2005-04-29 18:34:27 -07:00 +@@ -554,7 +554,7 @@ + struct via686a_data *data = via686a_update_device(dev); + return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms)); + } +-static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL); ++static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + + /* The driver. I choose to use type i2c_driver, as at is identical to both + smbus_driver and isa_driver, and clients could be of either kind */ +diff -Nru a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +--- a/drivers/input/serio/i8042-x86ia64io.h 2005-04-29 18:34:28 -07:00 ++++ b/drivers/input/serio/i8042-x86ia64io.h 2005-04-29 18:34:28 -07:00 +@@ -88,7 +88,7 @@ + }; + #endif + +-#ifdef CONFIG_ACPI ++#if defined(__ia64__) && defined(CONFIG_ACPI) + #include + #include + +@@ -281,7 +281,7 @@ + i8042_kbd_irq = I8042_MAP_IRQ(1); + i8042_aux_irq = I8042_MAP_IRQ(12); + +-#ifdef CONFIG_ACPI ++#if defined(__ia64__) && defined(CONFIG_ACPI) + if (i8042_acpi_init()) + return -1; + #endif +@@ -300,7 +300,7 @@ + + static inline void i8042_platform_exit(void) + { +-#ifdef CONFIG_ACPI ++#if defined(__ia64__) && defined(CONFIG_ACPI) + i8042_acpi_exit(); + #endif + } +diff -Nru a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc +--- a/drivers/md/raid6altivec.uc 2005-04-29 18:34:28 -07:00 ++++ b/drivers/md/raid6altivec.uc 2005-04-29 18:34:28 -07:00 +@@ -108,7 +108,11 @@ + int raid6_have_altivec(void) + { + /* This assumes either all CPUs have Altivec or none does */ ++#ifdef CONFIG_PPC64 + return cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC; ++#else ++ return cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC; ++#endif + } + #endif + +diff -Nru a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c +--- a/drivers/media/video/adv7170.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/media/video/adv7170.c 2005-04-29 18:34:28 -07:00 +@@ -130,7 +130,7 @@ + u8 block_data[32]; + + msg.addr = client->addr; +- msg.flags = client->flags; ++ msg.flags = 0; + while (len >= 2) { + msg.buf = (char *) block_data; + msg.len = 0; +diff -Nru a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c +--- a/drivers/media/video/adv7175.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/media/video/adv7175.c 2005-04-29 18:34:28 -07:00 +@@ -126,7 +126,7 @@ + u8 block_data[32]; + + msg.addr = client->addr; +- msg.flags = client->flags; ++ msg.flags = 0; + while (len >= 2) { + msg.buf = (char *) block_data; + msg.len = 0; +diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c +--- a/drivers/media/video/bt819.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/media/video/bt819.c 2005-04-29 18:34:27 -07:00 +@@ -146,7 +146,7 @@ + u8 block_data[32]; + + msg.addr = client->addr; +- msg.flags = client->flags; ++ msg.flags = 0; + while (len >= 2) { + msg.buf = (char *) block_data; + msg.len = 0; +diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c +--- a/drivers/media/video/bttv-cards.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/media/video/bttv-cards.c 2005-04-29 18:34:28 -07:00 +@@ -2718,8 +2718,6 @@ + } + btv->pll.pll_current = -1; + +- bttv_reset_audio(btv); +- + /* tuner configuration (from card list / autodetect / insmod option) */ + if (UNSET != bttv_tvcards[btv->c.type].tuner_type) + if(UNSET == btv->tuner_type) +diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c +--- a/drivers/media/video/saa7110.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/media/video/saa7110.c 2005-04-29 18:34:27 -07:00 +@@ -60,8 +60,10 @@ + + #define I2C_SAA7110 0x9C /* or 0x9E */ + ++#define SAA7110_NR_REG 0x35 ++ + struct saa7110 { +- unsigned char reg[54]; ++ u8 reg[SAA7110_NR_REG]; + + int norm; + int input; +@@ -95,31 +97,28 @@ + unsigned int len) + { + int ret = -1; +- u8 reg = *data++; ++ u8 reg = *data; /* first register to write to */ + +- len--; ++ /* Sanity check */ ++ if (reg + (len - 1) > SAA7110_NR_REG) ++ return ret; + + /* the saa7110 has an autoincrement function, use it if + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + struct saa7110 *decoder = i2c_get_clientdata(client); + struct i2c_msg msg; +- u8 block_data[54]; + +- msg.len = 0; +- msg.buf = (char *) block_data; ++ msg.len = len; ++ msg.buf = (char *) data; + msg.addr = client->addr; +- msg.flags = client->flags; +- while (len >= 1) { +- msg.len = 0; +- block_data[msg.len++] = reg; +- while (len-- >= 1 && msg.len < 54) +- block_data[msg.len++] = +- decoder->reg[reg++] = *data++; +- ret = i2c_transfer(client->adapter, &msg, 1); +- } ++ msg.flags = 0; ++ ret = i2c_transfer(client->adapter, &msg, 1); ++ ++ /* Cache the written data */ ++ memcpy(decoder->reg + reg, data + 1, len - 1); + } else { +- while (len-- >= 1) { ++ for (++data, --len; len; len--) { + if ((ret = saa7110_write(client, reg++, + *data++)) < 0) + break; +@@ -192,7 +191,7 @@ + return 0; + } + +-static const unsigned char initseq[] = { ++static const unsigned char initseq[1 + SAA7110_NR_REG] = { + 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00, + /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90, + /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA, +diff -Nru a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c +--- a/drivers/media/video/saa7114.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/media/video/saa7114.c 2005-04-29 18:34:28 -07:00 +@@ -163,7 +163,7 @@ + u8 block_data[32]; + + msg.addr = client->addr; +- msg.flags = client->flags; ++ msg.flags = 0; + while (len >= 2) { + msg.buf = (char *) block_data; + msg.len = 0; +diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c +--- a/drivers/media/video/saa7185.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/media/video/saa7185.c 2005-04-29 18:34:28 -07:00 +@@ -118,7 +118,7 @@ + u8 block_data[32]; + + msg.addr = client->addr; +- msg.flags = client->flags; ++ msg.flags = 0; + while (len >= 2) { + msg.buf = (char *) block_data; + msg.len = 0; +diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c +--- a/drivers/net/amd8111e.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/net/amd8111e.c 2005-04-29 18:34:28 -07:00 +@@ -1381,6 +1381,8 @@ + + if(amd8111e_restart(dev)){ + spin_unlock_irq(&lp->lock); ++ if (dev->irq) ++ free_irq(dev->irq, dev); + return -ENOMEM; + } + /* Start ipg timer */ +diff -Nru a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c +--- a/drivers/net/ppp_async.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/net/ppp_async.c 2005-04-29 18:34:28 -07:00 +@@ -1000,7 +1000,7 @@ + data += 4; + dlen -= 4; + /* data[0] is code, data[1] is length */ +- while (dlen >= 2 && dlen >= data[1]) { ++ while (dlen >= 2 && dlen >= data[1] && data[1] >= 2) { + switch (data[0]) { + case LCP_MRU: + val = (data[2] << 8) + data[3]; +diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c +--- a/drivers/net/r8169.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/net/r8169.c 2005-04-29 18:34:28 -07:00 +@@ -1683,16 +1683,19 @@ + rtl8169_make_unusable_by_asic(desc); + } + +-static inline void rtl8169_return_to_asic(struct RxDesc *desc, int rx_buf_sz) ++static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz) + { +- desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz); ++ u32 eor = le32_to_cpu(desc->opts1) & RingEnd; ++ ++ desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz); + } + +-static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping, +- int rx_buf_sz) ++static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, ++ u32 rx_buf_sz) + { + desc->addr = cpu_to_le64(mapping); +- desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz); ++ wmb(); ++ rtl8169_mark_to_asic(desc, rx_buf_sz); + } + + static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, +@@ -1712,7 +1715,7 @@ + mapping = pci_map_single(pdev, skb->tail, rx_buf_sz, + PCI_DMA_FROMDEVICE); + +- rtl8169_give_to_asic(desc, mapping, rx_buf_sz); ++ rtl8169_map_to_asic(desc, mapping, rx_buf_sz); + + out: + return ret; +@@ -2150,7 +2153,7 @@ + skb_reserve(skb, NET_IP_ALIGN); + eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0); + *sk_buff = skb; +- rtl8169_return_to_asic(desc, rx_buf_sz); ++ rtl8169_mark_to_asic(desc, rx_buf_sz); + ret = 0; + } + } +diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c +--- a/drivers/net/sis900.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/net/sis900.c 2005-04-29 18:34:27 -07:00 +@@ -236,7 +236,7 @@ + signature = (u16) read_eeprom(ioaddr, EEPROMSignature); + if (signature == 0xffff || signature == 0x0000) { + printk (KERN_INFO "%s: Error EERPOM read %x\n", +- net_dev->name, signature); ++ pci_name(pci_dev), signature); + return 0; + } + +@@ -268,7 +268,7 @@ + if (!isa_bridge) + isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0018, isa_bridge); + if (!isa_bridge) { +- printk("%s: Can not find ISA bridge\n", net_dev->name); ++ printk("%s: Can not find ISA bridge\n", pci_name(pci_dev)); + return 0; + } + pci_read_config_byte(isa_bridge, 0x48, ®); +@@ -456,10 +456,6 @@ + net_dev->tx_timeout = sis900_tx_timeout; + net_dev->watchdog_timeo = TX_TIMEOUT; + net_dev->ethtool_ops = &sis900_ethtool_ops; +- +- ret = register_netdev(net_dev); +- if (ret) +- goto err_unmap_rx; + + /* Get Mac address according to the chip revision */ + pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision); +@@ -476,7 +472,7 @@ + + if (ret == 0) { + ret = -ENODEV; +- goto err_out_unregister; ++ goto err_unmap_rx; + } + + /* 630ET : set the mii access mode as software-mode */ +@@ -486,7 +482,7 @@ + /* probe for mii transceiver */ + if (sis900_mii_probe(net_dev) == 0) { + ret = -ENODEV; +- goto err_out_unregister; ++ goto err_unmap_rx; + } + + /* save our host bridge revision */ +@@ -496,6 +492,10 @@ + pci_dev_put(dev); + } + ++ ret = register_netdev(net_dev); ++ if (ret) ++ goto err_unmap_rx; ++ + /* print some information about our NIC */ + printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, + card_name, ioaddr, net_dev->irq); +@@ -505,8 +505,6 @@ + + return 0; + +- err_out_unregister: +- unregister_netdev(net_dev); + err_unmap_rx: + pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring, + sis_priv->rx_ring_dma); +@@ -533,6 +531,7 @@ + static int __init sis900_mii_probe(struct net_device * net_dev) + { + struct sis900_private * sis_priv = net_dev->priv; ++ const char *dev_name = pci_name(sis_priv->pci_dev); + u16 poll_bit = MII_STAT_LINK, status = 0; + unsigned long timeout = jiffies + 5 * HZ; + int phy_addr; +@@ -582,21 +581,20 @@ + mii_phy->phy_types = + (mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX)) ? LAN : HOME; + printk(KERN_INFO "%s: %s transceiver found at address %d.\n", +- net_dev->name, mii_chip_table[i].name, ++ dev_name, mii_chip_table[i].name, + phy_addr); + break; + } + + if( !mii_chip_table[i].phy_id1 ) { + printk(KERN_INFO "%s: Unknown PHY transceiver found at address %d.\n", +- net_dev->name, phy_addr); ++ dev_name, phy_addr); + mii_phy->phy_types = UNKNOWN; + } + } + + if (sis_priv->mii == NULL) { +- printk(KERN_INFO "%s: No MII transceivers found!\n", +- net_dev->name); ++ printk(KERN_INFO "%s: No MII transceivers found!\n", dev_name); + return 0; + } + +@@ -621,7 +619,7 @@ + poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit); + if (time_after_eq(jiffies, timeout)) { + printk(KERN_WARNING "%s: reset phy and link down now\n", +- net_dev->name); ++ dev_name); + return -ETIME; + } + } +@@ -691,7 +689,7 @@ + sis_priv->mii = default_phy; + sis_priv->cur_phy = default_phy->phy_addr; + printk(KERN_INFO "%s: Using transceiver found at address %d as default\n", +- net_dev->name,sis_priv->cur_phy); ++ pci_name(sis_priv->pci_dev), sis_priv->cur_phy); + } + + status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL); +diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c +--- a/drivers/net/tun.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/net/tun.c 2005-04-29 18:34:27 -07:00 +@@ -229,7 +229,7 @@ + size_t len = count; + + if (!(tun->flags & TUN_NO_PI)) { +- if ((len -= sizeof(pi)) > len) ++ if ((len -= sizeof(pi)) > count) + return -EINVAL; + + if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) +diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c +--- a/drivers/net/via-rhine.c 2005-04-29 18:34:28 -07:00 ++++ b/drivers/net/via-rhine.c 2005-04-29 18:34:28 -07:00 +@@ -1197,8 +1197,10 @@ + dev->name, rp->pdev->irq); + + rc = alloc_ring(dev); +- if (rc) ++ if (rc) { ++ free_irq(rp->pdev->irq, dev); + return rc; ++ } + alloc_rbufs(dev); + alloc_tbufs(dev); + rhine_chip_reset(dev); +@@ -1898,6 +1900,9 @@ + struct net_device *dev = pci_get_drvdata(pdev); + struct rhine_private *rp = netdev_priv(dev); + void __iomem *ioaddr = rp->base; ++ ++ if (!(rp->quirks & rqWOL)) ++ return; /* Nothing to do for non-WOL adapters */ + + rhine_power_init(dev); + +diff -Nru a/drivers/net/wan/hd6457x.c b/drivers/net/wan/hd6457x.c +--- a/drivers/net/wan/hd6457x.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/net/wan/hd6457x.c 2005-04-29 18:34:27 -07:00 +@@ -315,7 +315,7 @@ + #endif + stats->rx_packets++; + stats->rx_bytes += skb->len; +- skb->dev->last_rx = jiffies; ++ dev->last_rx = jiffies; + skb->protocol = hdlc_type_trans(skb, dev); + netif_rx(skb); + } +diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c +--- a/drivers/pci/hotplug/pciehp_ctrl.c 2005-04-29 18:34:27 -07:00 ++++ b/drivers/pci/hotplug/pciehp_ctrl.c 2005-04-29 18:34:27 -07:00 +@@ -1354,10 +1354,11 @@ + dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", + ctrl->seg, func->bus, func->device, func->function); + bridge_slot_remove(func); +- } else ++ } else { + dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", + ctrl->seg, func->bus, func->device, func->function); + slot_remove(func); ++ } + + func = pciehp_slot_find(ctrl->slot_bus, device, 0); + } +diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c +--- a/fs/binfmt_elf.c 2005-04-29 18:34:28 -07:00 ++++ b/fs/binfmt_elf.c 2005-04-29 18:34:28 -07:00 +@@ -1008,6 +1008,7 @@ + static int load_elf_library(struct file *file) + { + struct elf_phdr *elf_phdata; ++ struct elf_phdr *eppnt; + unsigned long elf_bss, bss, len; + int retval, error, i, j; + struct elfhdr elf_ex; +@@ -1031,44 +1032,47 @@ + /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */ + + error = -ENOMEM; +- elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL); ++ elf_phdata = kmalloc(j, GFP_KERNEL); + if (!elf_phdata) + goto out; + ++ eppnt = elf_phdata; + error = -ENOEXEC; +- retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, j); ++ retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j); + if (retval != j) + goto out_free_ph; + + for (j = 0, i = 0; ip_type == PT_LOAD) j++; ++ if ((eppnt + i)->p_type == PT_LOAD) ++ j++; + if (j != 1) + goto out_free_ph; + +- while (elf_phdata->p_type != PT_LOAD) elf_phdata++; ++ while (eppnt->p_type != PT_LOAD) ++ eppnt++; + + /* Now use mmap to map the library into memory. */ + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, +- ELF_PAGESTART(elf_phdata->p_vaddr), +- (elf_phdata->p_filesz + +- ELF_PAGEOFFSET(elf_phdata->p_vaddr)), ++ ELF_PAGESTART(eppnt->p_vaddr), ++ (eppnt->p_filesz + ++ ELF_PAGEOFFSET(eppnt->p_vaddr)), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, +- (elf_phdata->p_offset - +- ELF_PAGEOFFSET(elf_phdata->p_vaddr))); ++ (eppnt->p_offset - ++ ELF_PAGEOFFSET(eppnt->p_vaddr))); + up_write(¤t->mm->mmap_sem); +- if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) ++ if (error != ELF_PAGESTART(eppnt->p_vaddr)) + goto out_free_ph; + +- elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz; ++ elf_bss = eppnt->p_vaddr + eppnt->p_filesz; + if (padzero(elf_bss)) { + error = -EFAULT; + goto out_free_ph; + } + +- len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1); +- bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; ++ len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); ++ bss = eppnt->p_memsz + eppnt->p_vaddr; + if (bss > len) { + down_write(¤t->mm->mmap_sem); + do_brk(len, bss - len); +diff -Nru a/fs/cramfs/inode.c b/fs/cramfs/inode.c +--- a/fs/cramfs/inode.c 2005-04-29 18:34:27 -07:00 ++++ b/fs/cramfs/inode.c 2005-04-29 18:34:27 -07:00 +@@ -70,6 +70,7 @@ + inode->i_data.a_ops = &cramfs_aops; + } else { + inode->i_size = 0; ++ inode->i_blocks = 0; + init_special_inode(inode, inode->i_mode, + old_decode_dev(cramfs_inode->size)); + } +diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c +--- a/fs/eventpoll.c 2005-04-29 18:34:27 -07:00 ++++ b/fs/eventpoll.c 2005-04-29 18:34:27 -07:00 +@@ -619,6 +619,7 @@ + return error; + } + ++#define MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) + + /* + * Implement the event wait interface for the eventpoll file. It is the kernel +@@ -635,7 +636,7 @@ + current, epfd, events, maxevents, timeout)); + + /* The maximum number of event must be greater than zero */ +- if (maxevents <= 0) ++ if (maxevents <= 0 || maxevents > MAX_EVENTS) + return -EINVAL; + + /* Verify that the area passed by the user is writeable */ +diff -Nru a/fs/exec.c b/fs/exec.c +--- a/fs/exec.c 2005-04-29 18:34:27 -07:00 ++++ b/fs/exec.c 2005-04-29 18:34:27 -07:00 +@@ -814,7 +814,7 @@ + { + /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); +- memcpy(buf, tsk->comm, sizeof(tsk->comm)); ++ strncpy(buf, tsk->comm, sizeof(tsk->comm)); + task_unlock(tsk); + } + +diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c +--- a/fs/ext2/dir.c 2005-04-29 18:34:28 -07:00 ++++ b/fs/ext2/dir.c 2005-04-29 18:34:28 -07:00 +@@ -592,6 +592,7 @@ + goto fail; + } + kaddr = kmap_atomic(page, KM_USER0); ++ memset(kaddr, 0, chunk_size); + de = (struct ext2_dir_entry_2 *)kaddr; + de->name_len = 1; + de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); +diff -Nru a/fs/isofs/inode.c b/fs/isofs/inode.c +--- a/fs/isofs/inode.c 2005-04-29 18:34:28 -07:00 ++++ b/fs/isofs/inode.c 2005-04-29 18:34:28 -07:00 +@@ -685,6 +685,8 @@ + sbi->s_log_zone_size = isonum_723 (h_pri->logical_block_size); + sbi->s_max_size = isonum_733(h_pri->volume_space_size); + } else { ++ if (!pri) ++ goto out_freebh; + rootp = (struct iso_directory_record *) pri->root_directory_record; + sbi->s_nzones = isonum_733 (pri->volume_space_size); + sbi->s_log_zone_size = isonum_723 (pri->logical_block_size); +@@ -1394,6 +1396,9 @@ + unsigned long hashval; + struct inode *inode; + struct isofs_iget5_callback_data data; ++ ++ if (offset >= 1ul << sb->s_blocksize_bits) ++ return NULL; + + data.block = block; + data.offset = offset; +diff -Nru a/fs/isofs/rock.c b/fs/isofs/rock.c +--- a/fs/isofs/rock.c 2005-04-29 18:34:28 -07:00 ++++ b/fs/isofs/rock.c 2005-04-29 18:34:28 -07:00 +@@ -53,6 +53,7 @@ + if(LEN & 1) LEN++; \ + CHR = ((unsigned char *) DE) + LEN; \ + LEN = *((unsigned char *) DE) - LEN; \ ++ if (LEN<0) LEN=0; \ + if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \ + { \ + LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \ +@@ -73,6 +74,10 @@ + offset1 = 0; \ + pbh = sb_bread(DEV->i_sb, block); \ + if(pbh){ \ ++ if (offset > pbh->b_size || offset + cont_size > pbh->b_size){ \ ++ brelse(pbh); \ ++ goto out; \ ++ } \ + memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \ + brelse(pbh); \ + chr = (unsigned char *) buffer; \ +@@ -103,12 +108,13 @@ + struct rock_ridge * rr; + int sig; + +- while (len > 1){ /* There may be one byte for padding somewhere */ ++ while (len > 2){ /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *) chr; +- if (rr->len == 0) goto out; /* Something got screwed up here */ ++ if (rr->len < 3) goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; ++ if (len < 0) goto out; /* corrupted isofs */ + + switch(sig){ + case SIG('R','R'): +@@ -122,6 +128,7 @@ + break; + case SIG('N','M'): + if (truncate) break; ++ if (rr->len < 5) break; + /* + * If the flags are 2 or 4, this indicates '.' or '..'. + * We don't want to do anything with this, because it +@@ -186,12 +193,13 @@ + struct rock_ridge * rr; + int rootflag; + +- while (len > 1){ /* There may be one byte for padding somewhere */ ++ while (len > 2){ /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *) chr; +- if (rr->len == 0) goto out; /* Something got screwed up here */ ++ if (rr->len < 3) goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; ++ if (len < 0) goto out; /* corrupted isofs */ + + switch(sig){ + #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ +@@ -462,7 +470,7 @@ + struct rock_ridge *rr; + + if (!ISOFS_SB(inode->i_sb)->s_rock) +- panic ("Cannot have symlink with high sierra variant of iso filesystem\n"); ++ goto error; + + block = ei->i_iget5_block; + lock_kernel(); +@@ -487,13 +495,15 @@ + SETUP_ROCK_RIDGE(raw_inode, chr, len); + + repeat: +- while (len > 1) { /* There may be one byte for padding somewhere */ ++ while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *) chr; +- if (rr->len == 0) ++ if (rr->len < 3) + goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; ++ if (len < 0) ++ goto out; /* corrupted isofs */ + + switch (sig) { + case SIG('R', 'R'): +@@ -543,6 +553,7 @@ + fail: + brelse(bh); + unlock_kernel(); ++ error: + SetPageError(page); + kunmap(page); + unlock_page(page); +diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c +--- a/fs/jbd/transaction.c 2005-04-29 18:34:27 -07:00 ++++ b/fs/jbd/transaction.c 2005-04-29 18:34:27 -07:00 +@@ -1775,10 +1775,10 @@ + JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget"); + ret = __dispose_buffer(jh, + journal->j_running_transaction); ++ journal_put_journal_head(jh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + spin_unlock(&journal->j_state_lock); +- journal_put_journal_head(jh); + return ret; + } else { + /* There is no currently-running transaction. So the +@@ -1789,10 +1789,10 @@ + JBUFFER_TRACE(jh, "give to committing trans"); + ret = __dispose_buffer(jh, + journal->j_committing_transaction); ++ journal_put_journal_head(jh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + spin_unlock(&journal->j_state_lock); +- journal_put_journal_head(jh); + return ret; + } else { + /* The orphan record's transaction has +@@ -1813,10 +1813,10 @@ + journal->j_running_transaction); + jh->b_next_transaction = NULL; + } ++ journal_put_journal_head(jh); + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + spin_unlock(&journal->j_state_lock); +- journal_put_journal_head(jh); + return 0; + } else { + /* Good, the buffer belongs to the running transaction. +diff -Nru a/fs/partitions/msdos.c b/fs/partitions/msdos.c +--- a/fs/partitions/msdos.c 2005-04-29 18:34:28 -07:00 ++++ b/fs/partitions/msdos.c 2005-04-29 18:34:28 -07:00 +@@ -114,6 +114,9 @@ + */ + for (i=0; i<4; i++, p++) { + u32 offs, size, next; ++ ++ if (SYS_IND(p) == 0) ++ continue; + if (!NR_SECTS(p) || is_extended_partition(p)) + continue; + +@@ -430,6 +433,8 @@ + for (slot = 1 ; slot <= 4 ; slot++, p++) { + u32 start = START_SECT(p)*sector_size; + u32 size = NR_SECTS(p)*sector_size; ++ if (SYS_IND(p) == 0) ++ continue; + if (!size) + continue; + if (is_extended_partition(p)) { +diff -Nru a/kernel/signal.c b/kernel/signal.c +--- a/kernel/signal.c 2005-04-29 18:34:27 -07:00 ++++ b/kernel/signal.c 2005-04-29 18:34:27 -07:00 +@@ -1728,6 +1728,7 @@ + * with another processor delivering a stop signal, + * then the SIGCONT that wakes us up should clear it. + */ ++ read_unlock(&tasklist_lock); + return 0; + } + +diff -Nru a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c +--- a/lib/rwsem-spinlock.c 2005-04-29 18:34:28 -07:00 ++++ b/lib/rwsem-spinlock.c 2005-04-29 18:34:28 -07:00 +@@ -140,12 +140,12 @@ + + rwsemtrace(sem, "Entering __down_read"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irq(&sem->wait_lock); + + if (sem->activity >= 0 && list_empty(&sem->wait_list)) { + /* granted */ + sem->activity++; +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irq(&sem->wait_lock); + goto out; + } + +@@ -160,7 +160,7 @@ + list_add_tail(&waiter.list, &sem->wait_list); + + /* we don't need to touch the semaphore struct anymore */ +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irq(&sem->wait_lock); + + /* wait to be given the lock */ + for (;;) { +@@ -181,10 +181,12 @@ + */ + int fastcall __down_read_trylock(struct rw_semaphore *sem) + { ++ unsigned long flags; + int ret = 0; ++ + rwsemtrace(sem, "Entering __down_read_trylock"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + if (sem->activity >= 0 && list_empty(&sem->wait_list)) { + /* granted */ +@@ -192,7 +194,7 @@ + ret = 1; + } + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving __down_read_trylock"); + return ret; +@@ -209,12 +211,12 @@ + + rwsemtrace(sem, "Entering __down_write"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irq(&sem->wait_lock); + + if (sem->activity == 0 && list_empty(&sem->wait_list)) { + /* granted */ + sem->activity = -1; +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irq(&sem->wait_lock); + goto out; + } + +@@ -229,7 +231,7 @@ + list_add_tail(&waiter.list, &sem->wait_list); + + /* we don't need to touch the semaphore struct anymore */ +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irq(&sem->wait_lock); + + /* wait to be given the lock */ + for (;;) { +@@ -250,10 +252,12 @@ + */ + int fastcall __down_write_trylock(struct rw_semaphore *sem) + { ++ unsigned long flags; + int ret = 0; ++ + rwsemtrace(sem, "Entering __down_write_trylock"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + if (sem->activity == 0 && list_empty(&sem->wait_list)) { + /* granted */ +@@ -261,7 +265,7 @@ + ret = 1; + } + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving __down_write_trylock"); + return ret; +@@ -272,14 +276,16 @@ + */ + void fastcall __up_read(struct rw_semaphore *sem) + { ++ unsigned long flags; ++ + rwsemtrace(sem, "Entering __up_read"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + if (--sem->activity == 0 && !list_empty(&sem->wait_list)) + sem = __rwsem_wake_one_writer(sem); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving __up_read"); + } +@@ -289,15 +295,17 @@ + */ + void fastcall __up_write(struct rw_semaphore *sem) + { ++ unsigned long flags; ++ + rwsemtrace(sem, "Entering __up_write"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + sem->activity = 0; + if (!list_empty(&sem->wait_list)) + sem = __rwsem_do_wake(sem, 1); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving __up_write"); + } +@@ -308,15 +316,17 @@ + */ + void fastcall __downgrade_write(struct rw_semaphore *sem) + { ++ unsigned long flags; ++ + rwsemtrace(sem, "Entering __downgrade_write"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + sem->activity = 1; + if (!list_empty(&sem->wait_list)) + sem = __rwsem_do_wake(sem, 0); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving __downgrade_write"); + } +diff -Nru a/lib/rwsem.c b/lib/rwsem.c +--- a/lib/rwsem.c 2005-04-29 18:34:28 -07:00 ++++ b/lib/rwsem.c 2005-04-29 18:34:28 -07:00 +@@ -150,7 +150,7 @@ + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + + /* set up my own style of waitqueue */ +- spin_lock(&sem->wait_lock); ++ spin_lock_irq(&sem->wait_lock); + waiter->task = tsk; + get_task_struct(tsk); + +@@ -163,7 +163,7 @@ + if (!(count & RWSEM_ACTIVE_MASK)) + sem = __rwsem_do_wake(sem, 0); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irq(&sem->wait_lock); + + /* wait to be given the lock */ + for (;;) { +@@ -219,15 +219,17 @@ + */ + struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) + { ++ unsigned long flags; ++ + rwsemtrace(sem, "Entering rwsem_wake"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + /* do nothing if list empty */ + if (!list_empty(&sem->wait_list)) + sem = __rwsem_do_wake(sem, 0); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving rwsem_wake"); + +@@ -241,15 +243,17 @@ + */ + struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem) + { ++ unsigned long flags; ++ + rwsemtrace(sem, "Entering rwsem_downgrade_wake"); + +- spin_lock(&sem->wait_lock); ++ spin_lock_irqsave(&sem->wait_lock, flags); + + /* do nothing if list empty */ + if (!list_empty(&sem->wait_list)) + sem = __rwsem_do_wake(sem, 1); + +- spin_unlock(&sem->wait_lock); ++ spin_unlock_irqrestore(&sem->wait_lock, flags); + + rwsemtrace(sem, "Leaving rwsem_downgrade_wake"); + return sem; +diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c +--- a/net/bluetooth/af_bluetooth.c 2005-04-29 18:34:27 -07:00 ++++ b/net/bluetooth/af_bluetooth.c 2005-04-29 18:34:27 -07:00 +@@ -64,7 +64,7 @@ + + int bt_sock_register(int proto, struct net_proto_family *ops) + { +- if (proto >= BT_MAX_PROTO) ++ if (proto < 0 || proto >= BT_MAX_PROTO) + return -EINVAL; + + if (bt_proto[proto]) +@@ -77,7 +77,7 @@ + + int bt_sock_unregister(int proto) + { +- if (proto >= BT_MAX_PROTO) ++ if (proto < 0 || proto >= BT_MAX_PROTO) + return -EINVAL; + + if (!bt_proto[proto]) +@@ -92,7 +92,7 @@ + { + int err = 0; + +- if (proto >= BT_MAX_PROTO) ++ if (proto < 0 || proto >= BT_MAX_PROTO) + return -EINVAL; + + #if defined(CONFIG_KMOD) +diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c +--- a/net/ipv4/fib_hash.c 2005-04-29 18:34:28 -07:00 ++++ b/net/ipv4/fib_hash.c 2005-04-29 18:34:28 -07:00 +@@ -919,13 +919,23 @@ + return fa; + } + ++static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos) ++{ ++ struct fib_alias *fa = fib_get_first(seq); ++ ++ if (fa) ++ while (pos && (fa = fib_get_next(seq))) ++ --pos; ++ return pos ? NULL : fa; ++} ++ + static void *fib_seq_start(struct seq_file *seq, loff_t *pos) + { + void *v = NULL; + + read_lock(&fib_hash_lock); + if (ip_fib_main_table) +- v = *pos ? fib_get_next(seq) : SEQ_START_TOKEN; ++ v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; + return v; + } + +diff -Nru a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +--- a/net/ipv4/tcp_input.c 2005-04-29 18:34:28 -07:00 ++++ b/net/ipv4/tcp_input.c 2005-04-29 18:34:28 -07:00 +@@ -1653,7 +1653,10 @@ + static void tcp_undo_cwr(struct tcp_sock *tp, int undo) + { + if (tp->prior_ssthresh) { +- tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); ++ if (tcp_is_bic(tp)) ++ tp->snd_cwnd = max(tp->snd_cwnd, tp->bictcp.last_max_cwnd); ++ else ++ tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); + + if (undo && tp->prior_ssthresh > tp->snd_ssthresh) { + tp->snd_ssthresh = tp->prior_ssthresh; +diff -Nru a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c +--- a/net/ipv4/tcp_timer.c 2005-04-29 18:34:28 -07:00 ++++ b/net/ipv4/tcp_timer.c 2005-04-29 18:34:28 -07:00 +@@ -38,6 +38,7 @@ + + #ifdef TCP_DEBUG + const char tcp_timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n"; ++EXPORT_SYMBOL(tcp_timer_bug_msg); + #endif + + /* +diff -Nru a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c +--- a/net/ipv4/xfrm4_output.c 2005-04-29 18:34:27 -07:00 ++++ b/net/ipv4/xfrm4_output.c 2005-04-29 18:34:27 -07:00 +@@ -103,16 +103,16 @@ + goto error_nolock; + } + +- spin_lock_bh(&x->lock); +- err = xfrm_state_check(x, skb); +- if (err) +- goto error; +- + if (x->props.mode) { + err = xfrm4_tunnel_check_size(skb); + if (err) +- goto error; ++ goto error_nolock; + } ++ ++ spin_lock_bh(&x->lock); ++ err = xfrm_state_check(x, skb); ++ if (err) ++ goto error; + + xfrm4_encap(skb); + +diff -Nru a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c +--- a/net/ipv6/xfrm6_output.c 2005-04-29 18:34:28 -07:00 ++++ b/net/ipv6/xfrm6_output.c 2005-04-29 18:34:28 -07:00 +@@ -103,16 +103,16 @@ + goto error_nolock; + } + +- spin_lock_bh(&x->lock); +- err = xfrm_state_check(x, skb); +- if (err) +- goto error; +- + if (x->props.mode) { + err = xfrm6_tunnel_check_size(skb); + if (err) +- goto error; ++ goto error_nolock; + } ++ ++ spin_lock_bh(&x->lock); ++ err = xfrm_state_check(x, skb); ++ if (err) ++ goto error; + + xfrm6_encap(skb); + +diff -Nru a/net/netrom/nr_in.c b/net/netrom/nr_in.c +--- a/net/netrom/nr_in.c 2005-04-29 18:34:27 -07:00 ++++ b/net/netrom/nr_in.c 2005-04-29 18:34:27 -07:00 +@@ -74,7 +74,6 @@ + static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, + int frametype) + { +- bh_lock_sock(sk); + switch (frametype) { + case NR_CONNACK: { + nr_cb *nr = nr_sk(sk); +@@ -103,8 +102,6 @@ + default: + break; + } +- bh_unlock_sock(sk); +- + return 0; + } + +@@ -116,7 +113,6 @@ + static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, + int frametype) + { +- bh_lock_sock(sk); + switch (frametype) { + case NR_CONNACK | NR_CHOKE_FLAG: + nr_disconnect(sk, ECONNRESET); +@@ -132,8 +128,6 @@ + default: + break; + } +- bh_unlock_sock(sk); +- + return 0; + } + +@@ -154,7 +148,6 @@ + nr = skb->data[18]; + ns = skb->data[17]; + +- bh_lock_sock(sk); + switch (frametype) { + case NR_CONNREQ: + nr_write_internal(sk, NR_CONNACK); +@@ -265,8 +258,6 @@ + default: + break; + } +- bh_unlock_sock(sk); +- + return queued; + } + +diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +--- a/net/xfrm/xfrm_state.c 2005-04-29 18:34:28 -07:00 ++++ b/net/xfrm/xfrm_state.c 2005-04-29 18:34:28 -07:00 +@@ -609,7 +609,7 @@ + + for (i = 0; i < XFRM_DST_HSIZE; i++) { + list_for_each_entry(x, xfrm_state_bydst+i, bydst) { +- if (x->km.seq == seq) { ++ if (x->km.seq == seq && x->km.state == XFRM_STATE_ACQ) { + xfrm_state_hold(x); + return x; + } +diff -Nru a/security/keys/key.c b/security/keys/key.c +--- a/security/keys/key.c 2005-04-29 18:34:28 -07:00 ++++ b/security/keys/key.c 2005-04-29 18:34:28 -07:00 +@@ -57,9 +57,10 @@ + { + struct key_user *candidate = NULL, *user; + struct rb_node *parent = NULL; +- struct rb_node **p = &key_user_tree.rb_node; ++ struct rb_node **p; + + try_again: ++ p = &key_user_tree.rb_node; + spin_lock(&key_user_lock); + + /* search the tree for a user record with a matching UID */ +diff -Nru a/sound/core/timer.c b/sound/core/timer.c +--- a/sound/core/timer.c 2005-04-29 18:34:28 -07:00 ++++ b/sound/core/timer.c 2005-04-29 18:34:28 -07:00 +@@ -1117,7 +1117,8 @@ + if (tu->qused >= tu->queue_size) { + tu->overrun++; + } else { +- memcpy(&tu->queue[tu->qtail++], tread, sizeof(*tread)); ++ memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread)); ++ tu->qtail %= tu->queue_size; + tu->qused++; + } + } +@@ -1140,6 +1141,8 @@ + spin_lock(&tu->qlock); + snd_timer_user_append_to_tqueue(tu, &r1); + spin_unlock(&tu->qlock); ++ kill_fasync(&tu->fasync, SIGIO, POLL_IN); ++ wake_up(&tu->qchange_sleep); + } + + static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, +diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c +--- a/sound/pci/ac97/ac97_codec.c 2005-04-29 18:34:28 -07:00 ++++ b/sound/pci/ac97/ac97_codec.c 2005-04-29 18:34:28 -07:00 +@@ -1185,7 +1185,7 @@ + /* + * create mute switch(es) for normal stereo controls + */ +-static int snd_ac97_cmute_new(snd_card_t *card, char *name, int reg, ac97_t *ac97) ++static int snd_ac97_cmute_new_stereo(snd_card_t *card, char *name, int reg, int check_stereo, ac97_t *ac97) + { + snd_kcontrol_t *kctl; + int err; +@@ -1196,7 +1196,7 @@ + + mute_mask = 0x8000; + val = snd_ac97_read(ac97, reg); +- if (ac97->flags & AC97_STEREO_MUTES) { ++ if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) { + /* check whether both mute bits work */ + val1 = val | 0x8080; + snd_ac97_write(ac97, reg, val1); +@@ -1254,7 +1254,7 @@ + /* + * create a mute-switch and a volume for normal stereo/mono controls + */ +-static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, ac97_t *ac97) ++static int snd_ac97_cmix_new_stereo(snd_card_t *card, const char *pfx, int reg, int check_stereo, ac97_t *ac97) + { + int err; + char name[44]; +@@ -1265,7 +1265,7 @@ + + if (snd_ac97_try_bit(ac97, reg, 15)) { + sprintf(name, "%s Switch", pfx); +- if ((err = snd_ac97_cmute_new(card, name, reg, ac97)) < 0) ++ if ((err = snd_ac97_cmute_new_stereo(card, name, reg, check_stereo, ac97)) < 0) + return err; + } + check_volume_resolution(ac97, reg, &lo_max, &hi_max); +@@ -1277,6 +1277,8 @@ + return 0; + } + ++#define snd_ac97_cmix_new(card, pfx, reg, ac97) snd_ac97_cmix_new_stereo(card, pfx, reg, 0, ac97) ++#define snd_ac97_cmute_new(card, name, reg, ac97) snd_ac97_cmute_new_stereo(card, name, reg, 0, ac97) + + static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97); + +@@ -1327,7 +1329,8 @@ + + /* build surround controls */ + if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) { +- if ((err = snd_ac97_cmix_new(card, "Surround Playback", AC97_SURROUND_MASTER, ac97)) < 0) ++ /* Surround Master (0x38) is with stereo mutes */ ++ if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0) + return err; + } + diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h index dd7a712ad6..3b464eb683 100644 --- a/tools/libxc/xc.h +++ b/tools/libxc/xc.h @@ -87,22 +87,22 @@ typedef struct xc_core_header { long xc_ptrace(enum __ptrace_request request, - u32 domid, - long addr, - long data); + u32 domid, + long addr, + long data); long xc_ptrace_core(enum __ptrace_request request, - u32 domid, - long addr, - long data); + u32 domid, + long addr, + long data); int xc_waitdomain(int domain, - int *status, - int options); + int *status, + int options); int xc_waitdomain_core(int domain, - int *status, - int options); + int *status, + int options); /* * DOMAIN MANAGEMENT FUNCTIONS @@ -110,7 +110,6 @@ int xc_waitdomain_core(int domain, typedef struct { u32 domid; - unsigned int cpu; unsigned int dying:1, crashed:1, shutdown:1, paused:1, blocked:1, running:1; unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ @@ -118,6 +117,9 @@ typedef struct { unsigned long shared_info_frame; u64 cpu_time; unsigned long max_memkb; + unsigned int vcpus; + s32 vcpu_to_cpu[MAX_VIRT_CPUS]; + cpumap_t cpumap[MAX_VIRT_CPUS]; } xc_dominfo_t; typedef dom0_getdomaininfo_t xc_domaininfo_t; @@ -129,8 +131,8 @@ int xc_domain_create(int xc_handle, int xc_domain_dumpcore(int xc_handle, - u32 domid, - const char *corename); + u32 domid, + const char *corename); /** @@ -167,7 +169,8 @@ int xc_domain_destroy(int xc_handle, u32 domid); int xc_domain_pincpu(int xc_handle, u32 domid, - int cpu); + int vcpu, + cpumap_t *cpumap); /** * This function will return information about one or more domains. * @@ -195,11 +198,11 @@ int xc_domain_getinfo(int xc_handle, * domain * @return 0 on success, -1 on failure */ -int xc_domain_getfullinfo(int xc_handle, - u32 domid, - u32 vcpu, - xc_domaininfo_t *info, - vcpu_guest_context_t *ctxt); +int xc_domain_get_vcpu_context(int xc_handle, + u32 domid, + u32 vcpu, + vcpu_guest_context_t *ctxt); + int xc_domain_setcpuweight(int xc_handle, u32 domid, float weight); @@ -260,8 +263,8 @@ xc_plan9_build (int xc_handle, u32 domid, const char *image_name, const char *cmdline, - unsigned int control_evtchn, - unsigned long flags); + unsigned int control_evtchn, + unsigned long flags); struct mem_map; int xc_vmx_build(int xc_handle, @@ -418,7 +421,7 @@ int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low, /** * Memory maps a range within one domain to a local address range. Mappings * should be unmapped with munmap and should follow the same rules as mmap - * regarding page alignment. + * regarding page alignment. Returns NULL on failure. * * In Linux, the ring queue for the control channel is accessible by mapping * the shared_info_frame (from xc_domain_getinfo()) + 2048. The structure @@ -438,7 +441,7 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, unsigned long *arr, int num ); int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, - unsigned long max_pfns); + unsigned long max_pfns); /*\ * GRANT TABLE FUNCTIONS diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c index 84ef16bf37..2d6b7d0fa2 100644 --- a/tools/libxc/xc_core.c +++ b/tools/libxc/xc_core.c @@ -7,6 +7,7 @@ /* number of pages to write at a time */ #define DUMP_INCREMENT 4 * 1024 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) + static int copy_from_domain_page(int xc_handle, u32 domid, @@ -28,13 +29,14 @@ xc_domain_dumpcore(int xc_handle, u32 domid, const char *corename) { - vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; unsigned long nr_pages; unsigned long *page_array; - xc_domaininfo_t st_info, *info = &st_info; + xc_dominfo_t info; int i, dump_fd; char *dump_mem, *dump_mem_start = NULL; struct xc_core_header header; + vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; + if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) { PERROR("Could not open corefile %s: %s", corename, strerror(errno)); @@ -46,14 +48,25 @@ xc_domain_dumpcore(int xc_handle, goto error_out; } - if (xc_domain_getfullinfo(xc_handle, domid, 0/* XXX hardcode */, info, ctxt)) { - PERROR("Could not get full info for domain"); + if (xc_domain_getinfo(xc_handle, domid, 1, &info)) { + PERROR("Could not get info for domain"); goto error_out; } + + for (i = 0; i < sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]); + i++) { + if (info.vcpu_to_cpu[i] == -1) + continue; + if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[i])) { + PERROR("Could not get all vcpu contexts for domain"); + goto error_out; + } + } + + nr_pages = info.nr_pages; - nr_pages = info->tot_pages; header.xch_magic = 0xF00FEBED; - header.xch_nr_vcpus = 1; /* no interface to query at the moment */ + header.xch_nr_vcpus = info.vcpus; header.xch_nr_pages = nr_pages; header.xch_ctxt_offset = sizeof(struct xc_core_header); header.xch_index_offset = sizeof(struct xc_core_header) + @@ -62,7 +75,7 @@ xc_domain_dumpcore(int xc_handle, sizeof(vcpu_guest_context_t) + nr_pages * sizeof(unsigned long)); write(dump_fd, &header, sizeof(struct xc_core_header)); - write(dump_fd, ctxt, sizeof(st_ctxt)); + write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus); if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) { printf("Could not allocate memory\n"); diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 488139cfd1..345af149f2 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -16,6 +16,8 @@ int xc_domain_create(int xc_handle, { int err, errno_saved; dom0_op_t op; + u32 vcpu = 0; /* FIXME, hard coded initial pin to vcpu 0 */ + cpumap_t cpumap = 1 << cpu; op.cmd = DOM0_CREATEDOMAIN; op.u.createdomain.domain = (domid_t)*pdomid; @@ -25,7 +27,7 @@ int xc_domain_create(int xc_handle, *pdomid = (u16)op.u.createdomain.domain; if ( (cpu != -1) && - ((err = xc_domain_pincpu(xc_handle, *pdomid, cpu)) != 0) ) + ((err = xc_domain_pincpu(xc_handle, *pdomid, vcpu, &cpumap)) != 0) ) goto fail; if ( (err = xc_domain_setcpuweight(xc_handle, *pdomid, cpu_weight)) != 0 ) @@ -84,13 +86,14 @@ int xc_domain_destroy(int xc_handle, int xc_domain_pincpu(int xc_handle, u32 domid, - int cpu) + int vcpu, + cpumap_t *cpumap) { dom0_op_t op; op.cmd = DOM0_PINCPUDOMAIN; - op.u.pincpudomain.domain = (domid_t)domid; - op.u.pincpudomain.exec_domain = 0; - op.u.pincpudomain.cpu = cpu; + op.u.pincpudomain.domain = (domid_t)domid; + op.u.pincpudomain.vcpu = vcpu; + op.u.pincpudomain.cpumap = cpumap; return do_dom0_op(xc_handle, &op); } @@ -109,14 +112,9 @@ int xc_domain_getinfo(int xc_handle, { op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)next_domid; - op.u.getdomaininfo.exec_domain = 0; // FIX ME?!? - op.u.getdomaininfo.ctxt = NULL; /* no exec context info, thanks. */ if ( (rc = do_dom0_op(xc_handle, &op)) < 0 ) break; - info->domid = (u16)op.u.getdomaininfo.domain; - - info->cpu = - (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK; + info->domid = (u16)op.u.getdomaininfo.domain; info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING); info->crashed = !!(op.u.getdomaininfo.flags & DOMFLAGS_CRASHED); @@ -133,29 +131,33 @@ int xc_domain_getinfo(int xc_handle, info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT); info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; info->cpu_time = op.u.getdomaininfo.cpu_time; + info->vcpus = op.u.getdomaininfo.n_vcpu; + memcpy(&info->vcpu_to_cpu, &op.u.getdomaininfo.vcpu_to_cpu, + sizeof(info->vcpu_to_cpu)); + memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap, + sizeof(info->cpumap)); next_domid = (u16)op.u.getdomaininfo.domain + 1; info++; } - if(!nr_doms) return rc; + if( !nr_doms ) return rc; return nr_doms; } -int xc_domain_getfullinfo(int xc_handle, - u32 domid, - u32 vcpu, - xc_domaininfo_t *info, - vcpu_guest_context_t *ctxt) +int xc_domain_get_vcpu_context(int xc_handle, + u32 domid, + u32 vcpu, + vcpu_guest_context_t *ctxt) { int rc, errno_saved; dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - op.u.getdomaininfo.exec_domain = (u16)vcpu; - op.u.getdomaininfo.ctxt = ctxt; + op.cmd = DOM0_GETVCPUCONTEXT; + op.u.getvcpucontext.domain = (domid_t)domid; + op.u.getvcpucontext.vcpu = (u16)vcpu; + op.u.getvcpucontext.ctxt = ctxt; if ( (ctxt != NULL) && ((rc = mlock(ctxt, sizeof(*ctxt))) != 0) ) @@ -170,10 +172,7 @@ int xc_domain_getfullinfo(int xc_handle, errno = errno_saved; } - if ( info != NULL ) - memcpy(info, &op.u.getdomaininfo, sizeof(*info)); - - if ( ((u16)op.u.getdomaininfo.domain != domid) && (rc > 0) ) + if ( rc > 0 ) return -ESRCH; else return rc; diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index abf427f87f..84e99e9457 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -356,14 +356,19 @@ int xc_linux_build(int xc_handle, op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) || ((u16)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; } + + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ) + { + PERROR("Could not get vcpu context"); + goto error_out; + } + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || (ctxt->pt_base != 0) ) { @@ -409,7 +414,7 @@ int xc_linux_build(int xc_handle, ctxt->user_regs.eip = vkern_entry; ctxt->user_regs.esp = vstartinfo_start + 2*PAGE_SIZE; ctxt->user_regs.esi = vstartinfo_start; - ctxt->user_regs.eflags = (1<<9) | (1<<2); + ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ /* FPU is set up to default initial state. */ memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); @@ -452,9 +457,9 @@ int xc_linux_build(int xc_handle, memset( &launch_op, 0, sizeof(launch_op) ); - launch_op.u.setdomaininfo.domain = (domid_t)domid; - launch_op.u.setdomaininfo.exec_domain = 0; - launch_op.u.setdomaininfo.ctxt = ctxt; + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.vcpu = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; launch_op.cmd = DOM0_SETDOMAININFO; rc = do_dom0_op(xc_handle, &launch_op); diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 3d3f4c1e18..5374ffd3a5 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -181,8 +181,6 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) /* Get the domain's shared-info frame. */ op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)dom; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = NULL; if ( do_dom0_op(xc_handle, &op) < 0 ) { xcio_error(ioctxt, "Could not get information on new domain"); @@ -636,9 +634,9 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) xcio_info(ioctxt, "Domain ready to be built.\n"); op.cmd = DOM0_SETDOMAININFO; - op.u.setdomaininfo.domain = (domid_t)dom; - op.u.setdomaininfo.exec_domain = 0; - op.u.setdomaininfo.ctxt = &ctxt; + op.u.setdomaininfo.domain = (domid_t)dom; + op.u.setdomaininfo.vcpu = 0; + op.u.setdomaininfo.ctxt = &ctxt; rc = do_dom0_op(xc_handle, &op); if ( rc != 0 ) diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index f8a28cf43f..17000d668e 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -324,7 +324,7 @@ static int analysis_phase( int xc_handle, u32 domid, int suspend_and_state(int xc_handle, XcIOContext *ioctxt, - xc_domaininfo_t *info, + xc_dominfo_t *info, vcpu_guest_context_t *ctxt) { int i=0; @@ -333,27 +333,29 @@ int suspend_and_state(int xc_handle, XcIOContext *ioctxt, retry: - if ( xc_domain_getfullinfo(xc_handle, ioctxt->domain, /* FIXME */ 0, - info, ctxt) ) + if ( xc_domain_getinfo(xc_handle, ioctxt->domain, 1, info) ) { xcio_error(ioctxt, "Could not get full domain info"); return -1; } - if ( (info->flags & - (DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<domain, 0 /* XXX */, + ctxt) ) + { + xcio_error(ioctxt, "Could not get vcpu context"); + } + + if ( info->shutdown && info->shutdown_reason == SHUTDOWN_suspend ) { return 0; // success } - if ( info->flags & DOMFLAGS_PAUSED ) + if ( info->paused ) { // try unpausing domain, wait, and retest xc_domain_unpause( xc_handle, ioctxt->domain ); - xcio_error(ioctxt, "Domain was paused. Wait and re-test. (%u)", - info->flags); + xcio_error(ioctxt, "Domain was paused. Wait and re-test."); usleep(10000); // 10ms goto retry; @@ -362,19 +364,19 @@ retry: if( ++i < 100 ) { - xcio_error(ioctxt, "Retry suspend domain (%u)", info->flags); + xcio_error(ioctxt, "Retry suspend domain."); usleep(10000); // 10ms goto retry; } - xcio_error(ioctxt, "Unable to suspend domain. (%u)", info->flags); + xcio_error(ioctxt, "Unable to suspend domain."); return -1; } int xc_linux_save(int xc_handle, XcIOContext *ioctxt) { - xc_domaininfo_t info; + xc_dominfo_t info; int rc = 1, i, j, k, last_iter, iter = 0; unsigned long mfn; @@ -444,13 +446,18 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) xcio_perror(ioctxt, "Unable to mlock ctxt"); return 1; } - - if ( xc_domain_getfullinfo( xc_handle, domid, /* FIXME */ 0, - &info, &ctxt) ) + + if ( xc_domain_getinfo(xc_handle, domid, 1, &info) ) { xcio_error(ioctxt, "Could not get full domain info"); goto out; } + if ( xc_domain_get_vcpu_context( xc_handle, domid, /* FIXME */ 0, + &ctxt) ) + { + xcio_error(ioctxt, "Could not get vcpu context"); + goto out; + } shared_info_frame = info.shared_info_frame; /* A cheesy test to see whether the domain contains valid state. */ @@ -459,7 +466,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) goto out; } - nr_pfns = info.max_pages; + nr_pfns = info.max_memkb >> PAGE_SHIFT; /* cheesy sanity check */ if ( nr_pfns > 1024*1024 ){ @@ -546,8 +553,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) if ( suspend_and_state( xc_handle, ioctxt, &info, &ctxt) ) { - xcio_error(ioctxt, "Domain appears not to have suspended: %u", - info.flags); + xcio_error(ioctxt, "Domain appears not to have suspended"); goto out; } @@ -913,14 +919,12 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) if ( suspend_and_state( xc_handle, ioctxt, &info, &ctxt) ) { xcio_error(ioctxt, - "Domain appears not to have suspended: %u", - info.flags); + "Domain appears not to have suspended"); goto out; } xcio_info(ioctxt, - "SUSPEND flags %08u shinfo %08lx eip %08u " - "esi %08u\n",info.flags, + "SUSPEND shinfo %08lx eip %08u esi %08u\n", info.shared_info_frame, ctxt.user_regs.eip, ctxt.user_regs.esi ); } diff --git a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c index 3260661acc..bfa5ccdf33 100644 --- a/tools/libxc/xc_plan9_build.c +++ b/tools/libxc/xc_plan9_build.c @@ -440,17 +440,21 @@ xc_plan9_build(int xc_handle, op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t) domid; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = ctxt; if ((do_dom0_op(xc_handle, &op) < 0) || ((u32) op.u.getdomaininfo.domain != domid)) { PERROR("Could not get info on domain"); goto error_out; } DPRINTF(("xc_get_tot_pages returns %ld pages\n", tot_pages)); + + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ) + { + PERROR("Could not get vcpu context"); + goto error_out; + } if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) - || (op.u.getdomaininfo.ctxt->pt_base != 0)) { + || (ctxt->pt_base != 0)) { ERROR("Domain is already constructed"); goto error_out; } @@ -495,7 +499,7 @@ xc_plan9_build(int xc_handle, /* why is this set? */ ctxt->user_regs.esi = ctxt->user_regs.esp; - ctxt->user_regs.eflags = (1 << 9) | (1 << 2); + ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ /* FPU is set up to default initial state. */ memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); @@ -539,7 +543,7 @@ xc_plan9_build(int xc_handle, memset(&launch_op, 0, sizeof (launch_op)); launch_op.u.setdomaininfo.domain = (domid_t) domid; - launch_op.u.setdomaininfo.exec_domain = 0; + launch_op.u.setdomaininfo.vcpu = 0; // launch_op.u.setdomaininfo.num_vifs = 1; launch_op.u.setdomaininfo.ctxt = ctxt; launch_op.cmd = DOM0_SETDOMAININFO; diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 15327ccdbb..0645af7a91 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -13,18 +13,18 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, privcmd_mmapbatch_t ioctlx; void *addr; addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0); - if ( addr != NULL ) + if ( addr == MAP_FAILED ) + return NULL; + + ioctlx.num=num; + ioctlx.dom=dom; + ioctlx.addr=(unsigned long)addr; + ioctlx.arr=arr; + if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 ) { - ioctlx.num=num; - ioctlx.dom=dom; - ioctlx.addr=(unsigned long)addr; - ioctlx.arr=arr; - if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 ) - { - perror("XXXXXXXX"); - munmap(addr, num*PAGE_SIZE); - return 0; - } + perror("XXXXXXXX"); + munmap(addr, num*PAGE_SIZE); + return NULL; } return addr; @@ -40,19 +40,19 @@ void *xc_map_foreign_range(int xc_handle, u32 dom, privcmd_mmap_entry_t entry; void *addr; addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0); - if ( addr != NULL ) + if ( addr == MAP_FAILED ) + return NULL; + + ioctlx.num=1; + ioctlx.dom=dom; + ioctlx.entry=&entry; + entry.va=(unsigned long) addr; + entry.mfn=mfn; + entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT; + if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 ) { - ioctlx.num=1; - ioctlx.dom=dom; - ioctlx.entry=&entry; - entry.va=(unsigned long) addr; - entry.mfn=mfn; - entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT; - if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 ) - { - munmap(addr, size); - return 0; - } + munmap(addr, size); + return NULL; } return addr; } @@ -173,17 +173,16 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu ) { dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - op.u.getdomaininfo.exec_domain = (u16)vcpu; - op.u.getdomaininfo.ctxt = NULL; - if ( (do_dom0_op(xc_handle, &op) < 0) || - ((u16)op.u.getdomaininfo.domain != domid) ) + op.cmd = DOM0_GETVCPUCONTEXT; + op.u.getvcpucontext.domain = (domid_t)domid; + op.u.getvcpucontext.vcpu = (u16)vcpu; + op.u.getvcpucontext.ctxt = NULL; + if ( (do_dom0_op(xc_handle, &op) < 0) ) { PERROR("Could not get info on domain"); return -1; } - return op.u.getdomaininfo.cpu_time; + return op.u.getvcpucontext.cpu_time; } @@ -258,8 +257,6 @@ long xc_get_tot_pages(int xc_handle, u32 domid) dom0_op_t op; op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = NULL; return (do_dom0_op(xc_handle, &op) < 0) ? -1 : op.u.getdomaininfo.tot_pages; } diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c index 63efdd7cb9..f465f1e085 100644 --- a/tools/libxc/xc_ptrace.c +++ b/tools/libxc/xc_ptrace.c @@ -71,7 +71,7 @@ struct gdb_regs { #define FETCH_REGS(cpu) \ if (!regs_valid[cpu]) \ { \ - int retval = xc_domain_getfullinfo(xc_handle, domid, cpu, NULL, &ctxt[cpu]); \ + int retval = xc_domain_get_vcpu_context(xc_handle, domid, cpu, &ctxt[cpu]); \ if (retval) \ goto error_out; \ cr3[cpu] = ctxt[cpu].pt_base; /* physical address */ \ @@ -221,7 +221,6 @@ xc_waitdomain(int domain, int *status, int options) { dom0_op_t op; int retval; - vcpu_guest_context_t ctxt; struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10*1000*1000; @@ -234,12 +233,10 @@ xc_waitdomain(int domain, int *status, int options) } op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = domain; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = &ctxt; retry: retval = do_dom0_op(xc_handle, &op); - if (retval) { + if (retval || op.u.getdomaininfo.domain != domain) { printf("getdomaininfo failed\n"); goto done; } @@ -314,8 +311,8 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata) op.cmd = DOM0_SETDOMAININFO; SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs); op.u.setdomaininfo.domain = domid; - /* XXX need to understand multiple exec_domains */ - op.u.setdomaininfo.exec_domain = cpu; + /* XXX need to understand multiple vcpus */ + op.u.setdomaininfo.vcpu = cpu; op.u.setdomaininfo.ctxt = &ctxt[cpu]; retval = do_dom0_op(xc_handle, &op); if (retval) @@ -325,10 +322,8 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata) case PTRACE_ATTACH: op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = domid; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = NULL; retval = do_dom0_op(xc_handle, &op); - if (retval) { + if (retval || op.u.getdomaininfo.domain != domid) { perror("dom0 op failed"); goto error_out; } @@ -345,7 +340,7 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata) ctxt[VCPU].user_regs.eflags |= PSL_T; op.cmd = DOM0_SETDOMAININFO; op.u.setdomaininfo.domain = domid; - op.u.setdomaininfo.exec_domain = 0; + op.u.setdomaininfo.vcpu = 0; op.u.setdomaininfo.ctxt = &ctxt[cpu]; retval = do_dom0_op(xc_handle, &op); if (retval) { @@ -362,7 +357,7 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata) ctxt[cpu].user_regs.eflags &= ~PSL_T; op.cmd = DOM0_SETDOMAININFO; op.u.setdomaininfo.domain = domid; - op.u.setdomaininfo.exec_domain = cpu; + op.u.setdomaininfo.vcpu = cpu; op.u.setdomaininfo.ctxt = &ctxt[cpu]; retval = do_dom0_op(xc_handle, &op); if (retval) { diff --git a/tools/libxc/xc_ptrace_core.c b/tools/libxc/xc_ptrace_core.c index a936bd8b42..7a5eeea21d 100644 --- a/tools/libxc/xc_ptrace_core.c +++ b/tools/libxc/xc_ptrace_core.c @@ -107,6 +107,7 @@ map_domain_va(unsigned long domfd, int cpu, void * guest_va) { unsigned long pde, page; unsigned long va = (unsigned long)guest_va; + void *v; static unsigned long cr3_phys[MAX_VIRT_CPUS]; static unsigned long *cr3_virt[MAX_VIRT_CPUS]; @@ -120,13 +121,15 @@ map_domain_va(unsigned long domfd, int cpu, void * guest_va) cr3_phys[cpu] = cr3[cpu]; if (cr3_virt[cpu]) munmap(cr3_virt[cpu], PAGE_SIZE); - if ((cr3_virt[cpu] = mmap(NULL, PAGE_SIZE, PROT_READ, - MAP_PRIVATE, domfd, map_mtop_offset(cr3_phys[cpu]))) == - (unsigned long*)0xffffffff) + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(cr3_phys[cpu])); + if (v == MAP_FAILED) { perror("mmap failed"); goto error_out; } + cr3_virt[cpu] = v; } if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */ goto error_out; @@ -137,9 +140,12 @@ map_domain_va(unsigned long domfd, int cpu, void * guest_va) pde_phys[cpu] = pde; if (pde_virt[cpu]) munmap(pde_virt[cpu], PAGE_SIZE); - if ((pde_virt[cpu] = mmap(NULL, PAGE_SIZE, PROT_READ, - MAP_PRIVATE, domfd, map_mtop_offset(pde_phys[cpu]))) == NULL) + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(pde_phys[cpu])); + if (v == MAP_FAILED) goto error_out; + pde_virt[cpu] = v; } if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */ goto error_out; @@ -150,12 +156,15 @@ map_domain_va(unsigned long domfd, int cpu, void * guest_va) page_phys[cpu] = page; if (page_virt[cpu]) munmap(page_virt[cpu], PAGE_SIZE); - if ((page_virt[cpu] = mmap(NULL, PAGE_SIZE, PROT_READ, - MAP_PRIVATE, domfd, map_mtop_offset(page_phys[cpu]))) == NULL) { + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(page_phys[cpu])); + if (v == MAP_FAILED) { printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va)); page_phys[cpu] = 0; goto error_out; } + page_virt[cpu] = v; } return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index a89b783fee..1edb8dc997 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -447,7 +447,7 @@ static int setup_guest(int xc_handle, ctxt->user_regs.esi = vboot_params_start; ctxt->user_regs.edi = vboot_params_start + 0x2d0; - ctxt->user_regs.eflags = (1<<2); + ctxt->user_regs.eflags = 0; return 0; @@ -543,14 +543,19 @@ int xc_vmx_build(int xc_handle, op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; - op.u.getdomaininfo.exec_domain = 0; - op.u.getdomaininfo.ctxt = ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) || ((u16)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; } + + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ) + { + PERROR("Could not get vcpu context"); + goto error_out; + } + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || (ctxt->pt_base != 0) ) { @@ -618,9 +623,9 @@ int xc_vmx_build(int xc_handle, memset( &launch_op, 0, sizeof(launch_op) ); - launch_op.u.setdomaininfo.domain = (domid_t)domid; - launch_op.u.setdomaininfo.exec_domain = 0; - launch_op.u.setdomaininfo.ctxt = ctxt; + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.vcpu = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; launch_op.cmd = DOM0_SETDOMAININFO; rc = do_dom0_op(xc_handle, &launch_op); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index faa6e06d62..a7b4aba7c6 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -155,15 +155,16 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, XcObject *xc = (XcObject *)self; u32 dom; - int cpu = -1; + int vcpu = 0; + cpumap_t cpumap = 0xFFFFFFFF; - static char *kwd_list[] = { "dom", "cpu", NULL }; + static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, - &dom, &cpu) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list, + &dom, &vcpu, &cpumap) ) return NULL; - if ( xc_domain_pincpu(xc->xc_handle, dom, cpu) != 0 ) + if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, &cpumap) != 0 ) return PyErr_SetFromErrno(xc_error); Py_INCREF(zero); @@ -175,10 +176,10 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - PyObject *list; + PyObject *list, *vcpu_list, *cpumap_list, *info_dict; u32 first_dom = 0; - int max_doms = 1024, nr_doms, i; + int max_doms = 1024, nr_doms, i, j; xc_dominfo_t *info; static char *kwd_list[] = { "first_dom", "max_doms", NULL }; @@ -195,23 +196,33 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, list = PyList_New(nr_doms); for ( i = 0 ; i < nr_doms; i++ ) { - PyList_SetItem( - list, i, - Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" - ",s:l,s:L,s:l,s:i}", - "dom", info[i].domid, - "cpu", info[i].cpu, - "dying", info[i].dying, - "crashed", info[i].crashed, - "shutdown", info[i].shutdown, - "paused", info[i].paused, - "blocked", info[i].blocked, - "running", info[i].running, - "mem_kb", info[i].nr_pages*4, - "cpu_time", info[i].cpu_time, - "maxmem_kb", info[i].max_memkb, - "shutdown_reason", info[i].shutdown_reason - )); + vcpu_list = PyList_New(MAX_VIRT_CPUS); + cpumap_list = PyList_New(MAX_VIRT_CPUS); + for ( j = 0; j < MAX_VIRT_CPUS; j++ ) { + PyList_SetItem( vcpu_list, j, + Py_BuildValue("i", info[i].vcpu_to_cpu[j])); + PyList_SetItem( cpumap_list, j, + Py_BuildValue("i", info[i].cpumap[j])); + } + + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" + ",s:l,s:L,s:l,s:i}", + "dom", info[i].domid, + "vcpus", info[i].vcpus, + "dying", info[i].dying, + "crashed", info[i].crashed, + "shutdown", info[i].shutdown, + "paused", info[i].paused, + "blocked", info[i].blocked, + "running", info[i].running, + "mem_kb", info[i].nr_pages*4, + "cpu_time", info[i].cpu_time, + "maxmem_kb", info[i].max_memkb, + "shutdown_reason", info[i].shutdown_reason); + PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list ); + PyDict_SetItemString( info_dict, "cpumap", cpumap_list ); + PyList_SetItem( list, i, info_dict); + } free(info); @@ -959,9 +970,10 @@ static PyMethodDef pyxc_methods[] = { { "domain_pincpu", (PyCFunction)pyxc_domain_pincpu, METH_VARARGS | METH_KEYWORDS, "\n" - "Pin a domain to a specified CPU.\n" - " dom [int]: Identifier of domain to be pinned.\n" - " cpu [int, -1]: CPU to pin to, or -1 to unpin\n\n" + "Pin a VCPU to a specified set CPUs.\n" + " dom [int]: Identifier of domain to which VCPU belongs.\n" + " vcpu [int, 0]: VCPU being pinned.\n" + " cpumap [int, -1]: Bitmap of usable CPUs.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "domain_getinfo", @@ -976,6 +988,7 @@ static PyMethodDef pyxc_methods[] = { " domain-id space was reached.\n" " dom [int]: Identifier of domain to which this info pertains\n" " cpu [int]: CPU to which this domain is bound\n" + " vcpus [int]: Number of Virtual CPUS in this domain\n" " dying [int]: Bool - is the domain dying?\n" " crashed [int]: Bool - has the domain crashed?\n" " shutdown [int]: Bool - has the domain shut itself down?\n" @@ -986,7 +999,8 @@ static PyMethodDef pyxc_methods[] = { " maxmem_kb [int]: Maximum memory limit, in kilobytes\n" " cpu_time [long]: CPU time consumed, in nanoseconds\n" " shutdown_reason [int]: Numeric code from guest OS, explaining " - "reason why it shut itself down.\n" }, + "reason why it shut itself down.\n" + " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" }, { "linux_save", (PyCFunction)pyxc_linux_save, diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 0be643a47f..4aa12ca930 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -236,10 +236,11 @@ class Xend: 'live' : live, 'resource' : resource }) - def xend_domain_pincpu(self, id, cpu): + def xend_domain_pincpu(self, id, vcpu, cpumap): return self.xendPost(self.domainurl(id), {'op' : 'pincpu', - 'cpu' : cpu }) + 'vcpu' : vcpu, + 'cpumap' : cpumap }) def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu): return self.xendPost(self.domainurl(id), diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 7c503f0c50..201bf2c3f7 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -675,15 +675,16 @@ class XendDomain: xmigrate = XendMigrate.instance() return xmigrate.save_begin(dominfo, dst) - def domain_pincpu(self, id, cpu): - """Pin a domain to a cpu. + def domain_pincpu(self, id, vcpu, cpumap): + """Set which cpus vcpu can use - @param id: domain - @param cpu: cpu number + @param id: domain + @param vcpu: vcpu number + @param cpumap: bitmap of usbale cpus """ dominfo = self.domain_lookup(id) try: - return xc.domain_pincpu(int(dominfo.id), cpu) + return xc.domain_pincpu(int(dominfo.id), vcpu, cpumap) except Exception, ex: raise XendError(str(ex)) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 9351e335c1..1fdfd4ca5a 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -419,8 +419,12 @@ class XendDomainInfo: if self.info['shutdown']: reason = shutdown_reason(self.info['shutdown_reason']) sxpr.append(['shutdown_reason', reason]) - sxpr.append(['cpu', self.info['cpu']]) + sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) + sxpr.append(['vcpus', self.info['vcpus']]) + sxpr.append(['cpumap', self.info['cpumap']]) + sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x), + self.info['vcpu_to_cpu'][0:self.info['vcpus']]))]) if self.start_time: up_time = time.time() - self.start_time @@ -529,7 +533,8 @@ class XendDomainInfo: raise VmError('missing memory size') cpu = sxp.child_value(config, 'cpu') if self.recreate and self.dom and cpu is not None: - xc.domain_pincpu(self.dom, int(cpu)) + #xc.domain_pincpu(self.dom, int(cpu)) + xc.domain_pincpu(self.dom, 0, 1< 1: + (x,y) = c.split('-') + for i in range(int(x),int(y)+1): + cpus.append(int(i)) + else: + cpus.append(int(c)) + cpus.sort() + for c in cpus: + cpumap = cpumap | 1<flags) ) + if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG(); #endif @@ -753,7 +753,7 @@ int construct_dom0(struct domain *d, #endif console_endboot(strstr(cmdline, "tty0") != NULL); - set_bit(DF_CONSTRUCTED, &d->flags); + set_bit(_DOMF_constructed, &d->domain_flags); new_thread(ed, pkern_entry, 0, 0); // FIXME: Hack for keyboard input @@ -783,10 +783,10 @@ int construct_domU(struct domain *d, unsigned long pkern_entry; #ifndef DOMU_AUTO_RESTART - if ( test_bit(DF_CONSTRUCTED, &d->flags) ) BUG(); + if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG(); #endif - printk("*** LOADING DOMAIN %d ***\n",d->id); + printk("*** LOADING DOMAIN %d ***\n",d->domain_id); d->max_pages = dom0_size/PAGE_SIZE; // FIXME: use dom0 size // FIXME: use domain0 command line @@ -796,13 +796,13 @@ int construct_domU(struct domain *d, d->arch.mm = xmalloc(struct mm_struct); if (unlikely(!d->arch.mm)) { - printk("Can't allocate mm_struct for domain %d\n",d->id); + printk("Can't allocate mm_struct for domain %d\n",d->domain_id); return -ENOMEM; } memset(d->arch.mm, 0, sizeof(*d->arch.mm)); d->arch.mm->pgd = pgd_alloc(d->arch.mm); if (unlikely(!d->arch.mm->pgd)) { - printk("Can't allocate pgd for domain %d\n",d->id); + printk("Can't allocate pgd for domain %d\n",d->domain_id); return -ENOMEM; } @@ -816,7 +816,7 @@ int construct_domU(struct domain *d, loaddomainelfimage(d,image_start); printk("loaddomainelfimage returns\n"); - set_bit(DF_CONSTRUCTED, &d->flags); + set_bit(_DOMF_constructed, &d->domain_flags); printk("calling new_thread, entry=%p\n",pkern_entry); #ifdef DOMU_AUTO_RESTART @@ -836,7 +836,7 @@ void reconstruct_domU(struct exec_domain *ed) { /* re-copy the OS image to reset data values to original */ printk("reconstruct_domU: restarting domain %d...\n", - ed->domain->id); + ed->domain->domain_id); loaddomainelfimage(ed->domain,ed->domain->arch.image_start); new_thread(ed, ed->domain->arch.entry, 0, 0); } @@ -859,7 +859,7 @@ int launch_domainU(unsigned long size) else next++; if (construct_domU(d, (unsigned long)domU_staging_area, size,0,0,0)) { printf("launch_domainU: couldn't construct(id=%d,%lx,%lx)\n", - d->id,domU_staging_area,size); + d->domain_id,domU_staging_area,size); return 2; } domain_unpause_by_systemcontroller(d); diff --git a/xen/arch/ia64/idle0_task.c b/xen/arch/ia64/idle0_task.c index 4bc636ae6e..8aa41a131c 100644 --- a/xen/arch/ia64/idle0_task.c +++ b/xen/arch/ia64/idle0_task.c @@ -21,8 +21,8 @@ #define IDLE0_DOMAIN(_t) \ { \ - id: IDLE_DOMAIN_ID, \ - flags: 1<cr_ipsr & IA64_PSR_RI; if (vcpu_timer_pending_early(ed)) -printf("*#*#*#* about to deliver early timer to domain %d!!!\n",ed->domain->id); +printf("*#*#*#* about to deliver early timer to domain %d!!!\n",ed->domain->domain_id); reflect_interruption(0,isr,0,regs,IA64_EXTINT_VECTOR); } } diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index 2f5562c46a..5e03a07493 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -234,21 +234,21 @@ void context_switch(struct exec_domain *prev, struct exec_domain *next) { //printk("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); //printk("@@@@@@ context switch from domain %d (%x) to domain %d (%x)\n", -//prev->domain->id,(long)prev&0xffffff,next->domain->id,(long)next&0xffffff); -//if (prev->domain->id == 1 && next->domain->id == 0) cs10foo(); -//if (prev->domain->id == 0 && next->domain->id == 1) cs01foo(); -//printk("@@sw %d->%d\n",prev->domain->id,next->domain->id); +//prev->domain->domain_id,(long)prev&0xffffff,next->domain->domain_id,(long)next&0xffffff); +//if (prev->domain->domain_id == 1 && next->domain->domain_id == 0) cs10foo(); +//if (prev->domain->domain_id == 0 && next->domain->domain_id == 1) cs01foo(); +//printk("@@sw %d->%d\n",prev->domain->domain_id,next->domain->domain_id); switch_to(prev,next,prev); // leave this debug for now: it acts as a heartbeat when more than // one domain is active { static long cnt[16] = { 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50}; static int i = 100; -int id = ((struct exec_domain *)current)->domain->id & 0xf; +int id = ((struct exec_domain *)current)->domain->domain_id & 0xf; if (!cnt[id]--) { printk("%x",id); cnt[id] = 50; } if (!i--) { printk("+",id); cnt[id] = 100; } } - clear_bit(EDF_RUNNING, &prev->flags); + clear_bit(_VCPUF_running, &prev->vcpu_flags); //if (!is_idle_task(next->domain) ) //send_guest_virq(next, VIRQ_TIMER); load_region_regs(current); @@ -271,15 +271,15 @@ void panic_domain(struct pt_regs *regs, const char *fmt, ...) loop: printf("$$$$$ PANIC in domain %d (k6=%p): ", - ed->domain->id, ia64_get_kr(IA64_KR_CURRENT)); + ed->domain->domain_id, ia64_get_kr(IA64_KR_CURRENT)); va_start(args, fmt); (void)vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printf(buf); if (regs) show_registers(regs); domain_pause_by_systemcontroller(current->domain); - set_bit(DF_CRASHED, ed->domain->flags); - if (ed->domain->id == 0) { + set_bit(_DOMF_crashed, ed->domain->domain_flags); + if (ed->domain->domain_id == 0) { int i = 1000000000L; // if domain0 crashes, just periodically print out panic // message to make post-mortem easier diff --git a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c index ec864e1ef2..c2ba2efac4 100644 --- a/xen/arch/ia64/xensetup.c +++ b/xen/arch/ia64/xensetup.c @@ -52,15 +52,10 @@ unsigned char opt_com1[30] = "", opt_com2[30] = ""; unsigned int opt_dom0_mem = 16000; /* opt_noht: If true, Hyperthreading is ignored. */ int opt_noht=0; -/* opt_noacpi: If true, ACPI tables are not parsed. */ -int opt_noacpi=0; /* opt_nosmp: If true, secondary processors are ignored. */ int opt_nosmp=0; /* opt_noreboot: If true, machine will need manual reset on error. */ int opt_noreboot=0; -/* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */ -/* NB. This flag implies 'nosmp' and 'noacpi'. */ -int opt_ignorebiostables=0; /* opt_watchdog: If true, run a watchdog NMI on each processor. */ int opt_watchdog=0; /* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */ @@ -267,7 +262,7 @@ printk("About to call init_idle_task()\n"); if ( dom0 == NULL ) panic("Error creating domain 0\n"); - set_bit(DF_PRIVILEGED, &dom0->flags); + set_bit(_DOMF_privileged, &dom0->domain_flags); /* * We're going to setup domain0 using the module(s) that we stashed safely diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c index c8525bce64..99fc21b018 100644 --- a/xen/arch/x86/acpi/boot.c +++ b/xen/arch/x86/acpi/boot.c @@ -36,26 +36,13 @@ #include #include #include +#include +#include int sbf_port; #define end_pfn_map max_page #define CONFIG_ACPI_PCI -#ifdef CONFIG_X86_64 - -static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { } -extern void __init clustered_apic_check(void); -static inline int ioapic_setup_disabled(void) { return 0; } - -#else /* X86 */ - -#ifdef CONFIG_X86_LOCAL_APIC -#include -#include -#endif /* CONFIG_X86_LOCAL_APIC */ - -#endif /* X86 */ - #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) diff --git a/xen/arch/x86/audit.c b/xen/arch/x86/audit.c index b7e874c62d..c15c3de31e 100644 --- a/xen/arch/x86/audit.c +++ b/xen/arch/x86/audit.c @@ -74,7 +74,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { APRINTK("Audit %d: type count went below zero " "mfn=%lx t=%x ot=%x", - d->id, page_to_pfn(page), + d->domain_id, page_to_pfn(page), page->u.inuse.type_info, page->tlbflush_timestamp); errors++; @@ -83,7 +83,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { APRINTK("Audit %d: type count overflowed " "mfn=%lx t=%x ot=%x", - d->id, page_to_pfn(page), + d->domain_id, page_to_pfn(page), page->u.inuse.type_info, page->tlbflush_timestamp); errors++; @@ -102,7 +102,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { APRINTK("Audit %d: general count went below zero " "mfn=%lx t=%x ot=%x", - d->id, page_to_pfn(page), + d->domain_id, page_to_pfn(page), page->u.inuse.type_info, page->tlbflush_timestamp); errors++; @@ -111,7 +111,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { APRINTK("Audit %d: general count overflowed " "mfn=%lx t=%x ot=%x", - d->id, page_to_pfn(page), + d->domain_id, page_to_pfn(page), page->u.inuse.type_info, page->tlbflush_timestamp); errors++; @@ -142,7 +142,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) "belonging to a domain %p (id=%d)\n", l1mfn, page_get_owner(l1page), - page_get_owner(l1page)->id); + page_get_owner(l1page)->domain_id); errors++; continue; } @@ -153,7 +153,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [Shadow L2 mfn=%lx i=%x] " "Expected Shadow L1 t=%x mfn=%lx\n", - d->id, mfn, i, + d->domain_id, mfn, i, l1page->u.inuse.type_info, l1mfn); errors++; } @@ -167,7 +167,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) l1mfn, page_get_owner(l1page), (page_get_owner(l1page) - ? page_get_owner(l1page)->id + ? page_get_owner(l1page)->domain_id : -1)); errors++; continue; @@ -179,14 +179,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [%x] Found %s Linear PT " "t=%x mfn=%lx\n", - d->id, i, (l1mfn==mfn) ? "Self" : "Other", + d->domain_id, i, (l1mfn==mfn) ? "Self" : "Other", l1page->u.inuse.type_info, l1mfn); } else if ( page_type != PGT_l1_page_table ) { printk("Audit %d: [L2 mfn=%lx i=%x] " "Expected L1 t=%x mfn=%lx\n", - d->id, mfn, i, + d->domain_id, mfn, i, l1page->u.inuse.type_info, l1mfn); errors++; } @@ -238,9 +238,9 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [hl2mfn=%lx,i=%x] Skip foreign page " "dom=%p (id=%d) mfn=%lx c=%08x t=%08x\n", - d->id, hl2mfn, i, + d->domain_id, hl2mfn, i, page_get_owner(gpage), - page_get_owner(gpage)->id, + page_get_owner(gpage)->domain_id, gmfn, gpage->count_info, gpage->u.inuse.type_info); @@ -289,7 +289,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [l1mfn=%lx, i=%x] Illegal RW " "t=%x mfn=%lx\n", - d->id, l1mfn, i, + d->domain_id, l1mfn, i, gpage->u.inuse.type_info, gmfn); errors++; } @@ -300,7 +300,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [l1mfn=%lx, i=%x] Illegal RW of " "page table gmfn=%lx\n", - d->id, l1mfn, i, gmfn); + d->domain_id, l1mfn, i, gmfn); errors++; } } @@ -309,9 +309,9 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: [l1mfn=%lx,i=%x] Skip foreign page " "dom=%p (id=%d) mfn=%lx c=%08x t=%08x\n", - d->id, l1mfn, i, + d->domain_id, l1mfn, i, page_get_owner(gpage), - page_get_owner(gpage)->id, + page_get_owner(gpage)->domain_id, gmfn, gpage->count_info, gpage->u.inuse.type_info); @@ -455,7 +455,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) { printk("Audit %d: found an L2 guest page " "mfn=%lx t=%08x c=%08x while in shadow mode\n", - d->id, mfn, page->u.inuse.type_info, + d->domain_id, mfn, page->u.inuse.type_info, page->count_info); errors++; } @@ -466,14 +466,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) PGT_validated ) { printk("Audit %d: L2 mfn=%lx not validated %08x\n", - d->id, mfn, page->u.inuse.type_info); + d->domain_id, mfn, page->u.inuse.type_info); errors++; } if ( (page->u.inuse.type_info & PGT_pinned) != PGT_pinned ) { printk("Audit %d: L2 mfn=%lx not pinned t=%08x\n", - d->id, mfn, page->u.inuse.type_info); + d->domain_id, mfn, page->u.inuse.type_info); errors++; } } @@ -506,7 +506,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) PGT_validated ) { printk("Audit %d: L1 not validated mfn=%lx t=%08x\n", - d->id, mfn, page->u.inuse.type_info); + d->domain_id, mfn, page->u.inuse.type_info); errors++; } @@ -515,7 +515,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) if ( !VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ) { printk("Audit %d: L1 mfn=%lx not pinned t=%08x\n", - d->id, mfn, page->u.inuse.type_info); + d->domain_id, mfn, page->u.inuse.type_info); } } } @@ -601,7 +601,7 @@ void audit_pagelist(struct domain *d) if ( xenpages != d->xenheap_pages || totpages != d->tot_pages ) { - printk("ARGH! dom %d: xen=%d %d, pages=%d %d\n", d->id, + printk("ARGH! dom %d: xen=%d %d, pages=%d %d\n", d->domain_id, xenpages, d->xenheap_pages, totpages, d->tot_pages ); } @@ -623,7 +623,7 @@ void _audit_domain(struct domain *d, int flags) if ( (pt[i] & _PAGE_PRESENT) && ((pt[i] >> PAGE_SHIFT) == xmfn) ) printk(" found dom=%d mfn=%lx t=%08x c=%08x " "pt[i=%x]=%lx\n", - d->id, mfn, page->u.inuse.type_info, + d->domain_id, mfn, page->u.inuse.type_info, page->count_info, i, pt[i]); } @@ -721,7 +721,7 @@ void _audit_domain(struct domain *d, int flags) { printk("skipping audit domain of translated domain %d " "from other context\n", - d->id); + d->domain_id); return; } @@ -832,7 +832,7 @@ void _audit_domain(struct domain *d, int flags) if ( !(flags & AUDIT_QUIET) && ((io_mappings > 0) || (lowmem_mappings > 0)) ) printk("Audit %d: Found %d lowmem mappings and %d io mappings\n", - d->id, lowmem_mappings, io_mappings); + d->domain_id, lowmem_mappings, io_mappings); /* PHASE 2 */ @@ -849,7 +849,7 @@ void _audit_domain(struct domain *d, int flags) if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) { printk("Audit %d: type count!=0 t=%x ot=%x c=%x mfn=%lx\n", - d->id, page->u.inuse.type_info, + d->domain_id, page->u.inuse.type_info, page->tlbflush_timestamp, page->count_info, mfn); errors++; @@ -863,7 +863,7 @@ void _audit_domain(struct domain *d, int flags) if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) { printk("Audit %d: type count!=0 t=%x ot=%x c=%x mfn=%lx\n", - d->id, page->u.inuse.type_info, + d->domain_id, page->u.inuse.type_info, page->tlbflush_timestamp, page->count_info, mfn); //errors++; @@ -876,7 +876,7 @@ void _audit_domain(struct domain *d, int flags) if ( (page->count_info & PGC_count_mask) != 1 ) { printk("Audit %d: gen count!=1 (c=%x) t=%x ot=%x mfn=%lx\n", - d->id, + d->domain_id, page->count_info, page->u.inuse.type_info, page->tlbflush_timestamp, mfn ); @@ -912,7 +912,7 @@ void _audit_domain(struct domain *d, int flags) { printk("Audit %d: shadow page counts wrong " "mfn=%lx t=%08x c=%08x\n", - d->id, page_to_pfn(page), + d->domain_id, page_to_pfn(page), page->u.inuse.type_info, page->count_info); printk("a->gpfn_and_flags=%p\n", @@ -950,7 +950,7 @@ void _audit_domain(struct domain *d, int flags) if ( !(flags & AUDIT_QUIET) ) printk("Audit dom%d Done. " "pages=%d oos=%d l1=%d l2=%d ctot=%d ttot=%d\n", - d->id, page_count, oos_count, l1, l2, ctot, ttot); + d->domain_id, page_count, oos_count, l1, l2, ctot, ttot); if ( !(flags & AUDIT_SHADOW_ALREADY_LOCKED) ) shadow_unlock(d); diff --git a/xen/arch/x86/cdb.c b/xen/arch/x86/cdb.c index 6eb3515ec2..451ce46853 100644 --- a/xen/arch/x86/cdb.c +++ b/xen/arch/x86/cdb.c @@ -12,7 +12,9 @@ #include #include #include -#include +#include +#include +#include /* Printk isn't particularly safe just after we've trapped to the debugger. so avoid it. */ diff --git a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c index a3251368ce..171cb3b8a6 100644 --- a/xen/arch/x86/dom0_ops.c +++ b/xen/arch/x86/dom0_ops.c @@ -397,7 +397,7 @@ void arch_getdomaininfo_ctxt( #endif c->flags = 0; - if ( test_bit(EDF_DONEFPUINIT, &ed->flags) ) + if ( test_bit(_VCPUF_fpu_initialised, &ed->vcpu_flags) ) c->flags |= VGCF_I387_VALID; if ( KERNEL_MODE(ed, &ed->arch.guest_context.user_regs) ) c->flags |= VGCF_IN_KERNEL; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index ebfc81387c..b2595ceac4 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -100,7 +100,7 @@ void startup_cpu_idle_loop(void) struct exec_domain *ed = current; /* Just some sanity to ensure that the scheduler is set up okay. */ - ASSERT(ed->domain->id == IDLE_DOMAIN_ID); + ASSERT(ed->domain->domain_id == IDLE_DOMAIN_ID); percpu_ctxt[smp_processor_id()].curr_ed = ed; set_bit(smp_processor_id(), &ed->domain->cpuset); domain_unpause_by_systemcontroller(ed->domain); @@ -246,13 +246,14 @@ void arch_do_createdomain(struct exec_domain *ed) ed->arch.flags = TF_kernel_mode; - if ( d->id != IDLE_DOMAIN_ID ) + if ( d->domain_id != IDLE_DOMAIN_ID ) { ed->arch.schedule_tail = continue_nonidle_task; d->shared_info = (void *)alloc_xenheap_page(); memset(d->shared_info, 0, PAGE_SIZE); - ed->vcpu_info = &d->shared_info->vcpu_data[ed->id]; + ed->vcpu_info = &d->shared_info->vcpu_data[ed->vcpu_id]; + ed->cpumap = CPUMAP_RUNANYWHERE; SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); machine_to_phys_mapping[virt_to_phys(d->shared_info) >> PAGE_SHIFT] = INVALID_M2P_ENTRY; @@ -294,7 +295,7 @@ void arch_do_boot_vcpu(struct exec_domain *ed) struct domain *d = ed->domain; ed->arch.schedule_tail = d->exec_domain[0]->arch.schedule_tail; ed->arch.perdomain_ptes = - d->arch.mm_perdomain_pt + (ed->id << PDPT_VCPU_SHIFT); + d->arch.mm_perdomain_pt + (ed->vcpu_id << PDPT_VCPU_SHIFT); ed->arch.flags = TF_kernel_mode; } @@ -398,9 +399,9 @@ int arch_set_info_guest( return -EINVAL; } - clear_bit(EDF_DONEFPUINIT, &ed->flags); + clear_bit(_VCPUF_fpu_initialised, &ed->vcpu_flags); if ( c->flags & VGCF_I387_VALID ) - set_bit(EDF_DONEFPUINIT, &ed->flags); + set_bit(_VCPUF_fpu_initialised, &ed->vcpu_flags); ed->arch.flags &= ~TF_kernel_mode; if ( c->flags & VGCF_IN_KERNEL ) @@ -408,15 +409,17 @@ int arch_set_info_guest( memcpy(&ed->arch.guest_context, c, sizeof(*c)); - /* IOPL privileges are virtualised. */ - ed->arch.iopl = (ed->arch.guest_context.user_regs.eflags >> 12) & 3; - ed->arch.guest_context.user_regs.eflags &= ~EF_IOPL; + if ( !(c->flags & VGCF_VMX_GUEST) ) + { + /* IOPL privileges are virtualised. */ + ed->arch.iopl = (ed->arch.guest_context.user_regs.eflags >> 12) & 3; + ed->arch.guest_context.user_regs.eflags &= ~EF_IOPL; - /* Clear IOPL for unprivileged domains. */ - if ( !IS_PRIV(d) ) - ed->arch.guest_context.user_regs.eflags &= 0xffffcfff; + /* Ensure real hardware interrupts are enabled. */ + ed->arch.guest_context.user_regs.eflags |= EF_IE; + } - if ( test_bit(EDF_DONEINIT, &ed->flags) ) + if ( test_bit(_VCPUF_initialised, &ed->vcpu_flags) ) return 0; if ( (rc = (int)set_fast_trap(ed, c->fast_trap_idx)) != 0 ) @@ -427,7 +430,7 @@ int arch_set_info_guest( for ( i = 0; i < 8; i++ ) (void)set_debugreg(ed, i, c->debugreg[i]); - if ( ed->id == 0 ) + if ( ed->vcpu_id == 0 ) d->vm_assist = c->vm_assist; phys_basetab = c->pt_base; @@ -479,7 +482,7 @@ int arch_set_info_guest( update_pagetables(ed); /* Don't redo final setup */ - set_bit(EDF_DONEINIT, &ed->flags); + set_bit(_VCPUF_initialised, &ed->vcpu_flags); return 0; } @@ -797,7 +800,7 @@ void context_switch(struct exec_domain *prev, struct exec_domain *next) * 'prev' (after this point, a dying domain's info structure may be freed * without warning). */ - clear_bit(EDF_RUNNING, &prev->flags); + clear_bit(_VCPUF_running, &prev->vcpu_flags); schedule_tail(next); BUG(); diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 7ed67f4b6b..560cea0a99 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -21,9 +22,18 @@ #include #include -/* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */ -static unsigned int opt_dom0_mem = 0; -integer_unit_param("dom0_mem", opt_dom0_mem); +/* opt_dom0_mem: memory allocated to domain 0. */ +static unsigned int opt_dom0_mem; +static void parse_dom0_mem(char *s) +{ + unsigned long long bytes = memparse(s); + /* If no unit is specified we default to kB units, not bytes. */ + if ( isdigit(s[strlen(s)-1]) ) + opt_dom0_mem = (unsigned int)bytes; + else + opt_dom0_mem = (unsigned int)(bytes >> 10); +} +custom_param("dom0_mem", parse_dom0_mem); static unsigned int opt_dom0_shadow = 0; boolean_param("dom0_shadow", opt_dom0_shadow); @@ -112,9 +122,9 @@ int construct_dom0(struct domain *d, extern void translate_l2pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn); /* Sanity! */ - if ( d->id != 0 ) + if ( d->domain_id != 0 ) BUG(); - if ( test_bit(DF_CONSTRUCTED, &d->flags) ) + if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG(); memset(&dsi, 0, sizeof(struct domain_setup_info)); @@ -540,7 +550,7 @@ int construct_dom0(struct domain *d, /* DOM0 gets access to everything. */ physdev_init_dom0(d); - set_bit(DF_CONSTRUCTED, &d->flags); + set_bit(_DOMF_constructed, &d->domain_flags); new_thread(ed, dsi.v_kernentry, vstack_end, vstartinfo_start); diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index 30c8d8b9bb..7c0050185f 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -3,6 +3,11 @@ #include #include +/* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */ +unsigned long long opt_mem; +static void parse_mem(char *s) { opt_mem = memparse(s); } +custom_param("mem", parse_mem); + struct e820map e820; static void __init add_memory_region(unsigned long long start, @@ -341,6 +346,31 @@ static void __init clip_4gb(void) #define clip_4gb() ((void)0) #endif +static void __init clip_mem(void) +{ + int i; + + if ( !opt_mem ) + return; + + for ( i = 0; i < e820.nr_map; i++ ) + { + if ( (e820.map[i].addr + e820.map[i].size) <= opt_mem ) + continue; + printk("Truncating memory map to %lukB\n", + (unsigned long)(opt_mem >> 10)); + if ( e820.map[i].addr >= opt_mem ) + { + e820.nr_map = i; + } + else + { + e820.map[i].size = opt_mem - e820.map[i].addr; + e820.nr_map = i + 1; + } + } +} + static void __init machine_specific_memory_setup( struct e820entry *raw, int raw_nr) { @@ -348,6 +378,7 @@ static void __init machine_specific_memory_setup( sanitize_e820_map(raw, &nr); (void)copy_e820_map(raw, nr); clip_4gb(); + clip_mem(); } unsigned long __init init_e820(struct e820entry *raw, int raw_nr) diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index af54d0af8a..b859e74110 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -18,7 +18,7 @@ void init_fpu(void) __asm__ __volatile__ ( "fninit" ); if ( cpu_has_xmm ) load_mxcsr(0x1f80); - set_bit(EDF_DONEFPUINIT, ¤t->flags); + set_bit(_VCPUF_fpu_initialised, ¤t->vcpu_flags); } void save_init_fpu(struct exec_domain *tsk) @@ -28,7 +28,7 @@ void save_init_fpu(struct exec_domain *tsk) * This causes us to set the real flag, so we'll need * to temporarily clear it while saving f-p state. */ - if ( test_bit(EDF_GUEST_STTS, &tsk->flags) ) + if ( test_bit(_VCPUF_guest_stts, &tsk->vcpu_flags) ) clts(); if ( cpu_has_fxsr ) @@ -40,7 +40,7 @@ void save_init_fpu(struct exec_domain *tsk) "fnsave %0 ; fwait" : "=m" (tsk->arch.guest_context.fpu_ctxt) ); - clear_bit(EDF_USEDFPU, &tsk->flags); + clear_bit(_VCPUF_fpu_dirtied, &tsk->vcpu_flags); stts(); } diff --git a/xen/arch/x86/idle0_task.c b/xen/arch/x86/idle0_task.c index 43c0c31c25..7e811b28e8 100644 --- a/xen/arch/x86/idle0_task.c +++ b/xen/arch/x86/idle0_task.c @@ -4,8 +4,8 @@ #include struct domain idle0_domain = { - id: IDLE_DOMAIN_ID, - flags: 1<domain->id , __LINE__ , ## _a ) + current->domain->domain_id , __LINE__ , ## _a ) #else #define MEM_LOG(_f, _a...) ((void)0) #endif @@ -183,7 +183,7 @@ void arch_init_memory(void) */ dom_xen = alloc_domain_struct(); atomic_set(&dom_xen->refcnt, 1); - dom_xen->id = DOMID_XEN; + dom_xen->domain_id = DOMID_XEN; /* * Initialise our DOMID_IO domain. @@ -192,7 +192,7 @@ void arch_init_memory(void) */ dom_io = alloc_domain_struct(); atomic_set(&dom_io->refcnt, 1); - dom_io->id = DOMID_IO; + dom_io->domain_id = DOMID_IO; /* First 1MB of RAM is historically marked as I/O. */ for ( i = 0; i < 0x100; i++ ) @@ -1162,7 +1162,7 @@ void put_page_type(struct pfn_info *page) * See domain.c:relinquish_list(). */ ASSERT((x & PGT_validated) || - test_bit(DF_DYING, &page_get_owner(page)->flags)); + test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)); if ( unlikely((nx & PGT_count_mask) == 0) ) { @@ -1392,7 +1392,7 @@ static int set_foreigndom(unsigned int cpu, domid_t domid) percpu_info[cpu].foreign = dom_io; break; default: - MEM_LOG("Dom %u cannot set foreign dom\n", d->id); + MEM_LOG("Dom %u cannot set foreign dom\n", d->domain_id); okay = 0; break; } @@ -1645,7 +1645,7 @@ int do_mmuext_op( if ( shadow_mode_external(d) ) { MEM_LOG("ignoring SET_LDT hypercall from external " - "domain %u\n", d->id); + "domain %u\n", d->domain_id); okay = 0; break; } @@ -1676,7 +1676,7 @@ int do_mmuext_op( case MMUEXT_REASSIGN_PAGE: if ( unlikely(!IS_PRIV(d)) ) { - MEM_LOG("Dom %u has no reassignment priv", d->id); + MEM_LOG("Dom %u has no reassignment priv", d->domain_id); okay = 0; break; } @@ -1711,13 +1711,13 @@ int do_mmuext_op( * it is dying. */ ASSERT(e->tot_pages <= e->max_pages); - if ( unlikely(test_bit(DF_DYING, &e->flags)) || + if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) || unlikely(e->tot_pages == e->max_pages) || unlikely(IS_XEN_HEAP_FRAME(page)) ) { MEM_LOG("Transferee has no reservation headroom (%d,%d), or " "page is in Xen heap (%lx), or dom is dying (%ld).\n", - e->tot_pages, e->max_pages, op.mfn, e->flags); + e->tot_pages, e->max_pages, op.mfn, e->domain_flags); okay = 0; goto reassign_fail; } @@ -1738,7 +1738,7 @@ int do_mmuext_op( { MEM_LOG("Bad page values %lx: ed=%p(%u), sd=%p," " caf=%08x, taf=%08x\n", page_to_pfn(page), - d, d->id, unpickle_domptr(_nd), x, + d, d->domain_id, unpickle_domptr(_nd), x, page->u.inuse.type_info); okay = 0; goto reassign_fail; @@ -1990,7 +1990,7 @@ int do_mmu_update( { shadow_lock(FOREIGNDOM); printk("privileged guest dom%d requests pfn=%lx to map mfn=%lx for dom%d\n", - d->id, gpfn, mfn, FOREIGNDOM->id); + d->domain_id, gpfn, mfn, FOREIGNDOM->domain_id); set_machinetophys(mfn, gpfn); set_p2m_entry(FOREIGNDOM, gpfn, mfn, &sh_mapcache, &mapcache); okay = 1; @@ -2452,7 +2452,7 @@ int revalidate_l1(struct domain *d, l1_pgentry_t *l1page, l1_pgentry_t *snapshot int modified = 0, i; #if 0 - if ( d->id ) + if ( d->domain_id ) printk("%s: l1page mfn=%lx snapshot mfn=%lx\n", __func__, l1e_get_pfn(linear_pg_table[l1_linear_offset((unsigned long)l1page)]), l1e_get_pfn(linear_pg_table[l1_linear_offset((unsigned long)snapshot)])); @@ -2909,7 +2909,7 @@ void ptwr_destroy(struct domain *d) { MEM_LOG("Bad page values %p: ed=%p(%u), sd=%p," " caf=%08x, taf=%08x\n", page_to_pfn(page), - d, d->id, unpickle_domptr(_nd), x, + d, d->domain_id, unpickle_domptr(_nd), x, page->u.inuse.type_info); spin_unlock(&d->page_alloc_lock); put_domain(e); @@ -2939,7 +2939,7 @@ void ptwr_destroy(struct domain *d) * Also, a domain mustn't have PGC_allocated pages when it is dying. */ ASSERT(e->tot_pages <= e->max_pages); - if ( unlikely(test_bit(DF_DYING, &e->flags)) || + if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) || unlikely(e->tot_pages == e->max_pages) || unlikely(!gnttab_prepare_for_transfer(e, d, gntref)) ) { diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 5de96ec96d..94cf15e2eb 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -128,7 +128,7 @@ void physdev_init_dom0(struct domain *d) BUG_ON(d->arch.iobmp_mask == NULL); memset(d->arch.iobmp_mask, 0, IOBMP_BYTES); - set_bit(DF_PHYSDEV, &d->flags); + set_bit(_DOMF_physdev_access, &d->domain_flags); } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 7310095f64..a43b8e0762 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -33,23 +33,29 @@ integer_param("xenheap_megabytes", opt_xenheap_megabytes); int opt_noht = 0; boolean_param("noht", opt_noht); -/* opt_noacpi: If true, ACPI tables are not parsed. */ -static int opt_noacpi = 0; -boolean_param("noacpi", opt_noacpi); - -/* opt_nosmp: If true, secondary processors are ignored. */ -static int opt_nosmp = 0; -boolean_param("nosmp", opt_nosmp); - -/* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */ -/* NB. This flag implies 'nosmp' and 'noacpi'. */ -static int opt_ignorebiostables = 0; -boolean_param("ignorebiostables", opt_ignorebiostables); - /* opt_watchdog: If true, run a watchdog NMI on each processor. */ static int opt_watchdog = 0; boolean_param("watchdog", opt_watchdog); +/* **** Linux config option: propagated to domain0. */ +/* "acpi=off": Sisables both ACPI table parsing and interpreter. */ +/* "acpi=force": Override the disable blacklist. */ +/* "acpi=strict": Disables out-of-spec workarounds. */ +/* "acpi=ht": Limit ACPI just to boot-time to enable HT. */ +/* "acpi=noirq": Disables ACPI interrupt routing. */ +static void parse_acpi_param(char *s); +custom_param("acpi", parse_acpi_param); + +/* **** Linux config option: propagated to domain0. */ +/* acpi_skip_timer_override: Skip IRQ0 overrides. */ +extern int acpi_skip_timer_override; +boolean_param("acpi_skip_timer_override", acpi_skip_timer_override); + +/* **** Linux config option: propagated to domain0. */ +/* noapic: Disable IOAPIC setup. */ +extern int skip_ioapic_setup; +boolean_param("noapic", skip_ioapic_setup); + int early_boot = 1; unsigned long xenheap_phys_end; @@ -62,7 +68,6 @@ extern void ac_timer_init(void); extern void initialize_keytable(); extern int do_timer_lists_from_pit; -char ignore_irq13; /* set if exception 16 works */ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1 }; #if defined(__x86_64__) @@ -328,6 +333,41 @@ void __init cpu_init(void) init_idle_task(); } +int acpi_force; +char acpi_param[10] = ""; +static void parse_acpi_param(char *s) +{ + /* Save the parameter so it can be propagated to domain0. */ + strncpy(acpi_param, s, sizeof(acpi_param)); + acpi_param[sizeof(acpi_param)-1] = '\0'; + + /* Interpret the parameter for use within Xen. */ + if ( !strcmp(s, "off") ) + { + disable_acpi(); + } + else if ( !strcmp(s, "force") ) + { + acpi_force = 1; + acpi_ht = 1; + acpi_disabled = 0; + } + else if ( !strcmp(s, "strict") ) + { + acpi_strict = 1; + } + else if ( !strcmp(s, "ht") ) + { + if ( !acpi_force ) + disable_acpi(); + acpi_ht = 1; + } + else if ( !strcmp(s, "noirq") ) + { + acpi_noirq_set(); + } +} + static void __init do_initcalls(void) { initcall_t *call; @@ -355,54 +395,36 @@ static void __init start_of_day(void) identify_cpu(&boot_cpu_data); /* get CPU type info */ if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR); if ( cpu_has_xmm ) set_in_cr4(X86_CR4_OSXMMEXCPT); -#ifdef CONFIG_SMP - if ( opt_ignorebiostables ) - { - opt_nosmp = 1; /* No SMP without configuration */ - opt_noacpi = 1; /* ACPI will just confuse matters also */ - } - else - { - find_smp_config(); - smp_alloc_memory(); /* trampoline which other CPUs jump at */ - } -#endif - paging_init(); /* not much here now, but sets up fixmap */ - if ( !opt_noacpi ) - { - acpi_boot_table_init(); - acpi_boot_init(); - } -#ifdef CONFIG_SMP + + find_smp_config(); + + smp_alloc_memory(); + + paging_init(); + + acpi_boot_table_init(); + acpi_boot_init(); + if ( smp_found_config ) get_smp_config(); -#endif - init_apic_mappings(); /* make APICs addressable in our pagetables. */ + + init_apic_mappings(); + scheduler_init(); - init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ + + init_IRQ(); + trap_init(); - time_init(); /* installs software handler for HZ clock. */ + + time_init(); arch_init_memory(); -#ifndef CONFIG_SMP - APIC_init_uniprocessor(); -#else - if ( opt_nosmp ) - APIC_init_uniprocessor(); - else - smp_boot_cpus(); - /* - * Does loads of stuff, including kicking the local - * APIC, and the IO APIC after other CPUs are booted. - * Each IRQ is preferably handled by IO-APIC, but - * fall thru to 8259A if we have to (but slower). - */ -#endif + smp_boot_cpus(); __sti(); - initialize_keytable(); /* call back handling for key codes */ + initialize_keytable(); serial_init_stage2(); @@ -419,19 +441,14 @@ static void __init start_of_day(void) check_nmi_watchdog(); -#ifdef CONFIG_PCI - pci_init(); -#endif do_initcalls(); -#ifdef CONFIG_SMP wait_init_idle = cpu_online_map; clear_bit(smp_processor_id(), &wait_init_idle); smp_threads_ready = 1; smp_commence(); /* Tell other CPUs that state of the world is stable. */ while ( wait_init_idle != 0 ) cpu_relax(); -#endif watchdog_on = 1; #ifdef __x86_64__ /* x86_32 uses low mappings when building DOM0. */ @@ -570,15 +587,34 @@ void __init __start_xen(multiboot_info_t *mbi) if ( dom0 == NULL ) panic("Error creating domain 0\n"); - set_bit(DF_PRIVILEGED, &dom0->flags); + set_bit(_DOMF_privileged, &dom0->domain_flags); - /* Grab the DOM0 command line. Skip past the image name. */ + /* Grab the DOM0 command line. */ cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); if ( cmdline != NULL ) { + static char dom0_cmdline[256]; + + /* Skip past the image name. */ while ( *cmdline == ' ' ) cmdline++; if ( (cmdline = strchr(cmdline, ' ')) != NULL ) while ( *cmdline == ' ' ) cmdline++; + + /* Copy the command line to a local buffer. */ + strcpy(dom0_cmdline, cmdline); + cmdline = dom0_cmdline; + + /* Append any extra parameters. */ + if ( skip_ioapic_setup && !strstr(cmdline, "noapic") ) + strcat(cmdline, " noapic"); + if ( acpi_skip_timer_override && + !strstr(cmdline, "acpi_skip_timer_override") ) + strcat(cmdline, " acpi_skip_timer_override"); + if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") ) + { + strcat(cmdline, " acpi="); + strcat(cmdline, acpi_param); + } } /* diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 3aa12ee5ea..b94e763f51 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -117,7 +117,7 @@ shadow_promote(struct domain *d, unsigned long gpfn, unsigned long gmfn, { printk("shadow_promote: get_page_type failed " "dom%d gpfn=%lx gmfn=%lx t=%08lx\n", - d->id, gpfn, gmfn, new_type); + d->domain_id, gpfn, gmfn, new_type); okay = 0; } @@ -233,7 +233,7 @@ alloc_shadow_page(struct domain *d, if ( unlikely(page == NULL) ) { printk("Couldn't alloc shadow page! dom%d count=%d\n", - d->id, d->arch.shadow_page_count); + d->domain_id, d->arch.shadow_page_count); printk("Shadow table counts: l1=%d l2=%d hl2=%d snapshot=%d\n", perfc_value(shadow_l1_pages), perfc_value(shadow_l2_pages), @@ -1179,7 +1179,8 @@ void __shadow_mode_disable(struct domain *d) * Currently this does not fix up page ref counts, so it is valid to call * only when a domain is being destroyed. */ - BUG_ON(!test_bit(DF_DYING, &d->flags) && shadow_mode_refcounts(d)); + BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags) && + shadow_mode_refcounts(d)); d->arch.shadow_tainted_refcnts = shadow_mode_refcounts(d); free_shadow_pages(d); @@ -1217,7 +1218,7 @@ static int shadow_mode_table_op( int i, rc = 0; struct exec_domain *ed; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); SH_VLOG("shadow mode table op %lx %lx count %d", pagetable_val(d->exec_domain[0]->arch.guest_table), /* XXX SMP */ @@ -1409,7 +1410,7 @@ gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn) if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) { printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l2e=%lx\n", - d->id, gpfn, l2e_get_value(l2e)); + d->domain_id, gpfn, l2e_get_value(l2e)); return INVALID_MFN; } unsigned long l1tab = l2e_get_phys(l2e); @@ -1419,13 +1420,13 @@ gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn) #if 0 printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => %lx phystab=%lx l2e=%lx l1tab=%lx, l1e=%lx\n", - d->id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, phystab, l2e, l1tab, l1e); + d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, phystab, l2e, l1tab, l1e); #endif if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) { printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l1e=%lx\n", - d->id, gpfn, l1e_get_value(l1e)); + d->domain_id, gpfn, l1e_get_value(l1e)); return INVALID_MFN; } @@ -1754,7 +1755,7 @@ shadow_make_snapshot( { printk("Couldn't alloc fullshadow snapshot for pfn=%lx mfn=%lx!\n" "Dom%d snapshot_count_count=%d\n", - gpfn, gmfn, d->id, d->arch.snapshot_page_count); + gpfn, gmfn, d->domain_id, d->arch.snapshot_page_count); BUG(); /* XXX FIXME: try a shadow flush to free up some memory. */ } @@ -1813,7 +1814,7 @@ shadow_mark_mfn_out_of_sync(struct exec_domain *ed, unsigned long gpfn, struct pfn_info *page = &frame_table[mfn]; struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d); - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(pfn_valid(mfn)); #ifndef NDEBUG @@ -1943,7 +1944,7 @@ int __shadow_out_of_sync(struct exec_domain *ed, unsigned long va) l2_pgentry_t l2e; unsigned long l1pfn, l1mfn; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(VALID_M2P(l2pfn)); perfc_incrc(shadow_out_of_sync_calls); @@ -2127,7 +2128,7 @@ int shadow_remove_all_write_access( u32 found = 0, fixups, write_refs; unsigned long prediction, predicted_gpfn, predicted_smfn; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(VALID_MFN(readonly_gmfn)); perfc_incrc(remove_write_access); @@ -2245,7 +2246,7 @@ u32 shadow_remove_all_access(struct domain *d, unsigned long forbidden_gmfn) if ( unlikely(!shadow_mode_enabled(d)) ) return 0; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); perfc_incrc(remove_all_access); for (i = 0; i < shadow_ht_buckets; i++) @@ -2287,7 +2288,7 @@ static int resync_all(struct domain *d, u32 stype) int unshadow; int changed; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); for ( entry = d->arch.out_of_sync; entry; entry = entry->next) { @@ -2485,7 +2486,7 @@ void __shadow_sync_all(struct domain *d) perfc_incrc(shadow_sync_all); - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); // First, remove all write permissions to the page tables // @@ -2645,7 +2646,7 @@ int shadow_fault(unsigned long va, struct cpu_user_regs *regs) { printk("%s() failed, crashing domain %d " "due to a read-only L2 page table (gpde=%lx), va=%lx\n", - __func__, d->id, l2e_get_value(gpde), va); + __func__, d->domain_id, l2e_get_value(gpde), va); domain_crash_synchronous(); } @@ -3146,7 +3147,7 @@ int check_l2_table( FAILPT("bogus owner for snapshot page"); if ( page_get_owner(pfn_to_page(smfn)) != NULL ) FAILPT("shadow page mfn=0x%lx is owned by someone, domid=%d", - smfn, page_get_owner(pfn_to_page(smfn))->id); + smfn, page_get_owner(pfn_to_page(smfn))->domain_id); #if 0 if ( memcmp(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], @@ -3307,7 +3308,7 @@ int _check_all_pagetables(struct exec_domain *ed, char *s) shadow_status_noswap = 1; sh_check_name = s; - SH_VVLOG("%s-PT Audit domid=%d", s, d->id); + SH_VVLOG("%s-PT Audit domid=%d", s, d->domain_id); sh_l2_present = sh_l1_present = 0; perfc_incrc(check_all_pagetables); diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 7a3abe9913..f3d34e0737 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -51,8 +51,11 @@ #include #include -/* Cconfigured maximum number of CPUs to activate. We name the parameter -"maxcpus" rather than max_cpus to be compatible with Linux */ +/* opt_nosmp: If true, secondary processors are ignored. */ +static int opt_nosmp = 0; +boolean_param("nosmp", opt_nosmp); + +/* maxcpus: maximum number of CPUs to activate. */ static int max_cpus = -1; integer_param("maxcpus", max_cpus); @@ -658,7 +661,7 @@ static void __init do_boot_cpu (int apicid) ed = idle->exec_domain[0]; - set_bit(DF_IDLETASK, &idle->flags); + set_bit(_DOMF_idle_domain, &idle->domain_flags); ed->arch.monitor_table = mk_pagetable(__pa(idle_pg_table)); @@ -797,8 +800,7 @@ void __init smp_boot_cpus(void) * If we couldnt find an SMP configuration at boot time, * get out of here now! */ - if (!smp_found_config) { - printk("SMP motherboard not detected.\n"); + if (!smp_found_config || opt_nosmp) { io_apic_irqs = 0; phys_cpu_present_map = physid_mask_of_physid(0); cpu_online_map = 1; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 52bd64ac9b..2838e28a35 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -152,7 +152,7 @@ static inline int do_trap(int trapnr, char *str, #ifndef NDEBUG if ( (ed->arch.guest_context.trap_ctxt[trapnr].address == 0) && - (ed->domain->id == 0) ) + (ed->domain->domain_id == 0) ) goto xen_fault; #endif @@ -326,7 +326,7 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs) #ifndef NDEBUG if ( (ed->arch.guest_context.trap_ctxt[TRAP_page_fault].address == 0) && - (d->id == 0) ) + (d->domain_id == 0) ) goto xen_fault; #endif @@ -361,13 +361,13 @@ long do_fpu_taskswitch(int set) if ( set ) { - set_bit(EDF_GUEST_STTS, &ed->flags); + set_bit(_VCPUF_guest_stts, &ed->vcpu_flags); stts(); } else { - clear_bit(EDF_GUEST_STTS, &ed->flags); - if ( test_bit(EDF_USEDFPU, &ed->flags) ) + clear_bit(_VCPUF_guest_stts, &ed->vcpu_flags); + if ( test_bit(_VCPUF_fpu_dirtied, &ed->vcpu_flags) ) clts(); } @@ -433,10 +433,19 @@ static inline int admin_io_okay( #define outl_user(_v, _p, _d, _r) \ (admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0)) +/* Propagate a fault back to the guest kernel. */ +#define USER_READ_FAULT 4 /* user mode, read fault */ +#define USER_WRITE_FAULT 6 /* user mode, write fault */ +#define PAGE_FAULT(_faultaddr, _errcode) \ +({ propagate_page_fault(_faultaddr, _errcode); \ + return EXCRET_fault_fixed; \ +}) + +/* Isntruction fetch with error handling. */ #define insn_fetch(_type, _size, _ptr) \ ({ unsigned long _x; \ if ( get_user(_x, (_type *)eip) ) \ - goto read_fault; \ + PAGE_FAULT(eip, USER_READ_FAULT); \ eip += _size; (_type)_x; }) static int emulate_privileged_op(struct cpu_user_regs *regs) @@ -502,17 +511,17 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 1: data = (u8)inb_user((u16)regs->edx, ed, regs); if ( put_user((u8)data, (u8 *)regs->edi) ) - goto write_fault; + PAGE_FAULT(regs->edi, USER_WRITE_FAULT); break; case 2: data = (u16)inw_user((u16)regs->edx, ed, regs); if ( put_user((u16)data, (u16 *)regs->edi) ) - goto write_fault; + PAGE_FAULT(regs->edi, USER_WRITE_FAULT); break; case 4: data = (u32)inl_user((u16)regs->edx, ed, regs); if ( put_user((u32)data, (u32 *)regs->edi) ) - goto write_fault; + PAGE_FAULT(regs->edi, USER_WRITE_FAULT); break; } regs->edi += (regs->eflags & EF_DF) ? -op_bytes : op_bytes; @@ -527,17 +536,17 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) { case 1: if ( get_user(data, (u8 *)regs->esi) ) - goto read_fault; + PAGE_FAULT(regs->esi, USER_READ_FAULT); outb_user((u8)data, (u16)regs->edx, ed, regs); break; case 2: if ( get_user(data, (u16 *)regs->esi) ) - goto read_fault; + PAGE_FAULT(regs->esi, USER_READ_FAULT); outw_user((u16)data, (u16)regs->edx, ed, regs); break; case 4: if ( get_user(data, (u32 *)regs->esi) ) - goto read_fault; + PAGE_FAULT(regs->esi, USER_READ_FAULT); outl_user((u32)data, (u16)regs->edx, ed, regs); break; } @@ -665,7 +674,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0: /* Read CR0 */ *reg = (read_cr0() & ~X86_CR0_TS) | - (test_bit(EDF_GUEST_STTS, &ed->flags) ? X86_CR0_TS : 0); + (test_bit(_VCPUF_guest_stts, &ed->vcpu_flags) ? X86_CR0_TS:0); break; case 2: /* Read CR2 */ @@ -736,14 +745,6 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) fail: return 0; - - read_fault: - propagate_page_fault(eip, 4); /* user mode, read fault */ - return EXCRET_fault_fixed; - - write_fault: - propagate_page_fault(eip, 6); /* user mode, write fault */ - return EXCRET_fault_fixed; } asmlinkage int do_general_protection(struct cpu_user_regs *regs) @@ -807,7 +808,7 @@ asmlinkage int do_general_protection(struct cpu_user_regs *regs) #ifndef NDEBUG if ( (ed->arch.guest_context.trap_ctxt[TRAP_gp_fault].address == 0) && - (ed->domain->id == 0) ) + (ed->domain->domain_id == 0) ) goto gp_in_kernel; #endif @@ -919,15 +920,9 @@ asmlinkage int math_state_restore(struct cpu_user_regs *regs) /* Prevent recursion. */ clts(); - if ( !test_and_set_bit(EDF_USEDFPU, ¤t->flags) ) - { - if ( test_bit(EDF_DONEFPUINIT, ¤t->flags) ) - restore_fpu(current); - else - init_fpu(); - } + setup_fpu(current); - if ( test_and_clear_bit(EDF_GUEST_STTS, ¤t->flags) ) + if ( test_and_clear_bit(_VCPUF_guest_stts, ¤t->vcpu_flags) ) { struct trap_bounce *tb = ¤t->arch.trap_bounce; tb->flags = TBF_EXCEPTION; diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 7fa433c0c1..52c976f51f 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -154,6 +154,21 @@ static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs) return result; } +static void vmx_do_no_device_fault() +{ + unsigned long cr0; + + clts(); + setup_fpu(current); + __vmread(CR0_READ_SHADOW, &cr0); + if (!(cr0 & X86_CR0_TS)) { + __vmread(GUEST_CR0, &cr0); + cr0 &= ~X86_CR0_TS; + __vmwrite(GUEST_CR0, cr0); + } + __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP); +} + static void vmx_do_general_protection_fault(struct cpu_user_regs *regs) { unsigned long eip, error_code; @@ -894,6 +909,9 @@ static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs mov_from_cr(cr, gp, regs); break; case TYPE_CLTS: + clts(); + setup_fpu(current); + __vmread(GUEST_CR0, &value); value &= ~X86_CR0_TS; /* clear TS */ __vmwrite(GUEST_CR0, value); @@ -966,7 +984,7 @@ static void vmx_print_line(const char c, struct exec_domain *d) print_buf[index++] = c; } print_buf[index] = '\0'; - printk("(GUEST: %u) %s\n", d->domain->id, (char *) &print_buf); + printk("(GUEST: %u) %s\n", d->domain->domain_id, (char *) &print_buf); index = 0; } else @@ -1054,7 +1072,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) } __vmread(GUEST_EIP, &eip); - TRACE_3D(TRC_VMX_VMEXIT, ed->domain->id, eip, exit_reason); + TRACE_3D(TRC_VMX_VMEXIT, ed->domain->domain_id, eip, exit_reason); switch (exit_reason) { case EXIT_REASON_EXCEPTION_NMI: @@ -1075,7 +1093,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) perfc_incra(cause_vector, vector); - TRACE_3D(TRC_VMX_VECTOR, ed->domain->id, eip, vector); + TRACE_3D(TRC_VMX_VECTOR, ed->domain->domain_id, eip, vector); switch (vector) { #ifdef XEN_DEBUGGER case TRAP_debug: @@ -1093,6 +1111,11 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) break; } #endif + case TRAP_no_device: + { + vmx_do_no_device_fault(); + break; + } case TRAP_gp_fault: { vmx_do_general_protection_fault(®s); @@ -1122,7 +1145,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, regs.error_code); ed->arch.arch_vmx.cpu_cr2 = va; - TRACE_3D(TRC_VMX_INT, ed->domain->id, TRAP_page_fault, va); + TRACE_3D(TRC_VMX_INT, ed->domain->domain_id, TRAP_page_fault, va); } break; } diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 05780a2157..49742286c5 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -429,6 +429,7 @@ void vmx_intr_assist(struct exec_domain *d) void vmx_do_resume(struct exec_domain *d) { + vmx_stts(); if ( test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state) ) __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table)); else diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index 90cc88122c..9566e60d9d 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -164,6 +164,9 @@ void vmx_do_launch(struct exec_domain *ed) struct pfn_info *page; struct cpu_user_regs *regs = get_cpu_user_regs(); + vmx_stts(); + set_bit(_VCPUF_guest_stts, &ed->vcpu_flags); + cpu = smp_processor_id(); page = (struct pfn_info *) alloc_domheap_page(NULL); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 23fc589d4d..add8f51d43 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -139,7 +139,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { ret = -EINVAL; if ( (d != current->domain) && - test_bit(DF_CONSTRUCTED, &d->flags) ) + test_bit(_DOMF_constructed, &d->domain_flags) ) { domain_unpause_by_systemcontroller(d); ret = 0; @@ -194,7 +194,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = 0; - op->u.createdomain.domain = d->id; + op->u.createdomain.domain = d->domain_id; copy_to_user(u_dom0_op, op, sizeof(*op)); } break; @@ -221,7 +221,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op) domid_t dom = op->u.pincpudomain.domain; struct domain *d = find_domain_by_id(dom); struct exec_domain *ed; - int cpu = op->u.pincpudomain.cpu; + cpumap_t cpumap; + if ( d == NULL ) { @@ -229,6 +230,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) break; } + if ( (op->u.pincpudomain.exec_domain >= MAX_VIRT_CPUS) || + !d->exec_domain[op->u.pincpudomain.exec_domain] ) + { + ret = -EINVAL; + put_domain(d); + break; + } + ed = d->exec_domain[op->u.pincpudomain.exec_domain]; if ( ed == NULL ) { @@ -244,17 +253,29 @@ long do_dom0_op(dom0_op_t *u_dom0_op) break; } - if ( cpu == -1 ) + if ( copy_from_user(&cpumap, op->u.pincpudomain.cpumap, + sizeof(cpumap)) ) { - clear_bit(EDF_CPUPINNED, &ed->flags); + ret = -EFAULT; + put_domain(d); + break; } + + /* update cpumap for this ed */ + ed->cpumap = cpumap; + + if ( cpumap == CPUMAP_RUNANYWHERE ) + clear_bit(_VCPUF_cpu_pinned, &ed->vcpu_flags); else { + /* pick a new cpu from the usable map */ + int new_cpu = (int)find_first_set_bit(cpumap) % smp_num_cpus; + exec_domain_pause(ed); - if ( ed->processor != (cpu % smp_num_cpus) ) - set_bit(EDF_MIGRATED, &ed->flags); - set_bit(EDF_CPUPINNED, &ed->flags); - ed->processor = cpu % smp_num_cpus; + if ( ed->processor != new_cpu ) + set_bit(_VCPUF_cpu_migrated, &ed->vcpu_flags); + set_bit(_VCPUF_cpu_pinned, &ed->vcpu_flags); + ed->processor = new_cpu; exec_domain_unpause(ed); } @@ -278,15 +299,17 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_GETDOMAININFO: { - struct vcpu_guest_context *c; - struct domain *d; - struct exec_domain *ed; + struct domain *d; + struct exec_domain *ed; + u64 cpu_time = 0; + int vcpu_count = 0; + int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED; read_lock(&domlist_lock); for_each_domain ( d ) { - if ( d->id >= op->u.getdomaininfo.domain ) + if ( d->domain_id >= op->u.getdomaininfo.domain ) break; } @@ -299,36 +322,84 @@ long do_dom0_op(dom0_op_t *u_dom0_op) read_unlock(&domlist_lock); - op->u.getdomaininfo.domain = d->id; + op->u.getdomaininfo.domain = d->domain_id; - if ( (op->u.getdomaininfo.exec_domain >= MAX_VIRT_CPUS) || - !d->exec_domain[op->u.getdomaininfo.exec_domain] ) - { - ret = -EINVAL; - break; + memset(&op->u.getdomaininfo.vcpu_to_cpu, -1, + sizeof(op->u.getdomaininfo.vcpu_to_cpu)); + memset(&op->u.getdomaininfo.cpumap, 0, + sizeof(op->u.getdomaininfo.cpumap)); + + /* + * - domain is marked as paused or blocked only if all its vcpus + * are paused or blocked + * - domain is marked as running if any of its vcpus is running + */ + for_each_exec_domain ( d, ed ) { + op->u.getdomaininfo.vcpu_to_cpu[ed->vcpu_id] = ed->processor; + op->u.getdomaininfo.cpumap[ed->vcpu_id] = ed->cpumap; + if ( !(ed->vcpu_flags & VCPUF_ctrl_pause) ) + flags &= ~DOMFLAGS_PAUSED; + if ( !(ed->vcpu_flags & VCPUF_blocked) ) + flags &= ~DOMFLAGS_BLOCKED; + if ( ed->vcpu_flags & VCPUF_running ) + flags |= DOMFLAGS_RUNNING; + if ( ed->cpu_time > cpu_time ) + cpu_time += ed->cpu_time; + vcpu_count++; } - - ed = d->exec_domain[op->u.getdomaininfo.exec_domain]; - op->u.getdomaininfo.flags = - (test_bit( DF_DYING, &d->flags) ? DOMFLAGS_DYING : 0) | - (test_bit( DF_CRASHED, &d->flags) ? DOMFLAGS_CRASHED : 0) | - (test_bit( DF_SHUTDOWN, &d->flags) ? DOMFLAGS_SHUTDOWN : 0) | - (test_bit(EDF_CTRLPAUSE, &ed->flags) ? DOMFLAGS_PAUSED : 0) | - (test_bit(EDF_BLOCKED, &ed->flags) ? DOMFLAGS_BLOCKED : 0) | - (test_bit(EDF_RUNNING, &ed->flags) ? DOMFLAGS_RUNNING : 0); + op->u.getdomaininfo.cpu_time = cpu_time; + op->u.getdomaininfo.n_vcpu = vcpu_count; - op->u.getdomaininfo.flags |= ed->processor << DOMFLAGS_CPUSHIFT; - op->u.getdomaininfo.flags |= + op->u.getdomaininfo.flags = flags | + ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | + ((d->domain_flags & DOMF_crashed) ? DOMFLAGS_CRASHED : 0) | + ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; op->u.getdomaininfo.tot_pages = d->tot_pages; op->u.getdomaininfo.max_pages = d->max_pages; - op->u.getdomaininfo.cpu_time = ed->cpu_time; op->u.getdomaininfo.shared_info_frame = __pa(d->shared_info) >> PAGE_SHIFT; - if ( op->u.getdomaininfo.ctxt != NULL ) + if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) + ret = -EINVAL; + + put_domain(d); + } + break; + + case DOM0_GETVCPUCONTEXT: + { + struct vcpu_guest_context *c; + struct domain *d; + struct exec_domain *ed; + + d = find_domain_by_id(op->u.getvcpucontext.domain); + if ( d == NULL ) + { + ret = -ESRCH; + break; + } + + if ( op->u.getvcpucontext.exec_domain >= MAX_VIRT_CPUS ) + { + ret = -EINVAL; + put_domain(d); + break; + } + + ed = d->exec_domain[op->u.getvcpucontext.exec_domain]; + if ( ed == NULL ) + { + ret = -ESRCH; + put_domain(d); + break; + } + + op->u.getvcpucontext.cpu_time = ed->cpu_time; + + if ( op->u.getvcpucontext.ctxt != NULL ) { if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) { @@ -345,7 +416,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) if ( ed != current ) exec_domain_unpause(ed); - if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) + if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) ) ret = -EINVAL; xfree(c); diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index 698f6ee835..40aa522eb0 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -29,7 +29,7 @@ __HYPERVISOR_dom_mem_op, \ (_op) | (i << START_EXTENT_SHIFT), \ extent_list, nr_extents, extent_order, \ - (d == current->domain) ? DOMID_SELF : d->id); + (d == current->domain) ? DOMID_SELF : d->domain_id); static long alloc_dom_mem(struct domain *d, @@ -95,14 +95,14 @@ free_dom_mem(struct domain *d, if ( unlikely((mpfn + j) >= max_page) ) { DPRINTK("Domain %u page number out of range (%lx >= %lx)\n", - d->id, mpfn + j, max_page); + d->domain_id, mpfn + j, max_page); return i; } page = &frame_table[mpfn + j]; if ( unlikely(!get_page(page, d)) ) { - DPRINTK("Bad page free for domain %u\n", d->id); + DPRINTK("Bad page free for domain %u\n", d->domain_id); return i; } diff --git a/xen/common/domain.c b/xen/common/domain.c index 7ab17768c6..3729489492 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -39,7 +39,7 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) atomic_set(&d->refcnt, 1); atomic_set(&ed->pausecnt, 0); - d->id = dom_id; + d->domain_id = dom_id; ed->processor = cpu; spin_lock_init(&d->time_lock); @@ -50,7 +50,7 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) INIT_LIST_HEAD(&d->page_list); INIT_LIST_HEAD(&d->xenpage_list); - if ( (d->id != IDLE_DOMAIN_ID) && + if ( (d->domain_id != IDLE_DOMAIN_ID) && ((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) ) { destroy_event_channels(d); @@ -62,12 +62,12 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) sched_add_domain(ed); - if ( d->id != IDLE_DOMAIN_ID ) + if ( d->domain_id != IDLE_DOMAIN_ID ) { write_lock(&domlist_lock); pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) - if ( (*pd)->id > d->id ) + if ( (*pd)->domain_id > d->domain_id ) break; d->next_in_list = *pd; *pd = d; @@ -88,7 +88,7 @@ struct domain *find_domain_by_id(domid_t dom) d = domain_hash[DOMAIN_HASH(dom)]; while ( d != NULL ) { - if ( d->id == dom ) + if ( d->domain_id == dom ) { if ( unlikely(!get_domain(d)) ) d = NULL; @@ -107,7 +107,7 @@ void domain_kill(struct domain *d) struct exec_domain *ed; domain_pause(d); - if ( !test_and_set_bit(DF_DYING, &d->flags) ) + if ( !test_and_set_bit(_DOMF_dying, &d->domain_flags) ) { for_each_exec_domain(d, ed) sched_rem_domain(ed); @@ -121,10 +121,10 @@ void domain_crash(void) { struct domain *d = current->domain; - if ( d->id == 0 ) + if ( d->domain_id == 0 ) BUG(); - set_bit(DF_CRASHED, &d->flags); + set_bit(_DOMF_crashed, &d->domain_flags); send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); @@ -144,7 +144,7 @@ void domain_shutdown(u8 reason) { struct domain *d = current->domain; - if ( d->id == 0 ) + if ( d->domain_id == 0 ) { extern void machine_restart(char *); extern void machine_halt(void); @@ -164,9 +164,9 @@ void domain_shutdown(u8 reason) } if ( (d->shutdown_code = reason) == SHUTDOWN_crash ) - set_bit(DF_CRASHED, &d->flags); + set_bit(_DOMF_crashed, &d->domain_flags); else - set_bit(DF_SHUTDOWN, &d->flags); + set_bit(_DOMF_shutdown, &d->domain_flags); send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); @@ -180,7 +180,7 @@ void domain_destruct(struct domain *d) struct domain **pd; atomic_t old, new; - if ( !test_bit(DF_DYING, &d->flags) ) + if ( !test_bit(_DOMF_dying, &d->domain_flags) ) BUG(); /* May be already destructed, or get_domain() can race us. */ @@ -196,7 +196,7 @@ void domain_destruct(struct domain *d) while ( *pd != d ) pd = &(*pd)->next_in_list; *pd = d->next_in_list; - pd = &domain_hash[DOMAIN_HASH(d->id)]; + pd = &domain_hash[DOMAIN_HASH(d->domain_id)]; while ( *pd != d ) pd = &(*pd)->next_in_hashbucket; *pd = d->next_in_hashbucket; @@ -217,18 +217,18 @@ void domain_destruct(struct domain *d) * of domains other than domain 0. ie. the domains that are being built by * the userspace dom0 domain builder. */ -int set_info_guest(struct domain *p, dom0_setdomaininfo_t *setdomaininfo) +int set_info_guest(struct domain *d, dom0_setdomaininfo_t *setdomaininfo) { int rc = 0; struct vcpu_guest_context *c = NULL; unsigned long vcpu = setdomaininfo->exec_domain; struct exec_domain *ed; - if ( (vcpu >= MAX_VIRT_CPUS) || ((ed = p->exec_domain[vcpu]) == NULL) ) + if ( (vcpu >= MAX_VIRT_CPUS) || ((ed = d->exec_domain[vcpu]) == NULL) ) return -EINVAL; - if (test_bit(DF_CONSTRUCTED, &p->flags) && - !test_bit(EDF_CTRLPAUSE, &ed->flags)) + if (test_bit(_DOMF_constructed, &d->domain_flags) && + !test_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags)) return -EINVAL; if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) @@ -243,7 +243,7 @@ int set_info_guest(struct domain *p, dom0_setdomaininfo_t *setdomaininfo) if ( (rc = arch_set_info_guest(ed, c)) != 0 ) goto out; - set_bit(DF_CONSTRUCTED, &p->flags); + set_bit(_DOMF_constructed, &d->domain_flags); out: xfree(c); @@ -283,6 +283,7 @@ long do_boot_vcpu(unsigned long vcpu, struct vcpu_guest_context *ctxt) ed = d->exec_domain[vcpu]; atomic_set(&ed->pausecnt, 0); + ed->cpumap = CPUMAP_RUNANYWHERE; memcpy(&ed->arch, &idle0_exec_domain.arch, sizeof(ed->arch)); @@ -294,7 +295,7 @@ long do_boot_vcpu(unsigned long vcpu, struct vcpu_guest_context *ctxt) sched_add_domain(ed); /* domain_unpause_by_systemcontroller */ - if ( test_and_clear_bit(EDF_CTRLPAUSE, &ed->flags) ) + if ( test_and_clear_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags) ) domain_wake(ed); xfree(c); diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 22b01ad541..32e519bd1e 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -40,7 +40,7 @@ static int get_free_port(struct exec_domain *ed) max = d->max_event_channel; chn = d->event_channel; - for ( port = ed->id * EVENT_CHANNELS_SPREAD; port < max; port++ ) + for ( port = ed->vcpu_id * EVENT_CHANNELS_SPREAD; port < max; port++ ) if ( chn[port].state == ECS_FREE ) break; @@ -114,9 +114,9 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) return -EINVAL; if ( dom1 == DOMID_SELF ) - dom1 = current->domain->id; + dom1 = current->domain->domain_id; if ( dom2 == DOMID_SELF ) - dom2 = current->domain->id; + dom2 = current->domain->domain_id; if ( ((d1 = find_domain_by_id(dom1)) == NULL) || ((d2 = find_domain_by_id(dom2)) == NULL) ) @@ -429,7 +429,7 @@ static long __evtchn_close(struct domain *d1, int port1) BUG(); chn2[port2].state = ECS_UNBOUND; - chn2[port2].u.unbound.remote_domid = d1->id; + chn2[port2].u.unbound.remote_domid = d1->domain_id; break; default: @@ -459,7 +459,7 @@ static long evtchn_close(evtchn_close_t *close) domid_t dom = close->dom; if ( dom == DOMID_SELF ) - dom = current->domain->id; + dom = current->domain->domain_id; else if ( !IS_PRIV(current->domain) ) return -EPERM; @@ -522,7 +522,7 @@ static long evtchn_status(evtchn_status_t *status) long rc = 0; if ( dom == DOMID_SELF ) - dom = current->domain->id; + dom = current->domain->domain_id; else if ( !IS_PRIV(current->domain) ) return -EPERM; @@ -552,7 +552,7 @@ static long evtchn_status(evtchn_status_t *status) case ECS_INTERDOMAIN: status->status = EVTCHNSTAT_interdomain; status->u.interdomain.dom = - chn[port].u.interdomain.remote_dom->domain->id; + chn[port].u.interdomain.remote_dom->domain->domain_id; status->u.interdomain.port = chn[port].u.interdomain.remote_port; break; case ECS_PIRQ: diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 7fdc92c9b9..591ec609f3 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -118,10 +118,10 @@ __gnttab_activate_grant_ref( u32 scombo, prev_scombo, new_scombo; if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) || - unlikely(sdom != mapping_d->id) ) + unlikely(sdom != mapping_d->domain_id) ) PIN_FAIL(unlock_out, GNTST_general_error, "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, mapping_d->id); + sflags, sdom, mapping_d->domain_id); /* Merge two 16-bit values into a 32-bit combined update. */ /* NB. Endianness! */ @@ -674,7 +674,7 @@ gnttab_setup_table( if ( op.dom == DOMID_SELF ) { - op.dom = current->domain->id; + op.dom = current->domain->domain_id; } else if ( unlikely(!IS_PRIV(current->domain)) ) { @@ -725,7 +725,7 @@ gnttab_dump_table(gnttab_dump_table_t *uop) if ( op.dom == DOMID_SELF ) { - op.dom = current->domain->id; + op.dom = current->domain->domain_id; } if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) ) @@ -866,10 +866,10 @@ gnttab_check_unmap( lgt = ld->grant_table; #if GRANT_DEBUG_VERBOSE - if ( ld->id != 0 ) + if ( ld->domain_id != 0 ) { DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n", - rd->id, ld->id, frame, readonly); + rd->domain_id, ld->domain_id, frame, readonly); } #endif @@ -879,7 +879,8 @@ gnttab_check_unmap( if ( get_domain(rd) == 0 ) { - DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->id); + DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", + rd->domain_id); return 0; } @@ -913,7 +914,7 @@ gnttab_check_unmap( /* gotcha */ DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", - rd->id, ld->id, frame, readonly); + rd->domain_id, ld->domain_id, frame, readonly); if ( readonly ) act->pin -= GNTPIN_hstr_inc; @@ -963,12 +964,13 @@ gnttab_prepare_for_transfer( unsigned long target_pfn; DPRINTK("gnttab_prepare_for_transfer rd(%hu) ld(%hu) ref(%hu).\n", - rd->id, ld->id, ref); + rd->domain_id, ld->domain_id, ref); if ( unlikely((rgt = rd->grant_table) == NULL) || unlikely(ref >= NR_GRANT_ENTRIES) ) { - DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n", rd->id, ref); + DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n", + rd->domain_id, ref); return 0; } @@ -990,10 +992,10 @@ gnttab_prepare_for_transfer( } if ( unlikely(sflags != GTF_accept_transfer) || - unlikely(sdom != ld->id) ) + unlikely(sdom != ld->domain_id) ) { DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n", - sflags, sdom, ld->id); + sflags, sdom, ld->domain_id); goto fail; } @@ -1041,7 +1043,7 @@ gnttab_notify_transfer( unsigned long pfn; DPRINTK("gnttab_notify_transfer rd(%hu) ld(%hu) ref(%hu).\n", - rd->id, ld->id, ref); + rd->domain_id, ld->domain_id, ref); sha = &rd->grant_table->shared[ref]; @@ -1062,7 +1064,7 @@ gnttab_notify_transfer( __phys_to_machine_mapping[pfn] = frame; } sha->frame = __mfn_to_gpfn(rd, frame); - sha->domid = rd->id; + sha->domid = rd->domain_id; wmb(); sha->flags = ( GTF_accept_transfer | GTF_transfer_completed ); diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 33122e9333..46d63901da 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -55,27 +55,13 @@ void cmdline_parse(char *cmdline) *(unsigned int *)param->var = simple_strtol(opt, (char **)&opt, 0); break; - case OPT_UINT_UNIT: - if ( opt != NULL ) - { - int base = 1; - unsigned int value; - - value = simple_strtoul(opt, (char **)&opt, 0); - if (*opt == 'G' || *opt == 'g') { - base = 1024 * 1024; - opt++; - } if (*opt == 'M' || *opt == 'm') { - base = 1024; - opt++; - } else if (*opt == 'K' || *opt == 'k') - opt++; - *(unsigned int *) param->var = value * base; - } - break; case OPT_BOOL: *(int *)param->var = 1; break; + case OPT_CUSTOM: + if ( opt != NULL ) + ((void (*)(char *))param->var)(opt); + break; } } cmdline = opt_end; diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 3449143458..34f9fd9291 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -109,7 +109,7 @@ static void do_task_queues(unsigned char key) for_each_domain ( d ) { printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d " - "xenheap_pages=%d\n", d->id, d->flags, + "xenheap_pages=%d\n", d->domain_id, d->domain_flags, atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages); dump_pageframe_info(d); @@ -118,11 +118,11 @@ static void do_task_queues(unsigned char key) printk("Guest: %p CPU %d [has=%c] flags=%lx " "upcall_pend = %02x, upcall_mask = %02x\n", ed, ed->processor, - test_bit(EDF_RUNNING, &ed->flags) ? 'T':'F', - ed->flags, + test_bit(_VCPUF_running, &ed->vcpu_flags) ? 'T':'F', + ed->vcpu_flags, ed->vcpu_info->evtchn_upcall_pending, ed->vcpu_info->evtchn_upcall_mask); - printk("Notifying guest... %d/%d\n", d->id, ed->id); + printk("Notifying guest... %d/%d\n", d->domain_id, ed->vcpu_id); printk("port %d/%d stat %d %d %d\n", VIRQ_DEBUG, ed->virq_to_evtchn[VIRQ_DEBUG], test_bit(ed->virq_to_evtchn[VIRQ_DEBUG], diff --git a/xen/common/lib.c b/xen/common/lib.c index 2e94339025..6c0706f1f1 100644 --- a/xen/common/lib.c +++ b/xen/common/lib.c @@ -441,6 +441,22 @@ s64 __moddi3(s64 a, s64 b) #endif /* BITS_PER_LONG == 32 */ +unsigned long long memparse(char *s) +{ + unsigned long long ret = simple_strtoull(s, &s, 0); + + switch (*s) { + case 'G': case 'g': + ret <<= 10; + case 'M': case 'm': + ret <<= 10; + case 'K': case 'k': + ret <<= 10; + } + + return ret; +} + /* * Local variables: * mode: C diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 5a4115c82e..8669ac8a27 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -504,13 +504,13 @@ struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order) spin_lock(&d->page_alloc_lock); - if ( unlikely(test_bit(DF_DYING, &d->flags)) || + if ( unlikely(test_bit(_DOMF_dying, &d->domain_flags)) || unlikely((d->tot_pages + (1 << order)) > d->max_pages) ) { DPRINTK("Over-allocation for domain %u: %u > %u\n", - d->id, d->tot_pages + (1 << order), d->max_pages); + d->domain_id, d->tot_pages + (1 << order), d->max_pages); DPRINTK("...or the domain is dying (%d)\n", - !!test_bit(DF_DYING, &d->flags)); + !!test_bit(_DOMF_dying, &d->domain_flags)); spin_unlock(&d->page_alloc_lock); free_heap_pages(MEMZONE_DOM, pg, order); return NULL; @@ -575,7 +575,7 @@ void free_domheap_pages(struct pfn_info *pg, unsigned int order) spin_unlock_recursive(&d->page_alloc_lock); - if ( likely(!test_bit(DF_DYING, &d->flags)) ) + if ( likely(!test_bit(_DOMF_dying, &d->domain_flags)) ) { free_heap_pages(MEMZONE_DOM, pg, order); } diff --git a/xen/common/sched_bvt.c b/xen/common/sched_bvt.c index 276479e490..1ad20578f4 100644 --- a/xen/common/sched_bvt.c +++ b/xen/common/sched_bvt.c @@ -174,9 +174,9 @@ static int bvt_alloc_task(struct exec_domain *ed) return -1; memset(d->sched_priv, 0, sizeof(struct bvt_dom_info)); } - ed->sched_priv = &BVT_INFO(d)->ed_inf[ed->id]; - BVT_INFO(d)->ed_inf[ed->id].inf = BVT_INFO(d); - BVT_INFO(d)->ed_inf[ed->id].exec_domain = ed; + ed->sched_priv = &BVT_INFO(d)->ed_inf[ed->vcpu_id]; + BVT_INFO(d)->ed_inf[ed->vcpu_id].inf = BVT_INFO(d); + BVT_INFO(d)->ed_inf[ed->vcpu_id].exec_domain = ed; return 0; } @@ -190,7 +190,8 @@ static void bvt_add_task(struct exec_domain *d) ASSERT(inf != NULL); ASSERT(d != NULL); - if (d->id == 0) { + if ( d->vcpu_id == 0 ) + { inf->mcu_advance = MCU_ADVANCE; inf->domain = d->domain; inf->warpback = 0; @@ -212,7 +213,7 @@ static void bvt_add_task(struct exec_domain *d) einf->exec_domain = d; - if ( d->domain->id == IDLE_DOMAIN_ID ) + if ( d->domain->domain_id == IDLE_DOMAIN_ID ) { einf->avt = einf->evt = ~0U; } @@ -231,7 +232,7 @@ static int bvt_init_idle_task(struct exec_domain *ed) bvt_add_task(ed); - set_bit(EDF_RUNNING, &ed->flags); + set_bit(_VCPUF_running, &ed->vcpu_flags); if ( !__task_on_runqueue(ed) ) __add_to_runqueue_head(ed); @@ -256,7 +257,7 @@ static void bvt_wake(struct exec_domain *ed) /* Set the BVT parameters. AVT should always be updated if CPU migration ocurred.*/ if ( einf->avt < CPU_SVT(cpu) || - unlikely(test_bit(EDF_MIGRATED, &ed->flags)) ) + unlikely(test_bit(_VCPUF_cpu_migrated, &ed->vcpu_flags)) ) einf->avt = CPU_SVT(cpu); /* Deal with warping here. */ @@ -279,7 +280,7 @@ static void bvt_wake(struct exec_domain *ed) static void bvt_sleep(struct exec_domain *ed) { - if ( test_bit(EDF_RUNNING, &ed->flags) ) + if ( test_bit(_VCPUF_running, &ed->vcpu_flags) ) cpu_raise_softirq(ed->processor, SCHEDULE_SOFTIRQ); else if ( __task_on_runqueue(ed) ) __del_from_runqueue(ed); @@ -538,8 +539,8 @@ static void bvt_dump_cpu_state(int i) list_for_each_entry ( ed_inf, queue, run_list ) { ed = ed_inf->exec_domain; - printk("%3d: %u has=%c ", loop++, ed->domain->id, - test_bit(EDF_RUNNING, &ed->flags) ? 'T':'F'); + printk("%3d: %u has=%c ", loop++, ed->domain->domain_id, + test_bit(_VCPUF_running, &ed->vcpu_flags) ? 'T':'F'); bvt_dump_runq_el(ed); printk("c=0x%X%08X\n", (u32)(ed->cpu_time>>32), (u32)ed->cpu_time); printk(" l: %p n: %p p: %p\n", diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c index 6bd8b5a0be..d4ed67ed5b 100644 --- a/xen/common/sched_sedf.c +++ b/xen/common/sched_sedf.c @@ -162,8 +162,8 @@ static inline void extraq_del(struct exec_domain *d, int i) { struct list_head *list = EXTRALIST(d,i); ASSERT(extraq_on(d,i)); - PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->id, - d->id, i); + PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->domain_id, + d->vcpu_id, i); list_del(list); list->next = NULL; ASSERT(!extraq_on(d, i)); @@ -182,7 +182,7 @@ static inline void extraq_add_sort_update(struct exec_domain *d, int i, int sub) ASSERT(!extraq_on(d,i)); PRINT(3, "Adding domain %i.%i (score= %i, short_pen= %"PRIi64")" " to L%i extraq\n", - d->domain->id, d->id, EDOM_INFO(d)->score[i], + d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->score[i], EDOM_INFO(d)->short_block_lost_tot, i); /*iterate through all elements to find our "hole" and on our way update all the other scores*/ @@ -193,8 +193,8 @@ static inline void extraq_add_sort_update(struct exec_domain *d, int i, int sub) break; else PRINT(4,"\tbehind domain %i.%i (score= %i)\n", - curinf->exec_domain->domain->id, - curinf->exec_domain->id, curinf->score[i]); + curinf->exec_domain->domain->domain_id, + curinf->exec_domain->vcpu_id, curinf->score[i]); } /*cur now contains the element, before which we'll enqueue*/ PRINT(3, "\tlist_add to %p\n", cur->prev); @@ -208,23 +208,23 @@ static inline void extraq_add_sort_update(struct exec_domain *d, int i, int sub) extralist[i]); curinf->score[i] -= sub; PRINT(4, "\tupdating domain %i.%i (score= %u)\n", - curinf->exec_domain->domain->id, - curinf->exec_domain->id, curinf->score[i]); + curinf->exec_domain->domain->domain_id, + curinf->exec_domain->vcpu_id, curinf->score[i]); } ASSERT(extraq_on(d,i)); } static inline void extraq_check(struct exec_domain *d) { if (extraq_on(d, EXTRA_UTIL_Q)) { - PRINT(2,"Dom %i.%i is on L1 extraQ\n",d->domain->id, d->id); + PRINT(2,"Dom %i.%i is on L1 extraQ\n",d->domain->domain_id, d->vcpu_id); if (!(EDOM_INFO(d)->status & EXTRA_AWARE) && !extra_runs(EDOM_INFO(d))) { extraq_del(d, EXTRA_UTIL_Q); PRINT(2,"Removed dom %i.%i from L1 extraQ\n", - d->domain->id, d->id); + d->domain->domain_id, d->vcpu_id); } } else { - PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->id, - d->id); + PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->domain_id, + d->vcpu_id); if ((EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d)) { #if (EXTRA == EXTRA_ROUNDR) @@ -235,8 +235,8 @@ static inline void extraq_check(struct exec_domain *d) { #elif ; #endif - PRINT(2,"Added dom %i.%i to L1 extraQ\n",d->domain->id, - d->id); + PRINT(2,"Added dom %i.%i to L1 extraQ\n",d->domain->domain_id, + d->vcpu_id); } } } @@ -268,7 +268,7 @@ static inline void __del_from_queue(struct exec_domain *d) struct list_head *list = LIST(d); ASSERT(__task_on_queue(d)); PRINT(3,"Removing domain %i.%i (bop= %"PRIu64") from runq/waitq\n", - d->domain->id, d->id, PERIOD_BEGIN(EDOM_INFO(d))); + d->domain->domain_id, d->vcpu_id, PERIOD_BEGIN(EDOM_INFO(d))); list_del(list); list->next = NULL; ASSERT(!__task_on_queue(d)); @@ -309,7 +309,7 @@ DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2)) static inline void __add_to_waitqueue_sort(struct exec_domain *d) { ASSERT(!__task_on_queue(d)); PRINT(3,"Adding domain %i.%i (bop= %"PRIu64") to waitq\n", - d->domain->id, d->id, PERIOD_BEGIN(EDOM_INFO(d))); + d->domain->domain_id, d->vcpu_id, PERIOD_BEGIN(EDOM_INFO(d))); list_insert_sort(WAITQ(d->processor), LIST(d), waitq_comp); ASSERT(__task_on_queue(d)); } @@ -322,7 +322,7 @@ static inline void __add_to_waitqueue_sort(struct exec_domain *d) { DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs) static inline void __add_to_runqueue_sort(struct exec_domain *d) { PRINT(3,"Adding domain %i.%i (deadl= %"PRIu64") to runq\n", - d->domain->id, d->id, EDOM_INFO(d)->deadl_abs); + d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->deadl_abs); list_insert_sort(RUNQ(d->processor), LIST(d), runq_comp); } @@ -346,8 +346,8 @@ static int sedf_init_scheduler() { /* Allocates memory for per domain private scheduling data*/ static int sedf_alloc_task(struct exec_domain *d) { - PRINT(2,"sedf_alloc_task was called, domain-id %i.%i\n",d->domain->id, - d->id); + PRINT(2,"sedf_alloc_task was called, domain-id %i.%i\n",d->domain->domain_id, + d->vcpu_id); if (d->domain->sched_priv == NULL) { if ((d->domain->sched_priv = xmalloc(struct sedf_dom_info)) == NULL ) @@ -366,10 +366,10 @@ static void sedf_add_task(struct exec_domain *d) struct sedf_edom_info *inf = EDOM_INFO(d); inf->exec_domain = d; - PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",d->domain->id, - d->id); + PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",d->domain->domain_id, + d->vcpu_id); - if (d->domain->id==0) { + if (d->domain->domain_id==0) { /*set dom0 to something useful to boot the machine*/ inf->period = MILLISECS(20); inf->slice = MILLISECS(15); @@ -391,7 +391,7 @@ static void sedf_add_task(struct exec_domain *d) INIT_LIST_HEAD(&(inf->extralist[EXTRA_PEN_Q])); INIT_LIST_HEAD(&(inf->extralist[EXTRA_UTIL_Q])); - if (d->domain->id != IDLE_DOMAIN_ID) { + if (d->domain->domain_id != IDLE_DOMAIN_ID) { extraq_check(d); } } @@ -400,7 +400,7 @@ static void sedf_add_task(struct exec_domain *d) static void sedf_free_task(struct domain *d) { int i; - PRINT(2,"sedf_free_task was called, domain-id %i\n",d->id); + PRINT(2,"sedf_free_task was called, domain-id %i\n",d->domain_id); ASSERT(d->sched_priv != NULL); xfree(d->sched_priv); @@ -414,14 +414,14 @@ static void sedf_free_task(struct domain *d) /* Initialises idle task */ static int sedf_init_idle_task(struct exec_domain *d) { PRINT(2,"sedf_init_idle_task was called, domain-id %i.%i\n", - d->domain->id, d->id); + d->domain->domain_id, d->vcpu_id); if ( sedf_alloc_task(d) < 0 ) return -1; sedf_add_task(d); EDOM_INFO(d)->deadl_abs = 0; EDOM_INFO(d)->status &= ~SEDF_ASLEEP; - set_bit(EDF_RUNNING, &d->flags); + set_bit(_VCPUF_running, &d->vcpu_flags); /*the idle task doesn't have to turn up on any list...*/ return 0; } @@ -497,7 +497,7 @@ struct list_head* waitq) { list_for_each_safe(cur, tmp, waitq) { curinf = list_entry(cur, struct sedf_edom_info, list); PRINT(4,"\tLooking @ dom %i.%i\n", - curinf->exec_domain->domain->id, curinf->exec_domain->id); + curinf->exec_domain->domain->domain_id, curinf->exec_domain->vcpu_id); if (PERIOD_BEGIN(curinf) <= now) { __del_from_queue(curinf->exec_domain); __add_to_runqueue_sort(curinf->exec_domain); @@ -512,12 +512,12 @@ struct list_head* waitq) { list_for_each_safe(cur, tmp, runq) { curinf = list_entry(cur,struct sedf_edom_info,list); PRINT(4,"\tLooking @ dom %i.%i\n", - curinf->exec_domain->domain->id, curinf->exec_domain->id); + curinf->exec_domain->domain->domain_id, curinf->exec_domain->vcpu_id); if (unlikely(curinf->slice == 0)) { /*ignore domains with empty slice*/ PRINT(4,"\tUpdating zero-slice domain %i.%i\n", - curinf->exec_domain->domain->id, - curinf->exec_domain->id); + curinf->exec_domain->domain->domain_id, + curinf->exec_domain->vcpu_id); __del_from_queue(curinf->exec_domain); /*move them to their next period*/ @@ -534,8 +534,8 @@ struct list_head* waitq) { PRINT(4,"\tDomain %i.%i exceeded it's deadline/" "slice (%"PRIu64" / %"PRIu64") now: %"PRIu64 " cputime: %"PRIu64"\n", - curinf->exec_domain->domain->id, - curinf->exec_domain->id, + curinf->exec_domain->domain->domain_id, + curinf->exec_domain->vcpu_id, curinf->deadl_abs, curinf->slice, now, curinf->cputime); __del_from_queue(curinf->exec_domain); @@ -601,11 +601,11 @@ static inline void desched_extra_dom(s_time_t now, struct exec_domain* d) { /*inf->short_block_lost_tot -= EXTRA_QUANTUM;*/ inf->short_block_lost_tot -= now - inf->sched_start_abs; PRINT(3,"Domain %i.%i: Short_block_loss: %"PRIi64"\n", - inf->exec_domain->domain->id, inf->exec_domain->id, + inf->exec_domain->domain->domain_id, inf->exec_domain->vcpu_id, inf->short_block_lost_tot); if (inf->short_block_lost_tot <= 0) { PRINT(4,"Domain %i.%i compensated short block loss!\n", - inf->exec_domain->domain->id, inf->exec_domain->id); + inf->exec_domain->domain->domain_id, inf->exec_domain->vcpu_id); /*we have (over-)compensated our block penalty*/ inf->short_block_lost_tot = 0; /*we don't want a place on the penalty queue anymore!*/ @@ -808,14 +808,14 @@ sched_done: } static void sedf_sleep(struct exec_domain *d) { - PRINT(2,"sedf_sleep was called, domain-id %i.%i\n",d->domain->id, d->id); + PRINT(2,"sedf_sleep was called, domain-id %i.%i\n",d->domain->domain_id, d->vcpu_id); if (is_idle_task(d->domain)) return; EDOM_INFO(d)->status |= SEDF_ASLEEP; - if ( test_bit(EDF_RUNNING, &d->flags) ) { + if ( test_bit(_VCPUF_running, &d->vcpu_flags) ) { #ifdef ADV_SCHED_HISTO adv_sched_hist_start(d->processor); #endif @@ -1140,14 +1140,14 @@ void sedf_wake(struct exec_domain *d) { s_time_t now = NOW(); struct sedf_edom_info* inf = EDOM_INFO(d); - PRINT(3, "sedf_wake was called, domain-id %i.%i\n",d->domain->id, d->id); + PRINT(3, "sedf_wake was called, domain-id %i.%i\n",d->domain->domain_id, d->vcpu_id); if (unlikely(is_idle_task(d->domain))) return; if ( unlikely(__task_on_queue(d)) ) { PRINT(3,"\tdomain %i.%i is already in some queue\n", - d->domain->id, d->id); + d->domain->domain_id, d->vcpu_id); return; } ASSERT(!sedf_runnable(d)); @@ -1160,7 +1160,7 @@ void sedf_wake(struct exec_domain *d) { inf->deadl_abs = now + inf->slice; PRINT(3,"waking up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64" "\ - "now= %"PRIu64")\n", d->domain->id, d->id, inf->deadl_abs, + "now= %"PRIu64")\n", d->domain->domain_id, d->vcpu_id, inf->deadl_abs, inf->period, now); #ifdef SEDF_STATS inf->block_tot++; @@ -1222,7 +1222,7 @@ void sedf_wake(struct exec_domain *d) { } } PRINT(3,"woke up domain %i.%i (deadl= %"PRIu64" period= %"PRIu64" "\ - "now= %"PRIu64")\n", d->domain->id, d->id, inf->deadl_abs, + "now= %"PRIu64")\n", d->domain->domain_id, d->vcpu_id, inf->deadl_abs, inf->period, now); if (PERIOD_BEGIN(inf) > now) { __add_to_waitqueue_sort(d); @@ -1257,8 +1257,8 @@ void sedf_wake(struct exec_domain *d) { /*Print a lot of use-{full, less} information about a domains in the system*/ static void sedf_dump_domain(struct exec_domain *d) { - printk("%i.%i has=%c ", d->domain->id, d->id, - test_bit(EDF_RUNNING, &d->flags) ? 'T':'F'); + printk("%i.%i has=%c ", d->domain->domain_id, d->vcpu_id, + test_bit(_VCPUF_running, &d->vcpu_flags) ? 'T':'F'); printk("p=%"PRIu64" sl=%"PRIu64" ddl=%"PRIu64" w=%hu c=%"PRIu64" sc=%i xtr(%s)=%"PRIu64" ew=%hu", EDOM_INFO(d)->period, EDOM_INFO(d)->slice, EDOM_INFO(d)->deadl_abs, EDOM_INFO(d)->weight, d->cpu_time, EDOM_INFO(d)->score[EXTRA_UTIL_Q], @@ -1399,7 +1399,7 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) { PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "\ "new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n", - p->id, cmd->u.sedf.period, cmd->u.sedf.slice, + p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice, cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no"); if ( cmd->direction == SCHED_INFO_PUT ) { diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 491c2f22ac..bcb6a06e6e 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -107,27 +107,27 @@ struct exec_domain *alloc_exec_domain_struct(struct domain *d, d->exec_domain[vcpu] = ed; ed->domain = d; - ed->id = vcpu; + ed->vcpu_id = vcpu; if ( SCHED_OP(alloc_task, ed) < 0 ) goto out; if ( vcpu != 0 ) { - ed->vcpu_info = &d->shared_info->vcpu_data[ed->id]; + ed->vcpu_info = &d->shared_info->vcpu_data[ed->vcpu_id]; for_each_exec_domain( d, edc ) { if ( (edc->next_in_list == NULL) || - (edc->next_in_list->id > vcpu) ) + (edc->next_in_list->vcpu_id > vcpu) ) break; } ed->next_in_list = edc->next_in_list; edc->next_in_list = ed; - if (test_bit(EDF_CPUPINNED, &edc->flags)) { + if (test_bit(_VCPUF_cpu_pinned, &edc->vcpu_flags)) { ed->processor = (edc->processor + 1) % smp_num_cpus; - set_bit(EDF_CPUPINNED, &ed->flags); + set_bit(_VCPUF_cpu_pinned, &ed->vcpu_flags); } else { ed->processor = (edc->processor + 1) % smp_num_cpus; /* XXX */ } @@ -169,9 +169,9 @@ void sched_add_domain(struct exec_domain *ed) struct domain *d = ed->domain; /* Must be unpaused by control software to start execution. */ - set_bit(EDF_CTRLPAUSE, &ed->flags); + set_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags); - if ( d->id != IDLE_DOMAIN_ID ) + if ( d->domain_id != IDLE_DOMAIN_ID ) { /* Initialise the per-domain timer. */ init_ac_timer(&ed->timer); @@ -185,14 +185,14 @@ void sched_add_domain(struct exec_domain *ed) } SCHED_OP(add_task, ed); - TRACE_2D(TRC_SCHED_DOM_ADD, d->id, ed->id); + TRACE_2D(TRC_SCHED_DOM_ADD, d->domain_id, ed->vcpu_id); } void sched_rem_domain(struct exec_domain *ed) { rem_ac_timer(&ed->timer); SCHED_OP(rem_task, ed); - TRACE_2D(TRC_SCHED_DOM_REM, ed->domain->id, ed->id); + TRACE_2D(TRC_SCHED_DOM_REM, ed->domain->domain_id, ed->vcpu_id); } void init_idle_task(void) @@ -210,10 +210,10 @@ void domain_sleep(struct exec_domain *ed) SCHED_OP(sleep, ed); spin_unlock_irqrestore(&schedule_data[ed->processor].schedule_lock, flags); - TRACE_2D(TRC_SCHED_SLEEP, ed->domain->id, ed->id); + TRACE_2D(TRC_SCHED_SLEEP, ed->domain->domain_id, ed->vcpu_id); /* Synchronous. */ - while ( test_bit(EDF_RUNNING, &ed->flags) && !domain_runnable(ed) ) + while ( test_bit(_VCPUF_running, &ed->vcpu_flags) && !domain_runnable(ed) ) cpu_relax(); } @@ -229,10 +229,10 @@ void domain_wake(struct exec_domain *ed) ed->wokenup = NOW(); #endif } - clear_bit(EDF_MIGRATED, &ed->flags); + clear_bit(_VCPUF_cpu_migrated, &ed->vcpu_flags); spin_unlock_irqrestore(&schedule_data[ed->processor].schedule_lock, flags); - TRACE_2D(TRC_SCHED_WAKE, ed->domain->id, ed->id); + TRACE_2D(TRC_SCHED_WAKE, ed->domain->domain_id, ed->vcpu_id); } /* Block the currently-executing domain until a pertinent event occurs. */ @@ -245,16 +245,16 @@ long do_block(void) #endif ed->vcpu_info->evtchn_upcall_mask = 0; - set_bit(EDF_BLOCKED, &ed->flags); + set_bit(_VCPUF_blocked, &ed->vcpu_flags); /* Check for events /after/ blocking: avoids wakeup waiting race. */ if ( event_pending(ed) ) { - clear_bit(EDF_BLOCKED, &ed->flags); + clear_bit(_VCPUF_blocked, &ed->vcpu_flags); } else { - TRACE_2D(TRC_SCHED_BLOCK, ed->domain->id, ed->id); + TRACE_2D(TRC_SCHED_BLOCK, ed->domain->domain_id, ed->vcpu_id); __enter_scheduler(); } @@ -268,7 +268,7 @@ static long do_yield(void) adv_sched_hist_start(current->processor); #endif - TRACE_2D(TRC_SCHED_YIELD, current->domain->id, current->id); + TRACE_2D(TRC_SCHED_YIELD, current->domain->domain_id, current->vcpu_id); __enter_scheduler(); return 0; } @@ -297,7 +297,7 @@ long do_sched_op(unsigned long op) case SCHEDOP_shutdown: { - TRACE_3D(TRC_SCHED_SHUTDOWN, current->domain->id, current->id, + TRACE_3D(TRC_SCHED_SHUTDOWN, current->domain->domain_id, current->vcpu_id, (op >> SCHEDOP_reasonshift)); domain_shutdown((u8)(op >> SCHEDOP_reasonshift)); break; @@ -400,7 +400,7 @@ long sched_adjdom(struct sched_adjdom_cmd *cmd) spin_unlock(&schedule_data[cpu].schedule_lock); __clear_cpu_bits(have_lock); - TRACE_1D(TRC_SCHED_ADJDOM, d->id); + TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id); put_domain(d); return 0; } @@ -451,7 +451,7 @@ static void __enter_scheduler(void) add_ac_timer(&schedule_data[cpu].s_timer); /* Must be protected by the schedule_lock! */ - set_bit(EDF_RUNNING, &next->flags); + set_bit(_VCPUF_running, &next->vcpu_flags); spin_unlock_irq(&schedule_data[cpu].schedule_lock); @@ -492,8 +492,8 @@ static void __enter_scheduler(void) } TRACE_4D(TRC_SCHED_SWITCH, - prev->domain->id, prev->id, - next->domain->id, next->id); + prev->domain->domain_id, prev->vcpu_id, + next->domain->domain_id, next->vcpu_id); #ifdef ADV_SCHED_HISTO adv_sched_hist_to_stop(cpu); diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index d9eb0c474a..73394c1973 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -303,7 +303,7 @@ long do_console_io(int cmd, int count, char *buffer) #ifndef VERBOSE /* Only domain-0 may access the emergency console. */ - if ( current->domain->id != 0 ) + if ( current->domain->domain_id != 0 ) return -EPERM; #endif diff --git a/xen/include/asm-x86/acpi.h b/xen/include/asm-x86/acpi.h index 3a15181819..b13f8ff79a 100644 --- a/xen/include/asm-x86/acpi.h +++ b/xen/include/asm-x86/acpi.h @@ -27,7 +27,7 @@ #define _ASM_ACPI_H #include -#include +#include /* defines cmpxchg */ #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -49,8 +49,8 @@ #define ACPI_ASM_MACROS #define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() __cli() -#define ACPI_ENABLE_IRQS() __sti() +#define ACPI_DISABLE_IRQS() local_irq_disable() +#define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() @@ -100,6 +100,11 @@ __acpi_release_global_lock (unsigned int *lock) :"=r"(n_hi), "=r"(n_lo) \ :"0"(n_hi), "1"(n_lo)) +/* + * Refer Intel ACPI _PDC support document for bit definitions + */ +#define ACPI_PDC_EST_CAPABILITY_SMP 0xa +#define ACPI_PDC_EST_CAPABILITY_MSR 0x1 #ifdef CONFIG_ACPI_BOOT extern int acpi_lapic; @@ -108,47 +113,53 @@ extern int acpi_noirq; extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; -static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; } +extern int acpi_pci_disabled; +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_ht = 0; + acpi_pci_disabled = 1; + acpi_noirq = 1; +} /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ #define FIX_ACPI_PAGES 4 -#else /* !CONFIG_ACPI_BOOT */ +extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); + +#ifdef CONFIG_X86_IO_APIC +extern int skip_ioapic_setup; +extern int acpi_skip_timer_override; + +extern void check_acpi_pci(void); + +static inline void disable_ioapic_setup(void) +{ + skip_ioapic_setup = 1; +} + +static inline int ioapic_setup_disabled(void) +{ + return skip_ioapic_setup; +} + +#else +static inline void disable_ioapic_setup(void) { } +static inline void check_acpi_pci(void) { } + +#endif + +#else /* CONFIG_ACPI_BOOT */ # define acpi_lapic 0 # define acpi_ioapic 0 -#endif /* !CONFIG_ACPI_BOOT */ - -#ifdef CONFIG_ACPI_PCI -static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -extern int acpi_irq_balance_set(char *str); -#else -static inline void acpi_noirq_set(void) { } -static inline int acpi_irq_balance_set(char *str) { return 0; } #endif +static inline void acpi_noirq_set(void) { acpi_noirq = 1; } +static inline int acpi_irq_balance_set(char *str) { return 0; } + #ifdef CONFIG_ACPI_SLEEP -extern unsigned long saved_eip; -extern unsigned long saved_esp; -extern unsigned long saved_ebp; -extern unsigned long saved_ebx; -extern unsigned long saved_esi; -extern unsigned long saved_edi; - -static inline void acpi_save_register_state(unsigned long return_point) -{ - saved_eip = return_point; - asm volatile ("movl %%esp,(%0)" : "=m" (saved_esp)); - asm volatile ("movl %%ebp,(%0)" : "=m" (saved_ebp)); - asm volatile ("movl %%ebx,(%0)" : "=m" (saved_ebx)); - asm volatile ("movl %%edi,(%0)" : "=m" (saved_edi)); - asm volatile ("movl %%esi,(%0)" : "=m" (saved_esi)); -} - -#define acpi_restore_register_state() do {} while (0) - - /* routines for saving/restoring kernel state */ extern int acpi_save_state_mem(void); extern int acpi_save_state_disk(void); @@ -156,11 +167,11 @@ extern void acpi_restore_state_mem(void); extern unsigned long acpi_wakeup_address; -extern void do_suspend_lowlevel_s4bios(int resume); - /* early initialization routine */ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ +extern u8 x86_acpiid_to_apicid[]; + #endif /*_ASM_ACPI_H*/ diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 1ddc8228db..d98a57e5a2 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -275,9 +275,9 @@ extern unsigned long _end; /* standard ELF symbol */ extern unsigned long xenheap_phys_end; /* user-configurable */ #endif -#define GDT_VIRT_START(ed) (PERDOMAIN_VIRT_START + ((ed)->id << PDPT_VCPU_VA_SHIFT)) +#define GDT_VIRT_START(ed) (PERDOMAIN_VIRT_START + ((ed)->vcpu_id << PDPT_VCPU_VA_SHIFT)) #define GDT_VIRT_END(ed) (GDT_VIRT_START(ed) + (64*1024)) -#define LDT_VIRT_START(ed) (PERDOMAIN_VIRT_START + (64*1024) + ((ed)->id << PDPT_VCPU_VA_SHIFT)) +#define LDT_VIRT_START(ed) (PERDOMAIN_VIRT_START + (64*1024) + ((ed)->vcpu_id << PDPT_VCPU_VA_SHIFT)) #define LDT_VIRT_END(ed) (LDT_VIRT_START(ed) + (64*1024)) #define PDPT_VCPU_SHIFT 5 diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h index 6e9cf223d5..cff37a83a8 100644 --- a/xen/include/asm-x86/debugger.h +++ b/xen/include/asm-x86/debugger.h @@ -62,14 +62,14 @@ static inline int debugger_trap_entry( { struct exec_domain *ed = current; - if ( !KERNEL_MODE(ed, regs) || (ed->domain->id == 0) ) + if ( !KERNEL_MODE(ed, regs) || (ed->domain->domain_id == 0) ) return 0; switch ( vector ) { case TRAP_int3: case TRAP_debug: - set_bit(EDF_CTRLPAUSE, &ed->flags); + set_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags); raise_softirq(SCHEDULE_SOFTIRQ); return 1; } diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 683ba2ac0c..86c806d2fd 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -30,7 +30,7 @@ struct arch_domain /* Shadow mode status and controls. */ unsigned int shadow_mode; /* flags to control shadow table operation */ - spinlock_t shadow_lock; + unsigned int shadow_nest; /* Recursive depth of shadow_lock() nesting */ /* Shadow mode has tainted page reference counts? */ unsigned int shadow_tainted_refcnts; diff --git a/xen/include/asm-x86/i387.h b/xen/include/asm-x86/i387.h index ca81778089..a1f0feaec0 100644 --- a/xen/include/asm-x86/i387.h +++ b/xen/include/asm-x86/i387.h @@ -19,7 +19,7 @@ extern void save_init_fpu(struct exec_domain *tsk); extern void restore_fpu(struct exec_domain *tsk); #define unlazy_fpu(_tsk) do { \ - if ( test_bit(EDF_USEDFPU, &(_tsk)->flags) ) \ + if ( test_bit(_VCPUF_fpu_dirtied, &(_tsk)->vcpu_flags) ) \ save_init_fpu(_tsk); \ } while ( 0 ) @@ -28,4 +28,16 @@ extern void restore_fpu(struct exec_domain *tsk); __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) ); \ } while ( 0 ) +/* Make domain the FPU owner */ +static inline void setup_fpu(struct exec_domain *ed) +{ + if ( !test_and_set_bit(_VCPUF_fpu_dirtied, &ed->vcpu_flags) ) + { + if ( test_bit(_VCPUF_fpu_initialised, &ed->vcpu_flags) ) + restore_fpu(ed); + else + init_fpu(); + } +} + #endif /* __ASM_I386_I387_H */ diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 202453194f..f176427991 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -60,9 +60,45 @@ #define __linear_hl2_table ((l1_pgentry_t *)(LINEAR_PT_VIRT_START + \ (PERDOMAIN_VIRT_START >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))) -#define shadow_lock_init(_d) spin_lock_init(&(_d)->arch.shadow_lock) -#define shadow_lock(_d) do { ASSERT(!spin_is_locked(&(_d)->arch.shadow_lock)); spin_lock(&(_d)->arch.shadow_lock); } while (0) -#define shadow_unlock(_d) spin_unlock(&(_d)->arch.shadow_lock) +/* + * For now we use the per-domain BIGLOCK rather than a shadow-specific lock. + * We usually have the BIGLOCK already acquired anyway, so this is unlikely + * to cause much unnecessary extra serialisation. Also it's a recursive + * lock, and there are some code paths containing nested shadow_lock(). + * The #if0'ed code below is therefore broken until such nesting is removed. + */ +#if 0 +#define shadow_lock_init(_d) \ + spin_lock_init(&(_d)->arch.shadow_lock) +#define shadow_lock_is_acquired(_d) \ + spin_is_locked(&(_d)->arch.shadow_lock) +#define shadow_lock(_d) \ +do { \ + ASSERT(!shadow_lock_is_acquired(_d)); \ + spin_lock(&(_d)->arch.shadow_lock); \ +} while (0) +#define shadow_unlock(_d) \ +do { \ + ASSERT(!shadow_lock_is_acquired(_d)); \ + spin_unlock(&(_d)->arch.shadow_lock); \ +} while (0) +#else +#define shadow_lock_init(_d) \ + ((_d)->arch.shadow_nest = 0) +#define shadow_lock_is_acquired(_d) \ + (spin_is_locked(&(_d)->big_lock) && ((_d)->arch.shadow_nest != 0)) +#define shadow_lock(_d) \ +do { \ + LOCK_BIGLOCK(_d); \ + (_d)->arch.shadow_nest++; \ +} while (0) +#define shadow_unlock(_d) \ +do { \ + ASSERT(shadow_lock_is_acquired(_d)); \ + (_d)->arch.shadow_nest--; \ + UNLOCK_BIGLOCK(_d); \ +} while (0) +#endif #define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((L1_PAGETABLE_ENTRIES - 1) - (_max)) << 16) | (_min)) #define SHADOW_MIN(_encoded) ((_encoded) & ((1u<<16) - 1)) @@ -281,7 +317,7 @@ extern int shadow_status_noswap; #ifdef VERBOSE #define SH_LOG(_f, _a...) \ printk("DOM%uP%u: SH_LOG(%d): " _f "\n", \ - current->domain->id , current->processor, __LINE__ , ## _a ) + current->domain->domain_id , current->processor, __LINE__ , ## _a ) #else #define SH_LOG(_f, _a...) ((void)0) #endif @@ -289,7 +325,7 @@ extern int shadow_status_noswap; #if SHADOW_VERBOSE_DEBUG #define SH_VLOG(_f, _a...) \ printk("DOM%uP%u: SH_VLOG(%d): " _f "\n", \ - current->domain->id, current->processor, __LINE__ , ## _a ) + current->domain->domain_id, current->processor, __LINE__ , ## _a ) #else #define SH_VLOG(_f, _a...) ((void)0) #endif @@ -297,7 +333,7 @@ extern int shadow_status_noswap; #if SHADOW_VVERBOSE_DEBUG #define SH_VVLOG(_f, _a...) \ printk("DOM%uP%u: SH_VVLOG(%d): " _f "\n", \ - current->domain->id, current->processor, __LINE__ , ## _a ) + current->domain->domain_id, current->processor, __LINE__ , ## _a ) #else #define SH_VVLOG(_f, _a...) ((void)0) #endif @@ -305,7 +341,7 @@ extern int shadow_status_noswap; #if SHADOW_VVVERBOSE_DEBUG #define SH_VVVLOG(_f, _a...) \ printk("DOM%uP%u: SH_VVVLOG(%d): " _f "\n", \ - current->domain->id, current->processor, __LINE__ , ## _a ) + current->domain->domain_id, current->processor, __LINE__ , ## _a ) #else #define SH_VVVLOG(_f, _a...) ((void)0) #endif @@ -313,7 +349,7 @@ extern int shadow_status_noswap; #if FULLSHADOW_DEBUG #define FSH_LOG(_f, _a...) \ printk("DOM%uP%u: FSH_LOG(%d): " _f "\n", \ - current->domain->id, current->processor, __LINE__ , ## _a ) + current->domain->domain_id, current->processor, __LINE__ , ## _a ) #else #define FSH_LOG(_f, _a...) ((void)0) #endif @@ -348,7 +384,8 @@ shadow_get_page_from_l1e(l1_pgentry_t l1e, struct domain *d) res = get_page_from_l1e(nl1e, owner); printk("tried to map mfn %lx from domain %d into shadow page tables " "of domain %d; %s\n", - mfn, owner->id, d->id, res ? "success" : "failed"); + mfn, owner->domain_id, d->domain_id, + res ? "success" : "failed"); } if ( unlikely(!res) ) @@ -403,7 +440,7 @@ static inline int __mark_dirty(struct domain *d, unsigned int mfn) unsigned long pfn; int rc = 0; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(d->arch.shadow_dirty_bitmap != NULL); if ( !VALID_MFN(mfn) ) @@ -1137,7 +1174,7 @@ static inline unsigned long __shadow_status( ? __gpfn_to_mfn(d, gpfn) : INVALID_MFN); - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(gpfn == (gpfn & PGT_mfn_mask)); ASSERT(stype && !(stype & ~PGT_type_mask)); @@ -1153,7 +1190,7 @@ static inline unsigned long __shadow_status( { printk("d->id=%d gpfn=%lx gmfn=%lx stype=%lx c=%x t=%x " "mfn_out_of_sync(gmfn)=%d mfn_is_page_table(gmfn)=%d\n", - d->id, gpfn, gmfn, stype, + d->domain_id, gpfn, gmfn, stype, frame_table[gmfn].count_info, frame_table[gmfn].u.inuse.type_info, mfn_out_of_sync(gmfn), mfn_is_page_table(gmfn)); @@ -1186,7 +1223,7 @@ shadow_max_pgtable_type(struct domain *d, unsigned long gpfn, struct shadow_status *x; u32 pttype = PGT_none, type; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(gpfn == (gpfn & PGT_mfn_mask)); perfc_incrc(shadow_max_type); @@ -1280,7 +1317,7 @@ static inline void delete_shadow_status( struct shadow_status *p, *x, *n, *head; unsigned long key = gpfn | stype; - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(!(gpfn & ~PGT_mfn_mask)); ASSERT(stype && !(stype & ~PGT_type_mask)); @@ -1362,7 +1399,7 @@ static inline void set_shadow_status( SH_VVLOG("set gpfn=%lx gmfn=%lx smfn=%lx t=%lx", gpfn, gmfn, smfn, stype); - ASSERT(spin_is_locked(&d->arch.shadow_lock)); + ASSERT(shadow_lock_is_acquired(d)); ASSERT(shadow_mode_translate(d) || gpfn); ASSERT(!(gpfn & ~PGT_mfn_mask)); diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index 334afcf6be..3041a334f1 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -24,6 +24,7 @@ #include #include #include +#include extern void vmx_asm_vmexit_handler(struct cpu_user_regs); extern void vmx_asm_do_resume(void); @@ -251,4 +252,19 @@ static inline int __vmxon (u64 addr) return 0; } +/* Make sure that xen intercepts any FP accesses from current */ +static inline void vmx_stts() +{ + unsigned long cr0; + + __vmread(GUEST_CR0, &cr0); + if (!(cr0 & X86_CR0_TS)) + __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS); + + __vmread(CR0_READ_SHADOW, &cr0); + if (!(cr0 & X86_CR0_TS)) + __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP | + EXCEPTION_BITMAP_NM); +} + #endif /* __ASM_X86_VMX_H__ */ diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 869a959f6c..430244d220 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -19,7 +19,7 @@ * This makes sure that old versions of dom0 tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define DOM0_INTERFACE_VERSION 0xAAAA1004 +#define DOM0_INTERFACE_VERSION 0xAAAA1005 /************************************************************************/ @@ -70,7 +70,6 @@ typedef struct { typedef struct { /* IN variables. */ domid_t domain; /* NB. IN/OUT variable. */ - u16 exec_domain; /* OUT variables. */ #define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ #define DOMFLAGS_CRASHED (1<<1) /* Crashed domain; frozen for postmortem. */ @@ -83,18 +82,20 @@ typedef struct { #define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */ #define DOMFLAGS_SHUTDOWNSHIFT 16 u32 flags; - vcpu_guest_context_t *ctxt; /* NB. IN/OUT variable. */ memory_t tot_pages; memory_t max_pages; memory_t shared_info_frame; /* MFN of shared_info struct */ u64 cpu_time; + u32 n_vcpu; + s32 vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */ + cpumap_t cpumap[MAX_VIRT_CPUS]; /* allowable mapping */ } dom0_getdomaininfo_t; #define DOM0_SETDOMAININFO 13 typedef struct { /* IN variables. */ domid_t domain; - u16 exec_domain; + u16 vcpu; /* IN/OUT parameters */ vcpu_guest_context_t *ctxt; } dom0_setdomaininfo_t; @@ -170,14 +171,14 @@ typedef struct { } dom0_readconsole_t; /* - * Pin Domain to a particular CPU (use -1 to unpin) + * Set which physical cpus a vcpu can execute on. */ #define DOM0_PINCPUDOMAIN 20 typedef struct { /* IN variables. */ domid_t domain; - u16 exec_domain; - s32 cpu; /* -1 implies unpin */ + u16 vcpu; + cpumap_t *cpumap; } dom0_pincpudomain_t; /* Get trace buffers machine base address */ @@ -342,6 +343,14 @@ typedef struct { u16 allow_access; /* allow or deny access to range? */ } dom0_ioport_permission_t; +#define DOM0_GETVCPUCONTEXT 37 +typedef struct { + domid_t domain; /* domain to be affected */ + u16 vcpu; /* vcpu # */ + vcpu_guest_context_t *ctxt; /* NB. IN/OUT variable. */ + u64 cpu_time; +} dom0_getvcpucontext_t; + typedef struct { u32 cmd; u32 interface_version; /* DOM0_INTERFACE_VERSION */ @@ -373,6 +382,7 @@ typedef struct { dom0_perfccontrol_t perfccontrol; dom0_microcode_t microcode; dom0_ioport_permission_t ioport_permission; + dom0_getvcpucontext_t getvcpucontext; } u; } dom0_op_t; diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 7dc30c9dc6..e3ba5e9b06 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -473,6 +473,8 @@ typedef struct { /* For use in guest OSes. */ extern shared_info_t *HYPERVISOR_shared_info; +typedef u64 cpumap_t; + #endif /* !__ASSEMBLY__ */ #endif /* __XEN_PUBLIC_XEN_H__ */ diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index ac7ce6b1a0..306883c594 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -35,15 +35,15 @@ static inline void evtchn_set_pending(struct exec_domain *ed, int port) set_bit(0, &ed->vcpu_info->evtchn_upcall_pending); /* - * NB1. 'flags' and 'processor' must be checked /after/ update of + * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of * pending flag. These values may fluctuate (after all, we hold no * locks) but the key insight is that each change will cause * evtchn_upcall_pending to be polled. * - * NB2. We save DF_RUNNING across the unblock to avoid a needless + * NB2. We save VCPUF_running across the unblock to avoid a needless * IPI for domains that we IPI'd to unblock. */ - running = test_bit(EDF_RUNNING, &ed->flags); + running = test_bit(_VCPUF_running, &ed->vcpu_flags); exec_domain_unblock(ed); if ( running ) smp_send_event_check_cpu(ed->processor); diff --git a/xen/include/xen/init.h b/xen/include/xen/init.h index 991abc6c24..0709c9abd8 100644 --- a/xen/include/xen/init.h +++ b/xen/include/xen/init.h @@ -59,13 +59,17 @@ extern initcall_t __initcall_start, __initcall_end; */ struct kernel_param { const char *name; - enum { OPT_STR, OPT_UINT, OPT_UINT_UNIT, OPT_BOOL } type; + enum { OPT_STR, OPT_UINT, OPT_BOOL, OPT_CUSTOM } type; void *var; unsigned int len; }; extern struct kernel_param __setup_start, __setup_end; +#define custom_param(_name, _var) \ + static char __setup_str_##_var[] __initdata = _name; \ + static struct kernel_param __setup_##_var __attribute_used__ \ + __initsetup = { __setup_str_##_var, OPT_CUSTOM, &_var, 0 } #define boolean_param(_name, _var) \ static char __setup_str_##_var[] __initdata = _name; \ static struct kernel_param __setup_##_var __attribute_used__ \ @@ -74,10 +78,6 @@ extern struct kernel_param __setup_start, __setup_end; static char __setup_str_##_var[] __initdata = _name; \ static struct kernel_param __setup_##_var __attribute_used__ \ __initsetup = { __setup_str_##_var, OPT_UINT, &_var, sizeof(_var) } -#define integer_unit_param(_name, _var) \ - static char __setup_str_##_var[] __initdata = _name; \ - static struct kernel_param __setup_##_var __attribute_used__ \ - __initsetup = { __setup_str_##_var, OPT_UINT_UNIT, &_var, sizeof(_var) } #define string_param(_name, _var) \ static char __setup_str_##_var[] __initdata = _name; \ static struct kernel_param __setup_##_var __attribute_used__ \ diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index b8a981a632..56eae9d9b5 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -57,8 +57,15 @@ extern int snprintf(char * buf, size_t size, const char * fmt, ...) __attribute__ ((format (printf, 3, 4))); extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); -long simple_strtol(const char *cp,char **endp,unsigned int base); -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base); -long long simple_strtoll(const char *cp,char **endp,unsigned int base); +long simple_strtol( + const char *cp,char **endp, unsigned int base); +unsigned long simple_strtoul( + const char *cp,char **endp, unsigned int base); +long long simple_strtoll( + const char *cp,char **endp, unsigned int base); +unsigned long long simple_strtoull( + const char *cp,char **endp, unsigned int base); + +unsigned long long memparse(char *s); #endif /* __LIB_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 6f64e0c057..96a3be971c 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -58,9 +58,11 @@ int init_event_channels(struct domain *d); void destroy_event_channels(struct domain *d); int init_exec_domain_event_channels(struct exec_domain *ed); +#define CPUMAP_RUNANYWHERE 0xFFFFFFFF + struct exec_domain { - int id; + int vcpu_id; int processor; @@ -78,12 +80,14 @@ struct exec_domain s_time_t wokenup; /* time domain got woken up */ void *sched_priv; /* scheduler-specific data */ - unsigned long flags; + unsigned long vcpu_flags; u16 virq_to_evtchn[NR_VIRQS]; atomic_t pausecnt; + cpumap_t cpumap; /* which cpus this domain can run on */ + struct arch_exec_domain arch; }; @@ -93,7 +97,7 @@ struct exec_domain struct domain { - domid_t id; + domid_t domain_id; shared_info_t *shared_info; /* shared data area */ spinlock_t time_lock; @@ -109,7 +113,7 @@ struct domain unsigned int xenheap_pages; /* # pages allocated from Xen heap */ /* Scheduling. */ - int shutdown_code; /* code value from OS (if DF_SHUTDOWN). */ + int shutdown_code; /* code value from OS (if DOMF_shutdown) */ void *sched_priv; /* scheduler-specific data */ struct domain *next_in_list; @@ -131,7 +135,7 @@ struct domain u16 pirq_to_evtchn[NR_PIRQS]; u32 pirq_mask[NR_PIRQS/32]; - unsigned long flags; + unsigned long domain_flags; unsigned long vm_assist; atomic_t refcnt; @@ -168,7 +172,7 @@ extern struct exec_domain idle0_exec_domain; extern struct exec_domain *idle_task[NR_CPUS]; #define IDLE_DOMAIN_ID (0x7FFFU) -#define is_idle_task(_p) (test_bit(DF_IDLETASK, &(_p)->flags)) +#define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags)) struct exec_domain *alloc_exec_domain_struct(struct domain *d, unsigned long vcpu); @@ -324,29 +328,67 @@ extern struct domain *domain_list; (_ed) != NULL; \ (_ed) = (_ed)->next_in_list ) -#define EDF_DONEFPUINIT 0 /* Has the FPU been initialised for this task? */ -#define EDF_USEDFPU 1 /* Has this task used the FPU since last save? */ -#define EDF_GUEST_STTS 2 /* Has the guest OS requested 'stts'? */ -#define EDF_BLOCKED 3 /* Domain is blocked waiting for an event. */ -#define EDF_CTRLPAUSE 4 /* Domain is paused by controller software. */ -#define EDF_RUNNING 5 /* Currently running on a CPU. */ -#define EDF_CPUPINNED 6 /* Disables auto-migration. */ -#define EDF_MIGRATED 7 /* Domain migrated between CPUs. */ -#define EDF_DONEINIT 8 /* Initialization completed . */ +/* + * Per-VCPU flags (vcpu_flags). + */ + /* Has the FPU been initialised? */ +#define _VCPUF_fpu_initialised 0 +#define VCPUF_fpu_initialised (1UL<<_VCPUF_fpu_initialised) + /* Has the FPU been used since it was last saved? */ +#define _VCPUF_fpu_dirtied 1 +#define VCPUF_fpu_dirtied (1UL<<_VCPUF_fpu_dirtied) + /* Has the guest OS requested 'stts'? */ +#define _VCPUF_guest_stts 2 +#define VCPUF_guest_stts (1UL<<_VCPUF_guest_stts) + /* Domain is blocked waiting for an event. */ +#define _VCPUF_blocked 3 +#define VCPUF_blocked (1UL<<_VCPUF_blocked) + /* Domain is paused by controller software. */ +#define _VCPUF_ctrl_pause 4 +#define VCPUF_ctrl_pause (1UL<<_VCPUF_ctrl_pause) + /* Currently running on a CPU? */ +#define _VCPUF_running 5 +#define VCPUF_running (1UL<<_VCPUF_running) + /* Disables auto-migration between CPUs. */ +#define _VCPUF_cpu_pinned 6 +#define VCPUF_cpu_pinned (1UL<<_VCPUF_cpu_pinned) + /* Domain migrated between CPUs. */ +#define _VCPUF_cpu_migrated 7 +#define VCPUF_cpu_migrated (1UL<<_VCPUF_cpu_migrated) + /* Initialization completed. */ +#define _VCPUF_initialised 8 +#define VCPUF_initialised (1UL<<_VCPUF_initialised) -#define DF_CONSTRUCTED 0 /* Has the guest OS been fully built yet? */ -#define DF_IDLETASK 1 /* Is this one of the per-CPU idle domains? */ -#define DF_PRIVILEGED 2 /* Is this domain privileged? */ -#define DF_PHYSDEV 3 /* May this domain do IO to physical devices? */ -#define DF_SHUTDOWN 4 /* Guest shut itself down for some reason. */ -#define DF_CRASHED 5 /* Domain crashed inside Xen, cannot continue. */ -#define DF_DYING 6 /* Death rattle. */ +/* + * Per-domain flags (domain_flags). + */ + /* Has the guest OS been fully built yet? */ +#define _DOMF_constructed 0 +#define DOMF_constructed (1UL<<_DOMF_constructed) + /* Is this one of the per-CPU idle domains? */ +#define _DOMF_idle_domain 1 +#define DOMF_idle_domain (1UL<<_DOMF_idle_domain) + /* Is this domain privileged? */ +#define _DOMF_privileged 2 +#define DOMF_privileged (1UL<<_DOMF_privileged) + /* May this domain do IO to physical devices? */ +#define _DOMF_physdev_access 3 +#define DOMF_physdev_access (1UL<<_DOMF_physdev_access) + /* Guest shut itself down for some reason. */ +#define _DOMF_shutdown 4 +#define DOMF_shutdown (1UL<<_DOMF_shutdown) + /* Domain has crashed and cannot continue to execute. */ +#define _DOMF_crashed 5 +#define DOMF_crashed (1UL<<_DOMF_crashed) + /* Death rattle. */ +#define _DOMF_dying 6 +#define DOMF_dying (1UL<<_DOMF_dying) static inline int domain_runnable(struct exec_domain *ed) { return ( (atomic_read(&ed->pausecnt) == 0) && - !(ed->flags & ((1<domain->flags & ((1<vcpu_flags & (VCPUF_blocked|VCPUF_ctrl_pause)) && + !(ed->domain->domain_flags & (DOMF_shutdown|DOMF_crashed)) ); } static inline void exec_domain_pause(struct exec_domain *ed) @@ -388,7 +430,7 @@ static inline void domain_unpause(struct domain *d) static inline void exec_domain_unblock(struct exec_domain *ed) { - if ( test_and_clear_bit(EDF_BLOCKED, &ed->flags) ) + if ( test_and_clear_bit(_VCPUF_blocked, &ed->vcpu_flags) ) domain_wake(ed); } @@ -399,7 +441,7 @@ static inline void domain_pause_by_systemcontroller(struct domain *d) for_each_exec_domain ( d, ed ) { ASSERT(ed != current); - if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->flags) ) + if ( !test_and_set_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags) ) domain_sleep(ed); } @@ -412,14 +454,15 @@ static inline void domain_unpause_by_systemcontroller(struct domain *d) for_each_exec_domain ( d, ed ) { - if ( test_and_clear_bit(EDF_CTRLPAUSE, &ed->flags) ) + if ( test_and_clear_bit(_VCPUF_ctrl_pause, &ed->vcpu_flags) ) domain_wake(ed); } } - -#define IS_PRIV(_d) (test_bit(DF_PRIVILEGED, &(_d)->flags)) -#define IS_CAPABLE_PHYSDEV(_d) (test_bit(DF_PHYSDEV, &(_d)->flags)) +#define IS_PRIV(_d) \ + (test_bit(_DOMF_privileged, &(_d)->domain_flags)) +#define IS_CAPABLE_PHYSDEV(_d) \ + (test_bit(_DOMF_physdev_access, &(_d)->domain_flags)) #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))