[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [xenppc-unstable] [POWERPC] merge with xen-unstable f7d65fb7299b
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID b53c343b47ae930248f5db194b72d390e4143ccd # Parent e7cb3aefc233e24c6fa2803bc591b8442b833b6d # Parent f7d65fb7299b95b8b6d3a44134a9f2af211393c6 [POWERPC] merge with xen-unstable f7d65fb7299b --- tools/debugger/pdb/Domain.ml | 61 tools/debugger/pdb/Domain.mli | 39 tools/debugger/pdb/Intel.ml | 66 tools/debugger/pdb/Makefile | 57 tools/debugger/pdb/OCamlMakefile | 1149 ------------- tools/debugger/pdb/PDB.ml | 342 --- tools/debugger/pdb/Process.ml | 79 tools/debugger/pdb/Process.mli | 41 tools/debugger/pdb/Util.ml | 165 - tools/debugger/pdb/Xen_domain.ml | 43 tools/debugger/pdb/Xen_domain.mli | 25 tools/debugger/pdb/debugger.ml | 372 ---- tools/debugger/pdb/evtchn.ml | 40 tools/debugger/pdb/evtchn.mli | 19 tools/debugger/pdb/linux-2.6-module/Makefile | 21 tools/debugger/pdb/linux-2.6-module/debug.c | 851 --------- tools/debugger/pdb/linux-2.6-module/module.c | 337 --- tools/debugger/pdb/linux-2.6-module/pdb_debug.h | 47 tools/debugger/pdb/linux-2.6-module/pdb_module.h | 142 - tools/debugger/pdb/linux-2.6-patches/Makefile | 11 tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch | 18 tools/debugger/pdb/linux-2.6-patches/kdebug.patch | 10 tools/debugger/pdb/linux-2.6-patches/makefile.patch | 10 tools/debugger/pdb/linux-2.6-patches/ptrace.patch | 10 tools/debugger/pdb/linux-2.6-patches/traps.patch | 19 tools/debugger/pdb/pdb_caml_domain.c | 527 ----- tools/debugger/pdb/pdb_caml_evtchn.c | 186 -- tools/debugger/pdb/pdb_caml_process.c | 587 ------ tools/debugger/pdb/pdb_caml_xc.c | 170 - tools/debugger/pdb/pdb_caml_xcs.c | 307 --- tools/debugger/pdb/pdb_caml_xen.h | 39 tools/debugger/pdb/pdb_xen.c | 75 tools/debugger/pdb/readme | 96 - tools/debugger/pdb/server.ml | 241 -- tools/debugger/pdb/xcs.ml | 85 tools/debugger/pdb/xcs.mli | 13 tools/python/xen/xm/sysrq.py | 32 xen/arch/x86/hvm/svm/instrlen.c | 479 ----- .hgignore | 3 buildconfigs/linux-defconfig_xen0_ia64 | 1 buildconfigs/linux-defconfig_xenU_ia64 | 1 buildconfigs/linux-defconfig_xen_ia64 | 1 buildconfigs/linux-defconfig_xen_x86_32 | 1 buildconfigs/linux-defconfig_xen_x86_64 | 1 docs/man/xm.pod.1 | 4 docs/src/user.tex | 2 extras/mini-os/arch/x86/setup.c | 108 + extras/mini-os/include/x86/os.h | 5 extras/mini-os/kernel.c | 67 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 21 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c | 8 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 1 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 24 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 142 - linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 51 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c | 10 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 394 +--- linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 1 linux-2.6-xen-sparse/drivers/xen/core/skbuff.c | 7 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 3 linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 29 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 64 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 93 - linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 22 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 116 + linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 167 + linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 8 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 19 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 14 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 14 linux-2.6-xen-sparse/include/xen/balloon.h | 20 linux-2.6-xen-sparse/include/xen/public/evtchn.h | 3 linux-2.6-xen-sparse/mm/memory.c | 5 patches/linux-2.6.16.29/pci-mmconfig-fix-from-2.6.17.patch | 143 + patches/linux-2.6.16.29/series | 1 tools/blktap/drivers/Makefile | 5 tools/blktap/drivers/blktapctrl.c | 38 tools/blktap/drivers/tapdisk.c | 9 tools/blktap/lib/blktaplib.h | 7 tools/blktap/lib/xenbus.c | 191 +- tools/blktap/lib/xs_api.c | 103 - tools/blktap/lib/xs_api.h | 2 tools/examples/block | 1 tools/examples/init.d/xendomains | 8 tools/examples/locking.sh | 2 tools/examples/xen-backend.rules | 1 tools/examples/xend-config.sxp | 5 tools/examples/xmexample.hvm | 5 tools/firmware/hvmloader/hvmloader.c | 6 tools/firmware/hvmloader/smbios.c | 148 - tools/firmware/vmxassist/machine.h | 1 tools/firmware/vmxassist/vm86.c | 100 - tools/ioemu/hw/serial.c | 68 tools/ioemu/hw/vga.c | 13 tools/ioemu/hw/xen_platform.c | 6 tools/ioemu/patches/domain-timeoffset | 8 tools/ioemu/patches/fix-vga-scanning-code-overflow | 37 tools/ioemu/patches/qemu-bootorder | 18 tools/ioemu/patches/qemu-daemonize | 4 tools/ioemu/patches/qemu-pci | 23 tools/ioemu/patches/qemu-target-i386-dm | 18 tools/ioemu/patches/series | 4 tools/ioemu/patches/vnc-access-monitor-vt | 4 tools/ioemu/patches/vnc-backoff-screen-scan | 227 ++ tools/ioemu/patches/vnc-cleanup | 42 tools/ioemu/patches/vnc-display-find-unused | 14 tools/ioemu/patches/vnc-fixes | 57 tools/ioemu/patches/vnc-start-vncviewer | 9 tools/ioemu/patches/vnc-title-domain-name | 6 tools/ioemu/patches/xen-platform-device | 12 tools/ioemu/patches/xen-support-buffered-ioreqs | 8 tools/ioemu/patches/xenstore-block-device-config | 47 tools/ioemu/patches/xenstore-write-vnc-port | 10 tools/ioemu/usb-linux.c | 4 tools/ioemu/vl.c | 43 tools/ioemu/vl.h | 5 tools/ioemu/vnc.c | 299 ++- tools/libxc/xc_linux.c | 82 tools/libxc/xc_load_elf.c | 2 tools/libxc/xc_ptrace.c | 20 tools/libxc/xenctrl.h | 10 tools/misc/mbootpack/Makefile | 17 tools/misc/mbootpack/buildimage.c | 19 tools/misc/mbootpack/mbootpack.c | 20 tools/misc/miniterm/miniterm.c | 25 tools/pygrub/Makefile | 2 tools/pygrub/src/fsys/ext2/__init__.py | 2 tools/pygrub/src/fsys/reiser/__init__.py | 1 tools/pygrub/src/pygrub | 20 tools/python/xen/util/blkif.py | 8 tools/python/xen/xend/XendBootloader.py | 3 tools/python/xen/xend/XendCheckpoint.py | 4 tools/python/xen/xend/XendDomain.py | 29 tools/python/xen/xend/XendDomainInfo.py | 36 tools/python/xen/xend/XendRoot.py | 6 tools/python/xen/xend/image.py | 12 tools/python/xen/xend/server/DevController.py | 2 tools/python/xen/xend/server/SrvDomain.py | 2 tools/python/xen/xm/addlabel.py | 101 - tools/python/xen/xm/cfgbootpolicy.py | 96 - tools/python/xen/xm/console.py | 2 tools/python/xen/xm/create.py | 92 - tools/python/xen/xm/dry-run.py | 56 tools/python/xen/xm/dumppolicy.py | 31 tools/python/xen/xm/getlabel.py | 61 tools/python/xen/xm/labels.py | 77 tools/python/xen/xm/loadpolicy.py | 34 tools/python/xen/xm/main.py | 727 ++++---- tools/python/xen/xm/makepolicy.py | 25 tools/python/xen/xm/migrate.py | 16 tools/python/xen/xm/opts.py | 92 - tools/python/xen/xm/resources.py | 44 tools/python/xen/xm/rmlabel.py | 62 tools/python/xen/xm/shutdown.py | 1 tools/vnet/doc/man/vn.pod.1 | 4 tools/vnet/libxutil/Makefile | 2 tools/vnet/libxutil/hash_table.c | 13 tools/vnet/libxutil/hash_table.h | 1 tools/vnet/vnet-module/Makefile.ver | 27 tools/vnet/vnet-module/esp.c | 16 tools/vnet/vnet-module/etherip.c | 43 tools/vnet/vnet-module/tunnel.c | 7 tools/vnet/vnet-module/tunnel.h | 8 tools/vnet/vnet-module/varp.c | 9 tools/vnet/vnet-module/varp_socket.c | 76 tools/vnet/vnet-module/vif.c | 1 tools/vnet/vnet-module/vnet.c | 13 tools/vnet/vnet-module/vnet_dev.c | 12 tools/vnet/vnet-module/vnet_eval.c | 2 tools/vnet/vnet-module/vnet_forward.c | 1 tools/vnet/vnetd/Makefile | 4 tools/vnet/vnetd/vnetd.c | 34 tools/xm-test/tests/vtpm/vtpm_utils.py | 6 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 6 xen/Makefile | 22 xen/arch/ia64/Makefile | 15 xen/arch/ia64/xen/domain.c | 6 xen/arch/ia64/xen/xensetup.c | 10 xen/arch/powerpc/Makefile | 3 xen/arch/powerpc/setup.c | 3 xen/arch/x86/Makefile | 24 xen/arch/x86/Rules.mk | 2 xen/arch/x86/acpi/boot.c | 81 xen/arch/x86/apic.c | 95 - xen/arch/x86/boot/x86_32.S | 26 xen/arch/x86/boot/x86_64.S | 49 xen/arch/x86/domain.c | 11 xen/arch/x86/hvm/Makefile | 1 xen/arch/x86/hvm/hvm.c | 158 + xen/arch/x86/hvm/i8259.c | 122 - xen/arch/x86/hvm/instrlen.c | 450 +++++ xen/arch/x86/hvm/intercept.c | 16 xen/arch/x86/hvm/io.c | 7 xen/arch/x86/hvm/platform.c | 103 - xen/arch/x86/hvm/svm/Makefile | 1 xen/arch/x86/hvm/svm/emulate.c | 6 xen/arch/x86/hvm/svm/intr.c | 12 xen/arch/x86/hvm/svm/svm.c | 241 +- xen/arch/x86/hvm/svm/x86_32/exits.S | 3 xen/arch/x86/hvm/svm/x86_64/exits.S | 1 xen/arch/x86/hvm/vioapic.c | 22 xen/arch/x86/hvm/vlapic.c | 4 xen/arch/x86/hvm/vmx/io.c | 22 xen/arch/x86/hvm/vmx/vmcs.c | 135 + xen/arch/x86/hvm/vmx/vmx.c | 471 ++--- xen/arch/x86/hvm/vmx/x86_32/exits.S | 3 xen/arch/x86/hvm/vmx/x86_64/exits.S | 1 xen/arch/x86/io_apic.c | 8 xen/arch/x86/irq.c | 12 xen/arch/x86/microcode.c | 11 xen/arch/x86/mm.c | 245 +- xen/arch/x86/mm/shadow/common.c | 188 -- xen/arch/x86/mm/shadow/multi.c | 451 +++-- xen/arch/x86/mm/shadow/multi.h | 7 xen/arch/x86/mm/shadow/private.h | 49 xen/arch/x86/mm/shadow/types.h | 31 xen/arch/x86/mpparse.c | 61 xen/arch/x86/platform_hypercall.c | 16 xen/arch/x86/setup.c | 10 xen/arch/x86/smp.c | 2 xen/arch/x86/smpboot.c | 2 xen/arch/x86/traps.c | 2 xen/arch/x86/x86_32/asm-offsets.c | 1 xen/arch/x86/x86_32/entry.S | 20 xen/arch/x86/x86_64/asm-offsets.c | 1 xen/arch/x86/x86_64/entry.S | 2 xen/arch/x86/x86_emulate.c | 37 xen/common/domain.c | 6 xen/common/domctl.c | 43 xen/common/elf.c | 2 xen/common/gdbstub.c | 83 xen/common/grant_table.c | 2 xen/common/sched_credit.c | 43 xen/common/sched_sedf.c | 15 xen/common/schedule.c | 76 xen/common/shutdown.c | 3 xen/common/symbols-dummy.c | 16 xen/common/symbols.c | 13 xen/drivers/acpi/tables.c | 473 ++--- xen/drivers/char/console.c | 36 xen/include/asm-x86/apicdef.h | 1 xen/include/asm-x86/debugger.h | 44 xen/include/asm-x86/domain.h | 2 xen/include/asm-x86/guest_access.h | 20 xen/include/asm-x86/hvm/hvm.h | 25 xen/include/asm-x86/hvm/io.h | 1 xen/include/asm-x86/hvm/support.h | 22 xen/include/asm-x86/hvm/svm/emulate.h | 32 xen/include/asm-x86/hvm/vioapic.h | 2 xen/include/asm-x86/hvm/vmx/vmcs.h | 27 xen/include/asm-x86/hvm/vmx/vmx.h | 157 - xen/include/asm-x86/hvm/vpic.h | 8 xen/include/asm-x86/io_apic.h | 1 xen/include/asm-x86/mm.h | 24 xen/include/asm-x86/multicall.h | 2 xen/include/asm-x86/shadow.h | 101 + xen/include/public/io/ring.h | 2 xen/include/xen/compiler.h | 2 xen/include/xen/console.h | 9 xen/include/xen/gdbstub.h | 3 xen/include/xen/keyhandler.h | 3 xen/include/xen/sched-if.h | 2 xen/include/xen/sched.h | 19 263 files changed, 6064 insertions(+), 10665 deletions(-) diff -r e7cb3aefc233 -r b53c343b47ae .hgignore --- a/.hgignore Wed Oct 11 13:01:31 2006 -0400 +++ b/.hgignore Wed Oct 11 13:04:07 2006 -0400 @@ -139,12 +139,15 @@ ^tools/security/secpol_tool$ ^tools/security/xen/.*$ ^tools/tests/test_x86_emulator$ +^tools/vnet/Make.local$ +^tools/vnet/build/.*$ ^tools/vnet/gc$ ^tools/vnet/gc.*/.*$ ^tools/vnet/vnet-module/.*\.ko$ ^tools/vnet/vnet-module/\..*\.cmd$ ^tools/vnet/vnet-module/\.tmp_versions/.*$ ^tools/vnet/vnet-module/vnet_module\.mod\..*$ +^tools/vnet/vnetd/vnetd$ ^tools/vtpm/tpm_emulator-.*\.tar\.gz$ ^tools/vtpm/tpm_emulator/.*$ ^tools/vtpm/vtpm/.*$ diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen0_ia64 --- a/buildconfigs/linux-defconfig_xen0_ia64 Wed Oct 11 13:01:31 2006 -0400 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Wed Oct 11 13:04:07 2006 -0400 @@ -1040,6 +1040,7 @@ CONFIG_SND_ATIIXP=y # CONFIG_SND_ES1938 is not set # CONFIG_SND_ES1968 is not set CONFIG_SND_FM801=y +# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDSP is not set diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xenU_ia64 --- a/buildconfigs/linux-defconfig_xenU_ia64 Wed Oct 11 13:01:31 2006 -0400 +++ b/buildconfigs/linux-defconfig_xenU_ia64 Wed Oct 11 13:04:07 2006 -0400 @@ -939,6 +939,7 @@ CONFIG_SND_AC97_BUS=y # CONFIG_SND_ES1938 is not set # CONFIG_SND_ES1968 is not set CONFIG_SND_FM801=y +# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDSP is not set diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_ia64 --- a/buildconfigs/linux-defconfig_xen_ia64 Wed Oct 11 13:01:31 2006 -0400 +++ b/buildconfigs/linux-defconfig_xen_ia64 Wed Oct 11 13:04:07 2006 -0400 @@ -1046,6 +1046,7 @@ CONFIG_SND_ATIIXP=y # CONFIG_SND_ES1938 is not set # CONFIG_SND_ES1968 is not set CONFIG_SND_FM801=y +# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDSP is not set diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_x86_32 --- a/buildconfigs/linux-defconfig_xen_x86_32 Wed Oct 11 13:01:31 2006 -0400 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Wed Oct 11 13:04:07 2006 -0400 @@ -2377,6 +2377,7 @@ CONFIG_SND_ES1938=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m +# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_x86_64 --- a/buildconfigs/linux-defconfig_xen_x86_64 Wed Oct 11 13:01:31 2006 -0400 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Wed Oct 11 13:04:07 2006 -0400 @@ -2237,6 +2237,7 @@ CONFIG_SND_ES1938=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m +# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m diff -r e7cb3aefc233 -r b53c343b47ae docs/man/xm.pod.1 --- a/docs/man/xm.pod.1 Wed Oct 11 13:01:31 2006 -0400 +++ b/docs/man/xm.pod.1 Wed Oct 11 13:04:07 2006 -0400 @@ -393,7 +393,9 @@ specified, VCPU information for all doma =item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus> -Pins the the VCPU to only run on the specific CPUs. +Pins the the VCPU to only run on the specific CPUs. The keyword +I<all> can be used to apply the I<cpus> list to all VCPUs in the +domain. Normally VCPUs can float between available CPUs whenever Xen deems a different run state is appropriate. Pinning can be used to restrict diff -r e7cb3aefc233 -r b53c343b47ae docs/src/user.tex --- a/docs/src/user.tex Wed Oct 11 13:01:31 2006 -0400 +++ b/docs/src/user.tex Wed Oct 11 13:04:07 2006 -0400 @@ -3208,6 +3208,8 @@ editing \path{grub.conf}. respectively; if no suffix is specified, the parameter defaults to kilobytes. In previous versions of Xen, suffixes were not supported and the value is always interpreted as kilobytes. +\item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective + physical CPUS (default=false). \item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in pages (default 0). \item [ sched=xxx ] Select the CPU scheduler Xen should use. The diff -r e7cb3aefc233 -r b53c343b47ae extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Wed Oct 11 13:01:31 2006 -0400 +++ b/extras/mini-os/include/x86/os.h Wed Oct 11 13:04:07 2006 -0400 @@ -60,6 +60,11 @@ extern shared_info_t *HYPERVISOR_shared_ extern shared_info_t *HYPERVISOR_shared_info; void trap_init(void); + +void arch_init(start_info_t *si); +void arch_print_info(void); + + diff -r e7cb3aefc233 -r b53c343b47ae extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Wed Oct 11 13:01:31 2006 -0400 +++ b/extras/mini-os/kernel.c Wed Oct 11 13:04:07 2006 -0400 @@ -38,49 +38,6 @@ #include <gnttab.h> #include <xen/features.h> #include <xen/version.h> - -/* - * Shared page for communicating with the hypervisor. - * Events flags go here, for example. - */ -shared_info_t *HYPERVISOR_shared_info; - -/* - * This structure contains start-of-day info, such as pagetable base pointer, - * address of the shared_info structure, and things like that. - */ -union start_info_union start_info_union; - -/* - * Just allocate the kernel stack here. SS:ESP is set up to point here - * in head.S. - */ -char stack[8192]; - - -/* Assembler interface fns in entry.S. */ -void hypervisor_callback(void); -void failsafe_callback(void); - -extern char shared_info[PAGE_SIZE]; - -#if !defined(CONFIG_X86_PAE) -#define __pte(x) ((pte_t) { (x) } ) -#else -#define __pte(x) ({ unsigned long long _x = (x); \ - ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); }) -#endif - -static shared_info_t *map_shared_info(unsigned long pa) -{ - if ( HYPERVISOR_update_va_mapping( - (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) ) - { - printk("Failed to map shared_info!!\n"); - do_exit(); - } - return (shared_info_t *)shared_info; -} u8 xen_features[XENFEAT_NR_SUBMAPS * 32]; @@ -126,27 +83,8 @@ void start_kernel(start_info_t *si) (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello); - /* Copy the start_info struct to a globally-accessible area. */ - /* WARN: don't do printk before here, it uses information from - shared_info. Use xprintk instead. */ - memcpy(&start_info, si, sizeof(*si)); - - /* set up minimal memory infos */ - phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; + arch_init(si); - /* Grab the shared_info pointer and put it in a safe place. */ - HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); - - /* Set up event and failsafe callback addresses. */ -#ifdef __i386__ - HYPERVISOR_set_callbacks( - __KERNEL_CS, (unsigned long)hypervisor_callback, - __KERNEL_CS, (unsigned long)failsafe_callback); -#else - HYPERVISOR_set_callbacks( - (unsigned long)hypervisor_callback, - (unsigned long)failsafe_callback, 0); -#endif trap_init(); /* ENABLE EVENT DELIVERY. This is disabled at start of day. */ @@ -163,7 +101,8 @@ void start_kernel(start_info_t *si) printk(" flags: 0x%x\n", (unsigned int)si->flags); printk(" cmd_line: %s\n", si->cmd_line ? (const char *)si->cmd_line : "NULL"); - printk(" stack: %p-%p\n", stack, stack + 8192); + + arch_print_info(); setup_xen_features(); diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Oct 11 13:04:07 2006 -0400 @@ -156,6 +156,9 @@ EXPORT_SYMBOL(ist_info); EXPORT_SYMBOL(ist_info); #endif struct e820map e820; +#ifdef CONFIG_XEN +struct e820map machine_e820; +#endif extern void early_cpu_init(void); extern void generic_apic_probe(char *); @@ -1451,7 +1454,6 @@ static void __init register_memory(void) static void __init register_memory(void) { #ifdef CONFIG_XEN - struct e820entry *machine_e820; struct xen_memory_map memmap; #endif int i; @@ -1461,14 +1463,14 @@ static void __init register_memory(void) return; #ifdef CONFIG_XEN - machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE); - memmap.nr_entries = E820MAX; - set_xen_guest_handle(memmap.buffer, machine_e820); - - BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)); - - legacy_init_iomem_resources(machine_e820, memmap.nr_entries, + set_xen_guest_handle(memmap.buffer, machine_e820.map); + + if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)) + BUG(); + machine_e820.nr_map = memmap.nr_entries; + + legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map, &code_resource, &data_resource); #else if (efi_enabled) @@ -1486,8 +1488,7 @@ static void __init register_memory(void) request_resource(&ioport_resource, &standard_io_resources[i]); #ifdef CONFIG_XEN - e820_setup_gap(machine_e820, memmap.nr_entries); - free_bootmem(__pa(machine_e820), PAGE_SIZE); + e820_setup_gap(machine_e820.map, machine_e820.nr_map); #else e820_setup_gap(e820.map, e820.nr_map); #endif diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Wed Oct 11 13:04:07 2006 -0400 @@ -28,6 +28,8 @@ static int direct_remap_area_pte_fn(pte_ void *data) { mmu_update_t **v = (mmu_update_t **)data; + + BUG_ON(!pte_none(*pte)); (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) << PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK); @@ -110,11 +112,13 @@ int direct_remap_pfn_range(struct vm_are pgprot_t prot, domid_t domid) { - /* Same as remap_pfn_range(). */ - vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + if (xen_feature(XENFEAT_auto_translated_physmap)) + return remap_pfn_range(vma, address, mfn, size, prot); if (domid == DOMID_SELF) return -EINVAL; + + vma->vm_flags |= VM_IO | VM_RESERVED; vma->vm_mm->context.has_foreign_mappings = 1; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed Oct 11 13:04:07 2006 -0400 @@ -350,7 +350,6 @@ static inline void set_32bit_tls(struct struct user_desc ud = { .base_addr = addr, .limit = 0xfffff, - .contents = (3 << 3), /* user */ .seg_32bit = 1, .limit_in_pages = 1, .useable = 1, diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Wed Oct 11 13:04:07 2006 -0400 @@ -144,6 +144,9 @@ struct sys_desc_table_struct { struct edid_info edid_info; struct e820map e820; +#ifdef CONFIG_XEN +struct e820map machine_e820; +#endif extern int root_mountflags; @@ -626,7 +629,6 @@ void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p) { unsigned long kernel_end; - struct e820entry *machine_e820; struct xen_memory_map memmap; #ifdef CONFIG_XEN @@ -919,14 +921,14 @@ void __init setup_arch(char **cmdline_p) probe_roms(); #ifdef CONFIG_XEN if (is_initial_xendomain()) { - machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE); - memmap.nr_entries = E820MAX; - set_xen_guest_handle(memmap.buffer, machine_e820); - - BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)); - - e820_reserve_resources(machine_e820, memmap.nr_entries); + set_xen_guest_handle(memmap.buffer, machine_e820.map); + + if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)) + BUG(); + machine_e820.nr_map = memmap.nr_entries; + + e820_reserve_resources(machine_e820.map, machine_e820.nr_map); } #else e820_reserve_resources(e820.map, e820.nr_map); @@ -942,10 +944,8 @@ void __init setup_arch(char **cmdline_p) } #ifdef CONFIG_XEN - if (is_initial_xendomain()) { - e820_setup_gap(machine_e820, memmap.nr_entries); - free_bootmem(__pa(machine_e820), PAGE_SIZE); - } + if (is_initial_xendomain()) + e820_setup_gap(machine_e820.map, machine_e820.nr_map); #else e820_setup_gap(e820.map, e820.nr_map); #endif diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Oct 11 13:04:07 2006 -0400 @@ -534,74 +534,86 @@ static int dealloc_pte_fn( return 0; } -struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) -{ - unsigned long vstart, flags; - unsigned int order = get_order(nr_pages * PAGE_SIZE); - int ret; - unsigned long i; - struct page *page; - - vstart = __get_free_pages(GFP_KERNEL, order); - if (vstart == 0) +struct page **alloc_empty_pages_and_pagevec(int nr_pages) +{ + unsigned long vaddr, flags; + struct page *page, **pagevec; + int i, ret; + + pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL); + if (pagevec == NULL) return NULL; - scrub_pages(vstart, 1 << order); - + for (i = 0; i < nr_pages; i++) { + page = pagevec[i] = alloc_page(GFP_KERNEL); + if (page == NULL) + goto err; + + vaddr = (unsigned long)page_address(page); + + scrub_pages(vaddr, 1); + + balloon_lock(flags); + + if (xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned long gmfn = page_to_pfn(page); + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + set_xen_guest_handle(reservation.extent_start, &gmfn); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + if (ret == 1) + ret = 0; /* success */ + } else { + ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE, + dealloc_pte_fn, NULL); + } + + if (ret != 0) { + balloon_unlock(flags); + __free_page(page); + goto err; + } + + totalram_pages = --current_pages; + + balloon_unlock(flags); + } + + out: + schedule_work(&balloon_worker); + flush_tlb_all(); + return pagevec; + + err: balloon_lock(flags); - if (xen_feature(XENFEAT_auto_translated_physmap)) { - unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT; - struct xen_memory_reservation reservation = { - .nr_extents = 1, - .extent_order = order, - .domid = DOMID_SELF - }; - set_xen_guest_handle(reservation.extent_start, &gmfn); - ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation); - if (ret == -ENOSYS) - goto err; - BUG_ON(ret != 1); - } else { - ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order, - dealloc_pte_fn, NULL); - if (ret == -ENOSYS) - goto err; - BUG_ON(ret); - } - current_pages -= 1UL << order; - totalram_pages = current_pages; + while (--i >= 0) + balloon_append(pagevec[i]); balloon_unlock(flags); - - schedule_work(&balloon_worker); - - flush_tlb_all(); - - page = virt_to_page(vstart); - - for (i = 0; i < (1UL << order); i++) - set_page_count(page + i, 1); - - return page; - - err: - free_pages(vstart, order); + kfree(pagevec); + pagevec = NULL; + goto out; +} + +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages) +{ + unsigned long flags; + int i; + + if (pagevec == NULL) + return; + + balloon_lock(flags); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page_count(pagevec[i]) != 1); + balloon_append(pagevec[i]); + } balloon_unlock(flags); - return NULL; -} - -void balloon_dealloc_empty_page_range( - struct page *page, unsigned long nr_pages) -{ - unsigned long i, flags; - unsigned int order = get_order(nr_pages * PAGE_SIZE); - - balloon_lock(flags); - for (i = 0; i < (1UL << order); i++) { - BUG_ON(page_count(page + i) != 1); - balloon_append(page + i); - } - balloon_unlock(flags); + + kfree(pagevec); schedule_work(&balloon_worker); } @@ -619,8 +631,8 @@ void balloon_release_driver_page(struct } EXPORT_SYMBOL_GPL(balloon_update_driver_allowance); -EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range); -EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range); +EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec); +EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec); EXPORT_SYMBOL_GPL(balloon_release_driver_page); MODULE_LICENSE("Dual BSD/GPL"); diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Oct 11 13:04:07 2006 -0400 @@ -55,8 +55,6 @@ static int blkif_reqs = 64; static int blkif_reqs = 64; module_param_named(reqs, blkif_reqs, int, 0); MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); - -static int mmap_pages; /* Run-time switchable: /sys/module/blkback/parameters/ */ static unsigned int log_stats = 0; @@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_f #define BLKBACK_INVALID_HANDLE (~0) -static unsigned long mmap_vstart; -static unsigned long *pending_vaddrs; +static struct page **pending_pages; static grant_handle_t *pending_grant_handles; static inline int vaddr_pagenr(pending_req_t *req, int seg) @@ -98,7 +95,8 @@ static inline int vaddr_pagenr(pending_r static inline unsigned long vaddr(pending_req_t *req, int seg) { - return pending_vaddrs[vaddr_pagenr(req, seg)]; + unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]); + return (unsigned long)pfn_to_kaddr(pfn); } #define pending_handle(_req, _seg) \ @@ -506,52 +504,43 @@ static void make_response(blkif_t *blkif static int __init blkif_init(void) { - struct page *page; - int i; + int i, mmap_pages; if (!is_running_on_xen()) return -ENODEV; - mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; - - page = balloon_alloc_empty_page_range(mmap_pages); - if (page == NULL) - return -ENOMEM; - mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; pending_reqs = kmalloc(sizeof(pending_reqs[0]) * blkif_reqs, GFP_KERNEL); pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * mmap_pages, GFP_KERNEL); - pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) * - mmap_pages, GFP_KERNEL); - if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) { - kfree(pending_reqs); - kfree(pending_grant_handles); - kfree(pending_vaddrs); - printk("%s: out of memory\n", __FUNCTION__); - return -ENOMEM; - } + pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); + + if (!pending_reqs || !pending_grant_handles || !pending_pages) + goto out_of_memory; + + for (i = 0; i < mmap_pages; i++) + pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; blkif_interface_init(); - - printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n", - __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart); - BUG_ON(mmap_vstart == 0); - for (i = 0; i < mmap_pages; i++) { - pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT); - pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; - } memset(pending_reqs, 0, sizeof(pending_reqs)); INIT_LIST_HEAD(&pending_free); for (i = 0; i < blkif_reqs; i++) list_add_tail(&pending_reqs[i].free_list, &pending_free); - + blkif_xenbus_init(); return 0; + + out_of_memory: + kfree(pending_reqs); + kfree(pending_grant_handles); + free_empty_pages_and_pagevec(pending_pages, mmap_pages); + printk("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; } module_init(blkif_init); diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 11 13:04:07 2006 -0400 @@ -273,7 +273,7 @@ static void backend_changed(struct xenbu xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); down(&bd->bd_sem); - if (info->users > 0 && system_state == SYSTEM_RUNNING) + if (info->users > 0) xenbus_dev_error(dev, -EBUSY, "Device in use; refusing to close"); else @@ -355,8 +355,10 @@ static void blkfront_closing(struct xenb blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); + spin_unlock_irqrestore(&blkif_io_lock, flags); + + /* Flush gnttab callback work. Must be done with no locks held. */ flush_scheduled_work(); - spin_unlock_irqrestore(&blkif_io_lock, flags); xlvbd_del(info); @@ -714,8 +716,10 @@ static void blkif_free(struct blkfront_i blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); + spin_unlock_irq(&blkif_io_lock); + + /* Flush gnttab callback work. Must be done with no locks held. */ flush_scheduled_work(); - spin_unlock_irq(&blkif_io_lock); /* Free resources associated with old device channel. */ if (info->ring_ref != GRANT_INVALID_REF) { diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Oct 11 13:04:07 2006 -0400 @@ -44,7 +44,6 @@ #include <linux/kernel.h> #include <linux/fs.h> #include <linux/mm.h> -#include <linux/miscdevice.h> #include <linux/errno.h> #include <linux/major.h> #include <linux/gfp.h> @@ -54,6 +53,30 @@ #define MAX_TAP_DEV 100 /*the maximum number of tapdisk ring devices */ #define MAX_DEV_NAME 100 /*the max tapdisk ring device name e.g. blktap0 */ + + +struct class *xen_class; +EXPORT_SYMBOL_GPL(xen_class); + +/* + * Setup the xen class. This should probably go in another file, but + * since blktap is the only user of it so far, it gets to keep it. + */ +int setup_xen_class(void) +{ + int ret; + + if (xen_class) + return 0; + + xen_class = class_create(THIS_MODULE, "xen"); + if ((ret = IS_ERR(xen_class))) { + xen_class = NULL; + return ret; + } + + return 0; +} /* * The maximum number of requests that can be outstanding at any time @@ -100,19 +123,14 @@ typedef struct tap_blkif { unsigned long *idx_map; /*Record the user ring id to kern [req id, idx] tuple */ blkif_t *blkif; /*Associate blkif with tapdev */ + int sysfs_set; /*Set if it has a class device. */ } tap_blkif_t; - -/*Private data struct associated with the inode*/ -typedef struct private_info { - int idx; -} private_info_t; /*Data struct handed back to userspace for tapdisk device to VBD mapping*/ typedef struct domid_translate { unsigned short domid; unsigned short busid; } domid_translate_t ; - static domid_translate_t translate_domid[MAX_TAP_DEV]; static tap_blkif_t *tapfds[MAX_TAP_DEV]; @@ -168,16 +186,18 @@ static inline unsigned int RTN_PEND_IDX( #define BLKBACK_INVALID_HANDLE (~0) -typedef struct mmap_page { - unsigned long start; - struct page *mpage; -} mmap_page_t; - -static mmap_page_t mmap_start[MAX_DYNAMIC_MEM]; +static struct page **foreign_pages[MAX_DYNAMIC_MEM]; +static inline unsigned long idx_to_kaddr( + unsigned int mmap_idx, unsigned int req_idx, unsigned int sg_idx) +{ + unsigned int arr_idx = req_idx*BLKIF_MAX_SEGMENTS_PER_REQUEST + sg_idx; + unsigned long pfn = page_to_pfn(foreign_pages[mmap_idx][arr_idx]); + return (unsigned long)pfn_to_kaddr(pfn); +} + static unsigned short mmap_alloc = 0; static unsigned short mmap_lock = 0; static unsigned short mmap_inuse = 0; -static unsigned long *pending_addrs[MAX_DYNAMIC_MEM]; /****************************************************************** * GRANT HANDLES @@ -200,14 +220,12 @@ static struct grant_handle_pair + (_i)]) -static int blktap_read_ufe_ring(int idx); /*local prototypes*/ - -#define BLKTAP_MINOR 0 /*/dev/xen/blktap resides at device number - major=254, minor numbers begin at 0 */ -#define BLKTAP_DEV_MAJOR 254 /* TODO: Make major number dynamic * - * and create devices in the kernel * - */ +static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/ + +#define BLKTAP_MINOR 0 /*/dev/xen/blktap has a dynamic major */ #define BLKTAP_DEV_DIR "/dev/xen" + +static int blktap_major; /* blktap IOCTLs: */ #define BLKTAP_IOCTL_KICK_FE 1 @@ -264,7 +282,8 @@ static inline int GET_NEXT_REQ(unsigned { int i; for (i = 0; i < MAX_PENDING_REQS; i++) - if (idx_map[i] == INVALID_REQ) return i; + if (idx_map[i] == INVALID_REQ) + return i; return INVALID_REQ; } @@ -311,8 +330,6 @@ static int blktap_ioctl(struct inode *in unsigned int cmd, unsigned long arg); static unsigned int blktap_poll(struct file *file, poll_table *wait); -struct miscdevice *set_misc(int minor, char *name, int dev); - static struct file_operations blktap_fops = { .owner = THIS_MODULE, .poll = blktap_poll, @@ -344,6 +361,16 @@ static int get_next_free_dev(void) done: spin_unlock_irqrestore(&pending_free_lock, flags); + + /* + * We are protected by having the dev_pending set. + */ + if (!tapfds[i]->sysfs_set && xen_class) { + class_device_create(xen_class, NULL, + MKDEV(blktap_major, ret), NULL, + "blktap%d", ret); + tapfds[i]->sysfs_set = 1; + } return ret; } @@ -369,9 +396,8 @@ void signal_tapdisk(int idx) info = tapfds[idx]; if ( (idx > 0) && (idx < MAX_TAP_DEV) && (info->pid > 0) ) { ptask = find_task_by_pid(info->pid); - if (ptask) { + if (ptask) info->status = CLEANSHUTDOWN; - } } info->blkif = NULL; return; @@ -382,7 +408,6 @@ static int blktap_open(struct inode *ino blkif_sring_t *sring; int idx = iminor(inode) - BLKTAP_MINOR; tap_blkif_t *info; - private_info_t *prv; int i; if (tapfds[idx] == NULL) { @@ -410,9 +435,7 @@ static int blktap_open(struct inode *ino SHARED_RING_INIT(sring); FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE); - prv = kzalloc(sizeof(private_info_t),GFP_KERNEL); - prv->idx = idx; - filp->private_data = prv; + filp->private_data = info; info->vma = NULL; info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, @@ -433,17 +456,16 @@ static int blktap_open(struct inode *ino static int blktap_release(struct inode *inode, struct file *filp) { - int idx = iminor(inode) - BLKTAP_MINOR; - tap_blkif_t *info; - - if (tapfds[idx] == NULL) { + tap_blkif_t *info = filp->private_data; + + /* can this ever happen? - sdr */ + if (!info) { WPRINTK("Trying to free device that doesn't exist " - "[/dev/xen/blktap%d]\n",idx); - return -1; - } - info = tapfds[idx]; + "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR); + return -EBADF; + } info->dev_inuse = 0; - DPRINTK("Freeing device [/dev/xen/blktap%d]\n",idx); + DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor); /* Free the ring page. */ ClearPageReserved(virt_to_page(info->ufe_ring.sring)); @@ -457,8 +479,6 @@ static int blktap_release(struct inode * info->vma = NULL; } - if (filp->private_data) kfree(filp->private_data); - if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) { kthread_stop(info->blkif->xenblkd); info->blkif->xenblkd = NULL; @@ -491,16 +511,12 @@ static int blktap_mmap(struct file *filp int size; struct page **map; int i; - private_info_t *prv; - tap_blkif_t *info; - - /*Retrieve the dev info*/ - prv = (private_info_t *)filp->private_data; - if (prv == NULL) { + tap_blkif_t *info = filp->private_data; + + if (info == NULL) { WPRINTK("blktap: mmap, retrieving idx failed\n"); return -ENOMEM; } - info = tapfds[prv->idx]; vma->vm_flags |= VM_RESERVED; vma->vm_ops = &blktap_vm_ops; @@ -556,20 +572,17 @@ static int blktap_ioctl(struct inode *in static int blktap_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - int idx = iminor(inode) - BLKTAP_MINOR; + tap_blkif_t *info = filp->private_data; + switch(cmd) { case BLKTAP_IOCTL_KICK_FE: { /* There are fe messages to process. */ - return blktap_read_ufe_ring(idx); + return blktap_read_ufe_ring(info); } case BLKTAP_IOCTL_SETMODE: { - tap_blkif_t *info = tapfds[idx]; - - if ( (idx > 0) && (idx < MAX_TAP_DEV) - && (tapfds[idx] != NULL) ) - { + if (info) { if (BLKTAP_MODE_VALID(arg)) { info->mode = arg; /* XXX: may need to flush rings here. */ @@ -582,11 +595,7 @@ static int blktap_ioctl(struct inode *in } case BLKTAP_IOCTL_PRINT_IDXS: { - tap_blkif_t *info = tapfds[idx]; - - if ( (idx > 0) && (idx < MAX_TAP_DEV) - && (tapfds[idx] != NULL) ) - { + if (info) { printk("User Rings: \n-----------\n"); printk("UF: rsp_cons: %2d, req_prod_prv: %2d " "| req_prod: %2d, rsp_prod: %2d\n", @@ -599,11 +608,7 @@ static int blktap_ioctl(struct inode *in } case BLKTAP_IOCTL_SENDPID: { - tap_blkif_t *info = tapfds[idx]; - - if ( (idx > 0) && (idx < MAX_TAP_DEV) - && (tapfds[idx] != NULL) ) - { + if (info) { info->pid = (pid_t)arg; DPRINTK("blktap: pid received %d\n", info->pid); @@ -631,26 +636,38 @@ static int blktap_ioctl(struct inode *in case BLKTAP_IOCTL_FREEINTF: { unsigned long dev = arg; - tap_blkif_t *info = NULL; - - if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev]; - + unsigned long flags; + + /* Looking at another device */ + info = NULL; + + if ( (dev > 0) && (dev < MAX_TAP_DEV) ) + info = tapfds[dev]; + + spin_lock_irqsave(&pending_free_lock, flags); if ( (info != NULL) && (info->dev_pending) ) info->dev_pending = 0; + spin_unlock_irqrestore(&pending_free_lock, flags); + return 0; } case BLKTAP_IOCTL_MINOR: { unsigned long dev = arg; - tap_blkif_t *info = NULL; + + /* Looking at another device */ + info = NULL; - if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev]; + if ( (dev > 0) && (dev < MAX_TAP_DEV) ) + info = tapfds[dev]; - if (info != NULL) return info->minor; - else return -1; + if (info != NULL) + return info->minor; + else + return -1; } case BLKTAP_IOCTL_MAJOR: - return BLKTAP_DEV_MAJOR; + return blktap_major; case BLKTAP_QUERY_ALLOC_REQS: { @@ -662,25 +679,21 @@ static int blktap_ioctl(struct inode *in return -ENOIOCTLCMD; } -static unsigned int blktap_poll(struct file *file, poll_table *wait) -{ - private_info_t *prv; - tap_blkif_t *info; - - /*Retrieve the dev info*/ - prv = (private_info_t *)file->private_data; - if (prv == NULL) { +static unsigned int blktap_poll(struct file *filp, poll_table *wait) +{ + tap_blkif_t *info = filp->private_data; + + if (!info) { WPRINTK(" poll, retrieving idx failed\n"); return 0; } - - if (prv->idx == 0) return 0; - - info = tapfds[prv->idx]; - - poll_wait(file, &info->wait, wait); + + /* do not work on the control device */ + if (!info->minor) + return 0; + + poll_wait(filp, &info->wait, wait); if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) { - flush_tlb_all(); RING_PUSH_REQUESTS(&info->ufe_ring); return POLLIN | POLLRDNORM; } @@ -691,11 +704,14 @@ void blktap_kick_user(int idx) { tap_blkif_t *info; - if (idx == 0) return; + if (idx == 0) + return; info = tapfds[idx]; - if (info != NULL) wake_up_interruptible(&info->wait); + if (info != NULL) + wake_up_interruptible(&info->wait); + return; } @@ -712,66 +728,21 @@ static int req_increase(void) static int req_increase(void) { int i, j; - struct page *page; - unsigned long flags; - int ret; - - spin_lock_irqsave(&pending_free_lock, flags); - - ret = -EINVAL; + if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) - goto done; - -#ifdef __ia64__ - extern unsigned long alloc_empty_foreign_map_page_range( - unsigned long pages); - mmap_start[mmap_alloc].start = (unsigned long) - alloc_empty_foreign_map_page_range(mmap_pages); -#else /* ! ia64 */ - page = balloon_alloc_empty_page_range(mmap_pages); - ret = -ENOMEM; - if (page == NULL) { - printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__); - goto done; - } - - /* Pin all of the pages. */ - for (i=0; i<mmap_pages; i++) - get_page(&page[i]); - - mmap_start[mmap_alloc].start = - (unsigned long)pfn_to_kaddr(page_to_pfn(page)); - mmap_start[mmap_alloc].mpage = page; - -#endif - - pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) * - blkif_reqs, GFP_KERNEL); - pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) * - mmap_pages, GFP_KERNEL); - - ret = -ENOMEM; - if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) { - kfree(pending_reqs[mmap_alloc]); - kfree(pending_addrs[mmap_alloc]); - WPRINTK("%s: out of memory\n", __FUNCTION__); - ret = -ENOMEM; - goto done; - } - - ret = 0; - - DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n", - __FUNCTION__, blkif_reqs, mmap_pages, - mmap_start[mmap_alloc].start); - - BUG_ON(mmap_start[mmap_alloc].start == 0); - - for (i = 0; i < mmap_pages; i++) - pending_addrs[mmap_alloc][i] = - mmap_start[mmap_alloc].start + (i << PAGE_SHIFT); - - for (i = 0; i < MAX_PENDING_REQS ; i++) { + return -EINVAL; + + pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) + * blkif_reqs, GFP_KERNEL); + foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages); + + if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc]) + goto out_of_memory; + + DPRINTK("%s: reqs=%d, pages=%d\n", + __FUNCTION__, blkif_reqs, mmap_pages); + + for (i = 0; i < MAX_PENDING_REQS; i++) { list_add_tail(&pending_reqs[mmap_alloc][i].free_list, &pending_free); pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc; @@ -782,65 +753,28 @@ static int req_increase(void) mmap_alloc++; DPRINTK("# MMAPs increased to %d\n",mmap_alloc); - done: - spin_unlock_irqrestore(&pending_free_lock, flags); - return ret; + return 0; + + out_of_memory: + free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages); + kfree(pending_reqs[mmap_alloc]); + WPRINTK("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; } static void mmap_req_del(int mmap) { - int i; - struct page *page; - - /*Spinlock already acquired*/ + BUG_ON(!spin_is_locked(&pending_free_lock)); + kfree(pending_reqs[mmap]); - kfree(pending_addrs[mmap]); - -#ifdef __ia64__ - /*Not sure what goes here yet!*/ -#else - - /* Unpin all of the pages. */ - page = mmap_start[mmap].mpage; - for (i=0; i<mmap_pages; i++) - put_page(&page[i]); - - balloon_dealloc_empty_page_range(mmap_start[mmap].mpage, mmap_pages); -#endif + pending_reqs[mmap] = NULL; + + free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages); + foreign_pages[mmap] = NULL; mmap_lock = 0; DPRINTK("# MMAPs decreased to %d\n",mmap_alloc); mmap_alloc--; -} - -/*N.B. Currently unused - will be accessed via sysfs*/ -static void req_decrease(void) -{ - pending_req_t *req; - int i; - unsigned long flags; - - spin_lock_irqsave(&pending_free_lock, flags); - - DPRINTK("Req decrease called.\n"); - if (mmap_lock || mmap_alloc == 1) - goto done; - - mmap_lock = 1; - mmap_inuse = MAX_PENDING_REQS; - - /*Go through reqs and remove any that aren't in use*/ - for (i = 0; i < MAX_PENDING_REQS ; i++) { - req = &pending_reqs[mmap_alloc-1][i]; - if (req->inuse == 0) { - list_del(&req->free_list); - mmap_inuse--; - } - } - if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1); - done: - spin_unlock_irqrestore(&pending_free_lock, flags); - return; } static pending_req_t* alloc_req(void) @@ -907,7 +841,7 @@ static void fast_flush_area(pending_req_ mmap_idx = req->mem_idx; for (i = 0; i < req->nr_pages; i++) { - kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i); + kvaddr = idx_to_kaddr(mmap_idx, k_idx, i); uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i); khandle = &pending_handle(mmap_idx, k_idx, i); @@ -916,7 +850,7 @@ static void fast_flush_area(pending_req_ continue; } gnttab_set_unmap_op(&unmap[invcount], - MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i), + idx_to_kaddr(mmap_idx, k_idx, i), GNTMAP_host_map, khandle->kernel); invcount++; @@ -1002,7 +936,7 @@ int tap_blkif_schedule(void *arg) * COMPLETION CALLBACK -- Called by user level ioctl() */ -static int blktap_read_ufe_ring(int idx) +static int blktap_read_ufe_ring(tap_blkif_t *info) { /* This is called to read responses from the UFE ring. */ RING_IDX i, j, rp; @@ -1010,12 +944,9 @@ static int blktap_read_ufe_ring(int idx) blkif_t *blkif=NULL; int pending_idx, usr_idx, mmap_idx; pending_req_t *pending_req; - tap_blkif_t *info; - - info = tapfds[idx]; - if (info == NULL) { + + if (!info) return 0; - } /* We currently only forward packets in INTERCEPT_FE mode. */ if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE)) @@ -1053,9 +984,8 @@ static int blktap_read_ufe_ring(int idx) struct page *pg; int offset; - uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j); - kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, - pending_idx, j); + uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j); + kvaddr = idx_to_kaddr(mmap_idx, pending_idx, j); pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT); ClearPageReserved(pg); @@ -1063,7 +993,7 @@ static int blktap_read_ufe_ring(int idx) >> PAGE_SHIFT; map[offset] = NULL; } - fast_flush_area(pending_req, pending_idx, usr_idx, idx); + fast_flush_area(pending_req, pending_idx, usr_idx, info->minor); make_response(blkif, pending_req->id, resp->operation, resp->status); info->idx_map[usr_idx] = INVALID_REQ; @@ -1237,8 +1167,7 @@ static void dispatch_rw_block_io(blkif_t uint32_t flags; uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i); - kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, - pending_idx, i); + kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i); page = virt_to_page(kvaddr); sector = req->sector_number + (8*i); @@ -1290,8 +1219,7 @@ static void dispatch_rw_block_io(blkif_t struct page *pg; uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2); - kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, - pending_idx, i/2); + kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2); if (unlikely(map[i].status != 0)) { WPRINTK("invalid kernel buffer -- " @@ -1321,8 +1249,7 @@ static void dispatch_rw_block_io(blkif_t unsigned long kvaddr; struct page *pg; - kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, - pending_idx, i); + kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i); pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT); SetPageReserved(pg); } @@ -1416,7 +1343,8 @@ static int __init blkif_init(void) /*Create the blktap devices, but do not map memory or waitqueue*/ for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF; - ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops); + /* Dynamically allocate a major for this device */ + ret = register_chrdev(0, "blktap", &blktap_fops); blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL); if ( (ret < 0)||(blktap_dir < 0) ) { @@ -1424,22 +1352,44 @@ static int __init blkif_init(void) return -ENOMEM; } + blktap_major = ret; + for(i = 0; i < MAX_TAP_DEV; i++ ) { info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL); - if(tapfds[i] == NULL) return -ENOMEM; + if(tapfds[i] == NULL) + return -ENOMEM; info->minor = i; info->pid = 0; info->blkif = NULL; - ret = devfs_mk_cdev(MKDEV(BLKTAP_DEV_MAJOR, i), + ret = devfs_mk_cdev(MKDEV(blktap_major, i), S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i); - if(ret != 0) return -ENOMEM; + if(ret != 0) + return -ENOMEM; info->dev_pending = info->dev_inuse = 0; DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i); } + /* Make sure the xen class exists */ + if (!setup_xen_class()) { + /* + * This will allow udev to create the blktap ctrl device. + * We only want to create blktap0 first. We don't want + * to flood the sysfs system with needless blktap devices. + * We only create the device when a request of a new device is + * made. + */ + class_device_create(xen_class, NULL, + MKDEV(blktap_major, 0), NULL, + "blktap0"); + tapfds[0]->sysfs_set = 1; + } else { + /* this is bad, but not fatal */ + WPRINTK("blktap: sysfs xen_class not created\n"); + } + DPRINTK("Blktap device successfully created\n"); return 0; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Wed Oct 11 13:04:07 2006 -0400 @@ -273,7 +273,6 @@ static void tap_frontend_changed(struct kthread_stop(be->blkif->xenblkd); be->blkif->xenblkd = NULL; } - tap_blkif_unmap(be->blkif); xenbus_switch_state(dev, XenbusStateClosing); break; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/core/skbuff.c --- a/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Wed Oct 11 13:04:07 2006 -0400 @@ -18,7 +18,12 @@ /*static*/ kmem_cache_t *skbuff_cachep; EXPORT_SYMBOL(skbuff_cachep); -#define MAX_SKBUFF_ORDER 4 +/* Allow up to 64kB or page-sized packets (whichever is greater). */ +#if PAGE_SHIFT < 16 +#define MAX_SKBUFF_ORDER (16 - PAGE_SHIFT) +#else +#define MAX_SKBUFF_ORDER 0 +#endif static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1]; static struct { diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Wed Oct 11 13:04:07 2006 -0400 @@ -419,10 +419,9 @@ static struct file_operations evtchn_fop }; static struct miscdevice evtchn_miscdev = { - .minor = EVTCHN_MINOR, + .minor = MISC_DYNAMIC_MINOR, .name = "evtchn", .fops = &evtchn_fops, - .devfs_name = "misc/evtchn", }; static int __init evtchn_init(void) diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Oct 11 13:04:07 2006 -0400 @@ -34,6 +34,24 @@ #include <linux/ethtool.h> #include <linux/rtnetlink.h> +/* + * Module parameter 'queue_length': + * + * Enables queuing in the network stack when a client has run out of receive + * descriptors. Although this feature can improve receive bandwidth by avoiding + * packet loss, it can also result in packets sitting in the 'tx_queue' for + * unbounded time. This is bad if those packets hold onto foreign resources. + * For example, consider a packet that holds onto resources belonging to the + * guest for which it is queued (e.g., packet received on vif1.0, destined for + * vif1.1 which is not activated in the guest): in this situation the guest + * will never be destroyed, unless vif1.1 is taken down (which flushes the + * 'tx_queue'). + * + * Only set this parameter to non-zero value if you know what you are doing! + */ +static unsigned long netbk_queue_length = 0; +module_param_named(queue_length, netbk_queue_length, ulong, 0); + static void __netif_up(netif_t *netif) { enable_irq(netif->irq); @@ -44,6 +62,7 @@ static void __netif_down(netif_t *netif) { disable_irq(netif->irq); netif_deschedule_work(netif); + del_timer_sync(&netif->credit_timeout); } static int net_open(struct net_device *dev) @@ -134,6 +153,7 @@ netif_t *netif_alloc(domid_t domid, unsi netif->credit_bytes = netif->remaining_credit = ~0UL; netif->credit_usec = 0UL; init_timer(&netif->credit_timeout); + netif->credit_timeout.expires = jiffies; dev->hard_start_xmit = netif_be_start_xmit; dev->get_stats = netif_be_get_stats; @@ -144,11 +164,10 @@ netif_t *netif_alloc(domid_t domid, unsi SET_ETHTOOL_OPS(dev, &network_ethtool_ops); - /* - * Reduce default TX queuelen so that each guest interface only - * allows it to eat around 6.4MB of host memory. - */ - dev->tx_queue_len = 100; + dev->tx_queue_len = netbk_queue_length; + if (dev->tx_queue_len != 0) + printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero " + "queue length (%lu)!\n", dev->name, dev->tx_queue_len); for (i = 0; i < ETH_ALEN; i++) if (be_mac[i] != 0) diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/netback/loopback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Oct 11 13:04:07 2006 -0400 @@ -53,8 +53,10 @@ #include <linux/skbuff.h> #include <linux/ethtool.h> #include <net/dst.h> - -static int nloopbacks = 8; +#include <net/xfrm.h> /* secpath_reset() */ +#include <asm/hypervisor.h> /* is_initial_xendomain() */ + +static int nloopbacks = -1; module_param(nloopbacks, int, 0); MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create"); @@ -77,9 +79,59 @@ static int loopback_close(struct net_dev return 0; } +#ifdef CONFIG_X86 +static int is_foreign(unsigned long pfn) +{ + /* NB. Play it safe for auto-translation mode. */ + return (xen_feature(XENFEAT_auto_translated_physmap) || + (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT)); +} +#else +/* How to detect a foreign mapping? Play it safe. */ +#define is_foreign(pfn) (1) +#endif + +static int skb_remove_foreign_references(struct sk_buff *skb) +{ + struct page *page; + unsigned long pfn; + int i, off; + char *vaddr; + + BUG_ON(skb_shinfo(skb)->frag_list); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page); + if (!is_foreign(pfn)) + continue; + + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(!page)) + return 0; + + vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); + off = skb_shinfo(skb)->frags[i].page_offset; + memcpy(page_address(page) + off, + vaddr + off, + skb_shinfo(skb)->frags[i].size); + kunmap_skb_frag(vaddr); + + put_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb)->frags[i].page = page; + } + + return 1; +} + static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_private *np = netdev_priv(dev); + + if (!skb_remove_foreign_references(skb)) { + np->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; + } dst_release(skb->dst); skb->dst = NULL; @@ -110,6 +162,11 @@ static int loopback_start_xmit(struct sk skb->protocol = eth_type_trans(skb, dev); skb->dev = dev; dev->last_rx = jiffies; + + /* Flush netfilter context: rx'ed skbuffs not expected to have any. */ + nf_reset(skb); + secpath_reset(skb); + netif_rx(skb); return 0; @@ -239,6 +296,9 @@ static int __init loopback_init(void) { int i, err = 0; + if (nloopbacks == -1) + nloopbacks = is_initial_xendomain() ? 4 : 0; + for (i = 0; i < nloopbacks; i++) if ((err = make_loopback(i)) != 0) break; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Oct 11 13:04:07 2006 -0400 @@ -70,10 +70,11 @@ static struct timer_list net_timer; static struct sk_buff_head rx_queue; -static unsigned long mmap_vstart; -#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE)) - -static void *rx_mmap_area; +static struct page **mmap_pages; +static inline unsigned long idx_to_kaddr(unsigned int idx) +{ + return (unsigned long)pfn_to_kaddr(page_to_pfn(mmap_pages[idx])); +} #define PKT_PROT_LEN 64 @@ -217,7 +218,7 @@ static struct sk_buff *netbk_copy_skb(st copy = len >= PAGE_SIZE ? PAGE_SIZE : len; zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO; - page = alloc_page(GFP_ATOMIC | zero); + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | zero); if (unlikely(!page)) goto err_free; @@ -792,10 +793,27 @@ void netif_deschedule_work(netif_t *neti } +static void tx_add_credit(netif_t *netif) +{ + unsigned long max_burst; + + /* + * Allow a burst big enough to transmit a jumbo packet of up to 128kB. + * Otherwise the interface can seize up due to insufficient credit. + */ + max_burst = RING_GET_REQUEST(&netif->tx, netif->tx.req_cons)->size; + max_burst = min(max_burst, 131072UL); + max_burst = max(max_burst, netif->credit_bytes); + + netif->remaining_credit = min(netif->remaining_credit + + netif->credit_bytes, + max_burst); +} + static void tx_credit_callback(unsigned long data) { netif_t *netif = (netif_t *)data; - netif->remaining_credit = netif->credit_bytes; + tx_add_credit(netif); netif_schedule_work(netif); } @@ -819,7 +837,7 @@ inline static void net_tx_action_dealloc gop = tx_unmap_ops; while (dc != dp) { pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; - gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx), + gnttab_set_unmap_op(gop, idx_to_kaddr(pending_idx), GNTMAP_host_map, grant_tx_handle[pending_idx]); gop++; @@ -907,7 +925,7 @@ static gnttab_map_grant_ref_t *netbk_get txp = RING_GET_REQUEST(&netif->tx, cons++); pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)]; - gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx), + gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx), GNTMAP_host_map | GNTMAP_readonly, txp->gref, netif->domid); @@ -940,7 +958,7 @@ static int netbk_tx_check_mop(struct sk_ netif_put(netif); } else { set_phys_to_machine( - __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT, + __pa(idx_to_kaddr(pending_idx)) >> PAGE_SHIFT, FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT)); grant_tx_handle[pending_idx] = mop->handle; } @@ -957,7 +975,7 @@ static int netbk_tx_check_mop(struct sk_ newerr = (++mop)->status; if (likely(!newerr)) { set_phys_to_machine( - __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT, + __pa(idx_to_kaddr(pending_idx))>>PAGE_SHIFT, FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT)); grant_tx_handle[pending_idx] = mop->handle; /* Had a previous error? Invalidate this fragment. */ @@ -1005,7 +1023,7 @@ static void netbk_fill_frags(struct sk_b pending_idx = (unsigned long)frag->page; txp = &pending_tx_info[pending_idx].req; - frag->page = virt_to_page(MMAP_VADDR(pending_idx)); + frag->page = virt_to_page(idx_to_kaddr(pending_idx)); frag->size = txp->size; frag->page_offset = txp->offset; @@ -1101,6 +1119,7 @@ static void net_tx_action(unsigned long i = netif->tx.req_cons; rmb(); /* Ensure that we see the request before we copy it. */ memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq)); + /* Credit-based scheduling. */ if (txreq.size > netif->remaining_credit) { unsigned long now = jiffies; @@ -1109,25 +1128,27 @@ static void net_tx_action(unsigned long msecs_to_jiffies(netif->credit_usec / 1000); /* Timer could already be pending in rare cases. */ - if (timer_pending(&netif->credit_timeout)) - break; + if (timer_pending(&netif->credit_timeout)) { + netif_put(netif); + continue; + } /* Passed the point where we can replenish credit? */ if (time_after_eq(now, next_credit)) { netif->credit_timeout.expires = now; - netif->remaining_credit = netif->credit_bytes; + tx_add_credit(netif); } /* Still too big to send right now? Set a callback. */ if (txreq.size > netif->remaining_credit) { - netif->remaining_credit = 0; netif->credit_timeout.data = (unsigned long)netif; netif->credit_timeout.function = tx_credit_callback; __mod_timer(&netif->credit_timeout, next_credit); - break; + netif_put(netif); + continue; } } netif->remaining_credit -= txreq.size; @@ -1201,7 +1222,7 @@ static void net_tx_action(unsigned long } } - gnttab_set_map_op(mop, MMAP_VADDR(pending_idx), + gnttab_set_map_op(mop, idx_to_kaddr(pending_idx), GNTMAP_host_map | GNTMAP_readonly, txreq.gref, netif->domid); mop++; @@ -1260,8 +1281,8 @@ static void net_tx_action(unsigned long } data_len = skb->len; - memcpy(skb->data, - (void *)(MMAP_VADDR(pending_idx)|txp->offset), + memcpy(skb->data, + (void *)(idx_to_kaddr(pending_idx)|txp->offset), data_len); if (data_len < txp->size) { /* Append the packet payload as a fragment. */ @@ -1315,18 +1336,10 @@ static void netif_idx_release(u16 pendin static void netif_page_release(struct page *page) { - u16 pending_idx = page - virt_to_page(mmap_vstart); - /* Ready for next use. */ set_page_count(page, 1); - netif_idx_release(pending_idx); -} - -static void netif_rx_page_release(struct page *page) -{ - /* Ready for next use. */ - set_page_count(page, 1); + netif_idx_release(page->index); } irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) @@ -1446,27 +1459,17 @@ static int __init netback_init(void) init_timer(&net_timer); net_timer.data = 0; net_timer.function = net_alarm; - - page = balloon_alloc_empty_page_range(MAX_PENDING_REQS); - if (page == NULL) + + mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS); + if (mmap_pages == NULL) { + printk("%s: out of memory\n", __FUNCTION__); return -ENOMEM; - - mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + } for (i = 0; i < MAX_PENDING_REQS; i++) { - page = virt_to_page(MMAP_VADDR(i)); - set_page_count(page, 1); + page = mmap_pages[i]; SetPageForeign(page, netif_page_release); - } - - page = balloon_alloc_empty_page_range(NET_RX_RING_SIZE); - BUG_ON(page == NULL); - rx_mmap_area = pfn_to_kaddr(page_to_pfn(page)); - - for (i = 0; i < NET_RX_RING_SIZE; i++) { - page = virt_to_page(rx_mmap_area + (i * PAGE_SIZE)); - set_page_count(page, 1); - SetPageForeign(page, netif_rx_page_release); + page->index = i; } pending_cons = 0; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Oct 11 13:04:07 2006 -0400 @@ -366,6 +366,10 @@ static void connect(struct backend_info be->netif->remaining_credit = be->netif->credit_bytes; xenbus_switch_state(dev, XenbusStateConnected); + + /* May not get a kick from the frontend, so start the tx_queue now. */ + if (!netbk_can_queue(be->netif->dev)) + netif_start_queue(be->netif->dev); } @@ -403,14 +407,16 @@ static int connect_rings(struct backend_ } be->netif->copying_receiver = !!rx_copy; - if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d", - &val) < 0) - val = 0; - if (val) - be->netif->can_queue = 1; - else - /* Must be non-zero for pfifo_fast to work. */ - be->netif->dev->tx_queue_len = 1; + if (be->netif->dev->tx_queue_len != 0) { + if (xenbus_scanf(XBT_NIL, dev->otherend, + "feature-rx-notify", "%d", &val) < 0) + val = 0; + if (val) + be->netif->can_queue = 1; + else + /* Must be non-zero for pfifo_fast to work. */ + be->netif->dev->tx_queue_len = 1; + } if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0) val = 0; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 11 13:04:07 2006 -0400 @@ -47,6 +47,7 @@ #include <linux/in.h> #include <linux/if_ether.h> #include <linux/io.h> +#include <linux/moduleparam.h> #include <net/sock.h> #include <net/pkt_sched.h> #include <net/arp.h> @@ -63,20 +64,64 @@ #include <xen/interface/grant_table.h> #include <xen/gnttab.h> +/* + * Mutually-exclusive module options to select receive data path: + * rx_copy : Packets are copied by network backend into local memory + * rx_flip : Page containing packet data is transferred to our ownership + * For fully-virtualised guests there is no option - copying must be used. + * For paravirtualised guests, flipping is the default. + */ +#ifdef CONFIG_XEN +static int MODPARM_rx_copy = 0; +module_param_named(rx_copy, MODPARM_rx_copy, bool, 0); +MODULE_PARM_DESC(rx_copy, "Copy packets from network card (rather than flip)"); +static int MODPARM_rx_flip = 0; +module_param_named(rx_flip, MODPARM_rx_flip, bool, 0); +MODULE_PARM_DESC(rx_flip, "Flip packets from network card (rather than copy)"); +#else +static const int MODPARM_rx_copy = 1; +static const int MODPARM_rx_flip = 0; +#endif + #define RX_COPY_THRESHOLD 256 /* If we don't have GSO, fake things up so that we never try to use it. */ -#ifndef NETIF_F_GSO -#define netif_needs_gso(dev, skb) 0 -#define dev_disable_gso_features(dev) ((void)0) -#else +#if defined(NETIF_F_GSO) #define HAVE_GSO 1 +#define HAVE_TSO 1 /* TSO is a subset of GSO */ static inline void dev_disable_gso_features(struct net_device *dev) { /* Turn off all GSO bits except ROBUST. */ dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1; dev->features |= NETIF_F_GSO_ROBUST; } +#elif defined(NETIF_F_TSO) +#define HAVE_TSO 1 +#define gso_size tso_size +#define gso_segs tso_segs +static inline void dev_disable_gso_features(struct net_device *dev) +{ + /* Turn off all TSO bits. */ + dev->features &= ~NETIF_F_TSO; +} +static inline int skb_is_gso(const struct sk_buff *skb) +{ + return skb_shinfo(skb)->tso_size; +} +static inline int skb_gso_ok(struct sk_buff *skb, int features) +{ + return (features & NETIF_F_TSO); +} + +static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) +{ + return skb_is_gso(skb) && + (!skb_gso_ok(skb, dev->features) || + unlikely(skb->ip_summed != CHECKSUM_HW)); +} +#else +#define netif_needs_gso(dev, skb) 0 +#define dev_disable_gso_features(dev) ((void)0) #endif #define GRANT_INVALID_REF 0 @@ -120,7 +165,7 @@ struct netfront_info { grant_ref_t gref_tx_head; grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; grant_ref_t gref_rx_head; - grant_ref_t grant_rx_ref[NET_TX_RING_SIZE]; + grant_ref_t grant_rx_ref[NET_RX_RING_SIZE]; struct xenbus_device *xbdev; int tx_ring_ref; @@ -229,8 +274,7 @@ static int __devinit netfront_probe(stru int err; struct net_device *netdev; struct netfront_info *info; - unsigned int handle; - unsigned feature_rx_copy; + unsigned int handle, feature_rx_copy, feature_rx_flip, use_copy; err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle); if (err != 1) { @@ -238,22 +282,24 @@ static int __devinit netfront_probe(stru return err; } -#ifndef CONFIG_XEN err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u", &feature_rx_copy); - if (err != 1) { - xenbus_dev_fatal(dev, err, "reading feature-rx-copy"); - return err; - } - if (!feature_rx_copy) { - xenbus_dev_fatal(dev, 0, "need a copy-capable backend"); - return -EINVAL; - } -#else - feature_rx_copy = 0; -#endif - - netdev = create_netdev(handle, feature_rx_copy, dev); + if (err != 1) + feature_rx_copy = 0; + err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flip", "%u", + &feature_rx_flip); + if (err != 1) + feature_rx_flip = 1; + + /* + * Copy packets on receive path if: + * (a) This was requested by user, and the backend supports it; or + * (b) Flipping was requested, but this is unsupported by the backend. + */ + use_copy = (MODPARM_rx_copy && feature_rx_copy) || + (MODPARM_rx_flip && !feature_rx_flip); + + netdev = create_netdev(handle, use_copy, dev); if (IS_ERR(netdev)) { err = PTR_ERR(netdev); xenbus_dev_fatal(dev, err, "creating netdev"); @@ -270,6 +316,9 @@ static int __devinit netfront_probe(stru err = open_netdev(info); if (err) goto fail_open; + + IPRINTK("Created netdev %s with %sing receive path.\n", + netdev->name, info->copying_receiver ? "copy" : "flipp"); return 0; @@ -385,7 +434,7 @@ again: goto abort_transaction; } -#ifdef HAVE_GSO +#ifdef HAVE_TSO err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); if (err) { message = "writing feature-gso-tcpv4"; @@ -742,7 +791,7 @@ no_skb: } else { gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, - pfn, + pfn_to_mfn(pfn), 0); } @@ -917,7 +966,7 @@ static int network_start_xmit(struct sk_ tx->flags |= NETTXF_data_validated; #endif -#ifdef HAVE_GSO +#ifdef HAVE_TSO if (skb_shinfo(skb)->gso_size) { struct netif_extra_info *gso = (struct netif_extra_info *) RING_GET_REQUEST(&np->tx, ++i); @@ -1205,12 +1254,14 @@ static int xennet_set_skb_gso(struct sk_ return -EINVAL; } +#ifdef HAVE_TSO + skb_shinfo(skb)->gso_size = gso->u.gso.size; #ifdef HAVE_GSO - skb_shinfo(skb)->gso_size = gso->u.gso.size; skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; /* Header must be checked, and gso_segs computed. */ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; +#endif skb_shinfo(skb)->gso_segs = 0; return 0; @@ -1561,7 +1612,7 @@ static int xennet_set_sg(struct net_devi static int xennet_set_tso(struct net_device *dev, u32 data) { -#ifdef HAVE_GSO +#ifdef HAVE_TSO if (data) { struct netfront_info *np = netdev_priv(dev); int val; @@ -1632,7 +1683,8 @@ static void network_connect(struct net_d } else { gnttab_grant_foreign_access_ref( ref, np->xbdev->otherend_id, - page_to_pfn(skb_shinfo(skb)->frags->page), + pfn_to_mfn(page_to_pfn(skb_shinfo(skb)-> + frags->page)), 0); } req->gref = ref; @@ -2053,6 +2105,16 @@ static int __init netif_init(void) if (!is_running_on_xen()) return -ENODEV; +#ifdef CONFIG_XEN + if (MODPARM_rx_flip && MODPARM_rx_copy) { + WPRINTK("Cannot specify both rx_copy and rx_flip.\n"); + return -EINVAL; + } + + if (!MODPARM_rx_flip && !MODPARM_rx_copy) + MODPARM_rx_flip = 1; /* Default is to flip. */ +#endif + if (is_initial_xendomain()) return 0; diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Oct 11 13:04:07 2006 -0400 @@ -100,10 +100,12 @@ static int privcmd_ioctl(struct inode *i break; case IOCTL_PRIVCMD_MMAP: { -#define PRIVCMD_MMAP_SZ 32 privcmd_mmap_t mmapcmd; - privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ]; + privcmd_mmap_entry_t msg; privcmd_mmap_entry_t __user *p; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long va; int i, rc; if (!is_initial_xendomain()) @@ -113,47 +115,62 @@ static int privcmd_ioctl(struct inode *i return -EFAULT; p = mmapcmd.entry; - - for (i = 0; i < mmapcmd.num; - i += PRIVCMD_MMAP_SZ, p += PRIVCMD_MMAP_SZ) { - int j, n = ((mmapcmd.num-i)>PRIVCMD_MMAP_SZ)? - PRIVCMD_MMAP_SZ:(mmapcmd.num-i); - - if (copy_from_user(&msg, p, - n*sizeof(privcmd_mmap_entry_t))) - return -EFAULT; - - for (j = 0; j < n; j++) { - struct vm_area_struct *vma = - find_vma( current->mm, msg[j].va ); - - if (!vma) - return -EINVAL; - - if (msg[j].va > PAGE_OFFSET) - return -EINVAL; - - if ((msg[j].va + (msg[j].npages << PAGE_SHIFT)) - > vma->vm_end ) - return -EINVAL; - - if ((rc = direct_remap_pfn_range( - vma, - msg[j].va&PAGE_MASK, - msg[j].mfn, - msg[j].npages<<PAGE_SHIFT, - vma->vm_page_prot, - mmapcmd.dom)) < 0) - return rc; - } - } - ret = 0; + if (copy_from_user(&msg, p, sizeof(msg))) + return -EFAULT; + + down_read(&mm->mmap_sem); + + vma = find_vma(mm, msg.va); + rc = -EINVAL; + if (!vma || (msg.va != vma->vm_start) || vma->vm_private_data) + goto mmap_out; + + /* Mapping is a one-shot operation per vma. */ + vma->vm_private_data = (void *)1; + + va = vma->vm_start; + + for (i = 0; i < mmapcmd.num; i++) { + rc = -EFAULT; + if (copy_from_user(&msg, p, sizeof(msg))) + goto mmap_out; + + /* Do not allow range to wrap the address space. */ + rc = -EINVAL; + if ((msg.npages > (INT_MAX >> PAGE_SHIFT)) || + ((unsigned long)(msg.npages << PAGE_SHIFT) >= -va)) + goto mmap_out; + + /* Range chunks must be contiguous in va space. */ + if ((msg.va != va) || + ((msg.va+(msg.npages<<PAGE_SHIFT)) > vma->vm_end)) + goto mmap_out; + + if ((rc = direct_remap_pfn_range( + vma, + msg.va & PAGE_MASK, + msg.mfn, + msg.npages << PAGE_SHIFT, + vma->vm_page_prot, + mmapcmd.dom)) < 0) + goto mmap_out; + + p++; + va += msg.npages << PAGE_SHIFT; + } + + rc = 0; + + mmap_out: + up_read(&mm->mmap_sem); + ret = rc; } break; case IOCTL_PRIVCMD_MMAPBATCH: { privcmd_mmapbatch_t m; - struct vm_area_struct *vma = NULL; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; xen_pfn_t __user *p; unsigned long addr, mfn; int i; @@ -161,37 +178,33 @@ static int privcmd_ioctl(struct inode *i if (!is_initial_xendomain()) return -EPERM; - if (copy_from_user(&m, udata, sizeof(m))) { - ret = -EFAULT; - goto batch_err; - } - - if (m.dom == DOMID_SELF) { - ret = -EINVAL; - goto batch_err; - } - - vma = find_vma(current->mm, m.addr); - if (!vma) { - ret = -EINVAL; - goto batch_err; - } - - if (m.addr > PAGE_OFFSET) { - ret = -EFAULT; - goto batch_err; - } - - if ((m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end) { - ret = -EFAULT; - goto batch_err; - } + if (copy_from_user(&m, udata, sizeof(m))) + return -EFAULT; + + if ((m.num <= 0) || (m.num > (INT_MAX >> PAGE_SHIFT))) + return -EINVAL; + + down_read(&mm->mmap_sem); + + vma = find_vma(mm, m.addr); + if (!vma || + (m.addr != vma->vm_start) || + ((m.addr + (m.num<<PAGE_SHIFT)) != vma->vm_end) || + vma->vm_private_data) { + up_read(&mm->mmap_sem); + return -EINVAL; + } + + /* Mapping is a one-shot operation per vma. */ + vma->vm_private_data = (void *)1; p = m.arr; addr = m.addr; for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) { - if (get_user(mfn, p)) + if (get_user(mfn, p)) { + up_read(&mm->mmap_sem); return -EFAULT; + } ret = direct_remap_pfn_range(vma, addr & PAGE_MASK, mfn, PAGE_SIZE, @@ -200,15 +213,8 @@ static int privcmd_ioctl(struct inode *i put_user(0xF0000000 | mfn, p); } + up_read(&mm->mmap_sem); ret = 0; - break; - - batch_err: - printk("batch_err ret=%d vma=%p addr=%lx " - "num=%d arr=%p %lx-%lx\n", - ret, vma, (unsigned long)m.addr, m.num, m.arr, - vma ? vma->vm_start : 0, vma ? vma->vm_end : 0); - break; } break; @@ -221,10 +227,27 @@ static int privcmd_ioctl(struct inode *i } #ifndef HAVE_ARCH_PRIVCMD_MMAP +static struct page *privcmd_nopage(struct vm_area_struct *vma, + unsigned long address, + int *type) +{ + return NOPAGE_SIGBUS; +} + +static struct vm_operations_struct privcmd_vm_ops = { + .nopage = privcmd_nopage +}; + static int privcmd_mmap(struct file * file, struct vm_area_struct * vma) { + /* Unsupported for auto-translate guests. */ + if (xen_feature(XENFEAT_auto_translated_physmap)) + return -ENOSYS; + /* DONTCOPY is essential for Xen as copy_page_range is broken. */ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; + vma->vm_ops = &privcmd_vm_ops; + vma->vm_private_data = NULL; return 0; } diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/tpmback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Oct 11 13:04:07 2006 -0400 @@ -46,11 +46,10 @@ typedef struct tpmif_st { atomic_t refcnt; struct backend_info *bi; - unsigned long mmap_vstart; grant_handle_t shmem_handle; grant_ref_t shmem_ref; - struct page *pagerange; + struct page **mmap_pages; char devname[20]; } tpmif_t; @@ -80,6 +79,9 @@ int vtpm_release_packets(tpmif_t * tpmif extern int num_frontends; -#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE)) +static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx) +{ + return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx])); +} #endif /* __TPMIF__BACKEND__COMMON_H__ */ diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Oct 11 13:04:07 2006 -0400 @@ -25,8 +25,8 @@ static tpmif_t *alloc_tpmif(domid_t domi tpmif_t *tpmif; tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL); - if (!tpmif) - return ERR_PTR(-ENOMEM); + if (tpmif == NULL) + goto out_of_memory; memset(tpmif, 0, sizeof (*tpmif)); tpmif->domid = domid; @@ -35,22 +35,27 @@ static tpmif_t *alloc_tpmif(domid_t domi snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid); atomic_set(&tpmif->refcnt, 1); - tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE); - BUG_ON(tpmif->pagerange == NULL); - tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr( - page_to_pfn(tpmif->pagerange)); + tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE); + if (tpmif->mmap_pages == NULL) + goto out_of_memory; list_add(&tpmif->tpmif_list, &tpmif_list); num_frontends++; return tpmif; + + out_of_memory: + if (tpmif != NULL) + kmem_cache_free(tpmif_cachep, tpmif); + printk("%s: out of memory\n", __FUNCTION__); + return ERR_PTR(-ENOMEM); } static void free_tpmif(tpmif_t * tpmif) { num_frontends--; list_del(&tpmif->tpmif_list); - balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE); + free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE); kmem_cache_free(tpmif_cachep, tpmif); } diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Oct 11 13:04:07 2006 -0400 @@ -253,7 +253,7 @@ int _packet_write(struct packet *pak, return 0; } - gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i), + gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, tx->ref, tpmif->domid); if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, @@ -270,7 +270,7 @@ int _packet_write(struct packet *pak, tocopy = min_t(size_t, size - offset, PAGE_SIZE); - if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) | + if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) | (tx->addr & ~PAGE_MASK)), &data[offset], tocopy, isuserbuffer)) { tpmif_put(tpmif); @@ -278,7 +278,7 @@ int _packet_write(struct packet *pak, } tx->size = tocopy; - gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i), + gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, handle); if (unlikely @@ -391,7 +391,7 @@ static int packet_read_shmem(struct pack tx = &tpmif->tx->ring[i].req; - gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i), + gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, tx->ref, tpmif->domid); if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, @@ -414,10 +414,10 @@ static int packet_read_shmem(struct pack } DPRINTK("Copying from mapped memory at %08lx\n", - (unsigned long)(MMAP_VADDR(tpmif, i) | + (unsigned long)(idx_to_kaddr(tpmif, i) | (tx->addr & ~PAGE_MASK))); - src = (void *)(MMAP_VADDR(tpmif, i) | + src = (void *)(idx_to_kaddr(tpmif, i) | ((tx->addr & ~PAGE_MASK) + pg_offset)); if (copy_to_buffer(&buffer[offset], src, to_copy, isuserbuffer)) { @@ -428,7 +428,7 @@ static int packet_read_shmem(struct pack tpmif->domid, buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]); - gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i), + gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, handle); if (unlikely diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 11 13:04:07 2006 -0400 @@ -322,6 +322,20 @@ static void otherend_changed(struct xenb DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state), dev->otherend_watch.node, vec[XS_WATCH_PATH]); + /* + * Ignore xenbus transitions during shutdown. This prevents us doing + * work that can fail e.g., when the rootfs is gone. + */ + if (system_state > SYSTEM_RUNNING) { + struct xen_bus_type *bus = bus; + bus = container_of(dev->dev.bus, struct xen_bus_type, bus); + /* If we're frontend, drive the state machine to Closed. */ + /* This should cause the backend to release our resources. */ + if ((bus == &xenbus_frontend) && (state == XenbusStateClosing)) + xenbus_frontend_closed(dev); + return; + } + if (drv->otherend_changed) drv->otherend_changed(dev, state); } diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/include/xen/balloon.h --- a/linux-2.6-xen-sparse/include/xen/balloon.h Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/include/xen/balloon.h Wed Oct 11 13:04:07 2006 -0400 @@ -38,23 +38,13 @@ * Inform the balloon driver that it should allow some slop for device-driver * memory activities. */ -void -balloon_update_driver_allowance( - long delta); +void balloon_update_driver_allowance(long delta); -/* Allocate an empty low-memory page range. */ -struct page * -balloon_alloc_empty_page_range( - unsigned long nr_pages); +/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */ +struct page **alloc_empty_pages_and_pagevec(int nr_pages); +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages); -/* Deallocate an empty page range, adding to the balloon. */ -void -balloon_dealloc_empty_page_range( - struct page *page, unsigned long nr_pages); - -void -balloon_release_driver_page( - struct page *page); +void balloon_release_driver_page(struct page *page); /* * Prevent the balloon driver from changing the memory reservation during diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/include/xen/public/evtchn.h --- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h Wed Oct 11 13:04:07 2006 -0400 @@ -32,9 +32,6 @@ #ifndef __LINUX_PUBLIC_EVTCHN_H__ #define __LINUX_PUBLIC_EVTCHN_H__ - -/* /dev/xen/evtchn resides at device number major=10, minor=201 */ -#define EVTCHN_MINOR 201 /* * Bind a fresh port to VIRQ @virq. diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/mm/memory.c --- a/linux-2.6-xen-sparse/mm/memory.c Wed Oct 11 13:01:31 2006 -0400 +++ b/linux-2.6-xen-sparse/mm/memory.c Wed Oct 11 13:04:07 2006 -0400 @@ -390,7 +390,7 @@ struct page *vm_normal_page(struct vm_ar if (vma->vm_flags & VM_PFNMAP) { unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT; - if ((pfn == vma->vm_pgoff + off) || !pfn_valid(pfn)) + if (pfn == vma->vm_pgoff + off) return NULL; if (!is_cow_mapping(vma->vm_flags)) return NULL; @@ -405,7 +405,8 @@ struct page *vm_normal_page(struct vm_ar * Remove this test eventually! */ if (unlikely(!pfn_valid(pfn))) { - print_bad_pte(vma, pte, addr); + if (!(vma->vm_flags & VM_RESERVED)) + print_bad_pte(vma, pte, addr); return NULL; } diff -r e7cb3aefc233 -r b53c343b47ae patches/linux-2.6.16.29/series --- a/patches/linux-2.6.16.29/series Wed Oct 11 13:01:31 2006 -0400 +++ b/patches/linux-2.6.16.29/series Wed Oct 11 13:04:07 2006 -0400 @@ -10,6 +10,7 @@ net-gso-2-checksum-fix.patch net-gso-2-checksum-fix.patch net-gso-3-fix-errorcheck.patch net-gso-4-kill-warnon.patch +pci-mmconfig-fix-from-2.6.17.patch pmd-shared.patch rcu_needs_cpu.patch rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/Makefile --- a/tools/blktap/drivers/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/drivers/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -10,11 +10,8 @@ INSTALL_DIR = /usr/sbin INSTALL_DIR = /usr/sbin LIBAIO_DIR = ../../libaio/src -CFLAGS += -fPIC -CFLAGS += -Wall CFLAGS += -Werror CFLAGS += -Wno-unused -CFLAGS += -g3 CFLAGS += -fno-strict-aliasing CFLAGS += -I $(XEN_LIBXC) -I $(LIBAIO_DIR) CFLAGS += $(INCLUDES) -I. -I../../xenstore @@ -28,7 +25,7 @@ THREADLIB := -lpthread -lz THREADLIB := -lpthread -lz LIBS := -L. -L.. -L../lib LIBS += -L$(XEN_LIBXC) -LIBS += -lblktap +LIBS += -lblktap -lxenctrl LIBS += -lcrypto LIBS += -lz LIBS += -L$(XEN_XENSTORE) -lxenstore diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/blktapctrl.c --- a/tools/blktap/drivers/blktapctrl.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/drivers/blktapctrl.c Wed Oct 11 13:04:07 2006 -0400 @@ -67,15 +67,12 @@ int max_timeout = MAX_TIMEOUT; int max_timeout = MAX_TIMEOUT; int ctlfd = 0; +int blktap_major; + static int open_ctrl_socket(char *devname); static int write_msg(int fd, int msgtype, void *ptr, void *ptr2); static int read_msg(int fd, int msgtype, void *ptr); static driver_list_entry_t *active_disks[MAX_DISK_TYPES]; - -void sig_handler(int sig) -{ - run = 0; -} static void init_driver_list(void) { @@ -108,7 +105,18 @@ static void make_blktap_dev(char *devnam if (mknod(devname, S_IFCHR|0600, makedev(major, minor)) == 0) DPRINTF("Created %s device\n",devname); - } else DPRINTF("%s device already exists\n",devname); + } else { + DPRINTF("%s device already exists\n",devname); + /* it already exists, but is it the same major number */ + if (((st.st_rdev>>8) & 0xff) != major) { + DPRINTF("%s has old major %d\n", + devname, + (unsigned int)((st.st_rdev >> 8) & 0xff)); + /* only try again if we succed in deleting it */ + if (!unlink(devname)) + make_blktap_dev(devname, major, minor); + } + } } static int get_new_dev(int *major, int *minor, blkif_t *blkif) @@ -644,14 +652,18 @@ int main(int argc, char *argv[]) register_new_devmap_hook(map_new_blktapctrl); register_new_unmap_hook(unmap_blktapctrl); - /*Attach to blktap0 */ + /* Attach to blktap0 */ asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME); - make_blktap_dev(devname,254,0); + if ((ret = xc_find_device_number("blktap0")) < 0) + goto open_failed; + blktap_major = major(ret); + make_blktap_dev(devname,blktap_major,0); ctlfd = open(devname, O_RDWR); if (ctlfd == -1) { DPRINTF("blktap0 open failed\n"); goto open_failed; } + retry: /* Set up store connection and watch. */ @@ -666,15 +678,11 @@ int main(int argc, char *argv[]) } else goto open_failed; } - ret = add_blockdevice_probe_watch(h, "Domain-0"); + ret = setup_probe_watch(h); if (ret != 0) { DPRINTF("Failed adding device probewatch\n"); - if (count < MAX_ATTEMPTS) { - count++; - sleep(2); - xs_daemon_close(h); - goto retry; - } else goto open_failed; + xs_daemon_close(h); + goto open_failed; } ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/tapdisk.c --- a/tools/blktap/drivers/tapdisk.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/drivers/tapdisk.c Wed Oct 11 13:04:07 2006 -0400 @@ -271,7 +271,6 @@ static int read_msg(char *buf) int length, len, msglen, tap_fd, *io_fd; char *ptr, *path; image_t *img; - struct timeval timeout; msg_hdr_t *msg; msg_newdev_t *msg_dev; msg_pid_t *msg_pid; @@ -579,8 +578,7 @@ int main(int argc, char *argv[]) { int len, msglen, ret; char *p, *buf; - fd_set readfds, writefds; - struct timeval timeout; + fd_set readfds, writefds; fd_list_entry_t *ptr; struct tap_disk *drv; struct td_state *s; @@ -622,12 +620,9 @@ int main(int argc, char *argv[]) /*Set all tap fds*/ LOCAL_FD_SET(&readfds); - timeout.tv_sec = 0; - timeout.tv_usec = 1000; - /*Wait for incoming messages*/ ret = select(maxfds + 1, &readfds, (fd_set *) 0, - (fd_set *) 0, &timeout); + (fd_set *) 0, NULL); if (ret > 0) { diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/blktaplib.h --- a/tools/blktap/lib/blktaplib.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/lib/blktaplib.h Wed Oct 11 13:04:07 2006 -0400 @@ -80,8 +80,9 @@ static inline int BLKTAP_MODE_VALID(unsi #define MAX_PENDING_REQS 64 #define BLKTAP_DEV_DIR "/dev/xen" #define BLKTAP_DEV_NAME "blktap" -#define BLKTAP_DEV_MAJOR 254 #define BLKTAP_DEV_MINOR 0 + +extern int blktap_major; #define BLKTAP_RING_PAGES 1 /* Front */ #define BLKTAP_MMAP_REGION_SIZE (BLKTAP_RING_PAGES + MMAP_PAGES) @@ -192,8 +193,8 @@ typedef struct msg_pid { #define CTLMSG_PID_RSP 10 /* xenstore/xenbus: */ -extern int add_blockdevice_probe_watch(struct xs_handle *h, - const char *domname); +#define DOMNAME "Domain-0" +int setup_probe_watch(struct xs_handle *h); int xs_fire_next_watch(struct xs_handle *h); diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xenbus.c --- a/tools/blktap/lib/xenbus.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/lib/xenbus.c Wed Oct 11 13:04:07 2006 -0400 @@ -166,60 +166,58 @@ static void ueblktap_setup(struct xs_han goto fail; } - deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL); - if (!deverr) { - DPRINTF("pdev set to %ld\n",pdev); - if (be->pdev && be->pdev != pdev) { - DPRINTF("changing physical-device not supported"); - goto fail; - } - be->pdev = pdev; - } - - /*Check to see if device is to be opened read-only*/ - asprintf(&path, "%s/%s", bepath, "read-only"); - if (xs_exists(h, path)) - be->readonly = 1; - - if (be->blkif == NULL) { - - /* Front end dir is a number, which is used as the handle. */ - p = strrchr(be->frontpath, '/') + 1; - handle = strtoul(p, NULL, 0); - - be->blkif = alloc_blkif(be->frontend_id); - - if (be->blkif == NULL) - goto fail; + deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL); + if (!deverr) { + DPRINTF("pdev set to %ld\n",pdev); + if (be->pdev && be->pdev != pdev) { + DPRINTF("changing physical-device not supported"); + goto fail; + } + be->pdev = pdev; + } + + /* Check to see if device is to be opened read-only. */ + asprintf(&path, "%s/%s", bepath, "read-only"); + if (xs_exists(h, path)) + be->readonly = 1; + + if (be->blkif == NULL) { + /* Front end dir is a number, which is used as the handle. */ + p = strrchr(be->frontpath, '/') + 1; + handle = strtoul(p, NULL, 0); + + be->blkif = alloc_blkif(be->frontend_id); + if (be->blkif == NULL) + goto fail; be->blkif->be_id = get_be_id(bepath); - /*Insert device specific info*/ - blk = malloc(sizeof(blkif_info_t)); + /* Insert device specific info, */ + blk = malloc(sizeof(blkif_info_t)); if (!blk) { DPRINTF("Out of memory - blkif_info_t\n"); goto fail; } - er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL); - if (er) - goto fail; - be->blkif->info = blk; + er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL); + if (er) + goto fail; + be->blkif->info = blk; - if (deverr) { - /*Dev number was not available, try to set manually*/ - pdev = convert_dev_name_to_num(blk->params); - be->pdev = pdev; - } - - er = blkif_init(be->blkif, handle, be->pdev, be->readonly); - - if (er != 0) { - DPRINTF("Unable to open device %s\n",blk->params); - goto fail; - } - - DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath); - } + if (deverr) { + /*Dev number was not available, try to set manually*/ + pdev = convert_dev_name_to_num(blk->params); + be->pdev = pdev; + } + + er = blkif_init(be->blkif, handle, be->pdev, be->readonly); + if (er != 0) { + DPRINTF("Unable to open device %s\n",blk->params); + goto fail; + } + + DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath); + } + /* Supply the information about the device to xenstore */ er = xs_printf(h, be->backpath, "sectors", "%lu", be->blkif->ops->get_size(be->blkif)); @@ -283,10 +281,10 @@ static void ueblktap_probe(struct xs_han *asserts that xenstore structure is always 7 levels deep *e.g. /local/domain/0/backend/vbd/1/2049 */ - len = strsep_len(bepath, '/', 7); - if (len < 0) - goto free_be; - bepath[len] = '\0'; + len = strsep_len(bepath, '/', 7); + if (len < 0) + goto free_be; + bepath[len] = '\0'; be = malloc(sizeof(*be)); if (!be) { @@ -318,22 +316,21 @@ static void ueblktap_probe(struct xs_han if ( (be != NULL) && (be->blkif != NULL) ) backend_remove(h, be); else goto free_be; - if (bepath) + if (bepath) free(bepath); return; } - /* Are we already tracking this device? */ - if (be_exists_be(bepath)) { + /* Are we already tracking this device? */ + if (be_exists_be(bepath)) goto free_be; - } be->backpath = bepath; - be->frontpath = frontend; - - list_add(&be->list, &belist); - - DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath); + be->frontpath = frontend; + + list_add(&be->list, &belist); + + DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath); DPRINTF("\tFRONTEND (%s),(%ld)\n", frontend,be->frontend_id); ueblktap_setup(h, bepath); @@ -342,11 +339,10 @@ static void ueblktap_probe(struct xs_han free_be: if (frontend) free(frontend); - if (bepath) + if (bepath) free(bepath); if (be) free(be); - return; } /** @@ -356,16 +352,10 @@ static void ueblktap_probe(struct xs_han *are created, we initalise the state and attach a disk. */ -int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname) -{ - char *domid, *path; +int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid) +{ + char *path; struct xenbus_watch *vbd_watch; - int er; - - domid = get_dom_domid(h, domname); - - DPRINTF("%s: %s\n", - domname, (domid != NULL) ? domid : "[ not found! ]"); asprintf(&path, "/local/domain/%s/backend/tap", domid); if (path == NULL) @@ -378,10 +368,67 @@ int add_blockdevice_probe_watch(struct x } vbd_watch->node = path; vbd_watch->callback = ueblktap_probe; - er = register_xenbus_watch(h, vbd_watch); - if (er == 0) { + if (register_xenbus_watch(h, vbd_watch) != 0) { DPRINTF("ERROR: adding vbd probe watch %s\n", path); return -EINVAL; } return 0; } + +/* Asynch callback to check for /local/domain/<DOMID>/name */ +void check_dom(struct xs_handle *h, struct xenbus_watch *w, + const char *bepath_im) +{ + char *domid; + + domid = get_dom_domid(h); + if (domid == NULL) + return; + + add_blockdevice_probe_watch(h, domid); + free(domid); + unregister_xenbus_watch(h, w); +} + +/* We must wait for xend to register /local/domain/<DOMID> */ +int watch_for_domid(struct xs_handle *h) +{ + struct xenbus_watch *domid_watch; + char *path = NULL; + + asprintf(&path, "/local/domain"); + if (path == NULL) + return -ENOMEM; + + domid_watch = malloc(sizeof(struct xenbus_watch)); + if (domid_watch == NULL) { + DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path); + return -EINVAL; + } + + domid_watch->node = path; + domid_watch->callback = check_dom; + + if (register_xenbus_watch(h, domid_watch) != 0) { + DPRINTF("ERROR: adding vbd probe watch %s\n", path); + return -EINVAL; + } + + DPRINTF("Set async watch for /local/domain\n"); + + return 0; +} + +int setup_probe_watch(struct xs_handle *h) +{ + char *domid; + int ret; + + domid = get_dom_domid(h); + if (domid == NULL) + return watch_for_domid(h); + + ret = add_blockdevice_probe_watch(h, domid); + free(domid); + return ret; +} diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xs_api.c --- a/tools/blktap/lib/xs_api.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/lib/xs_api.c Wed Oct 11 13:04:07 2006 -0400 @@ -106,7 +106,7 @@ again: if (!xs_transaction_end(xs, xth, ret)) { if (ret == 0 && errno == EAGAIN) goto again; - else + else ret = errno; } @@ -118,25 +118,25 @@ int xs_printf(struct xs_handle *h, const int xs_printf(struct xs_handle *h, const char *dir, const char *node, const char *fmt, ...) { - char *buf, *path; - va_list ap; - int ret; - - va_start(ap, fmt); - ret = vasprintf(&buf, fmt, ap); - va_end(ap); - - asprintf(&path, "%s/%s", dir, node); - - if ( (path == NULL) || (buf == NULL) ) + char *buf, *path; + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vasprintf(&buf, fmt, ap); + va_end(ap); + + asprintf(&path, "%s/%s", dir, node); + + if ((path == NULL) || (buf == NULL)) return 0; - ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1); - - free(buf); - free(path); - - return ret; + ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1); + + free(buf); + free(path); + + return ret; } @@ -165,7 +165,7 @@ int xs_exists(struct xs_handle *h, const * This assumes that the domain name we are looking for is unique. * Name parameter Domain-0 */ -char *get_dom_domid(struct xs_handle *h, const char *name) +char *get_dom_domid(struct xs_handle *h) { char **e, *val, *domid = NULL; unsigned int num, len; @@ -179,7 +179,9 @@ char *get_dom_domid(struct xs_handle *h, } e = xs_directory(h, xth, "/local/domain", &num); - + if (e == NULL) + return NULL; + for (i = 0; (i < num) && (domid == NULL); i++) { asprintf(&path, "/local/domain/%s/name", e[i]); val = xs_read(h, xth, path, &len); @@ -187,7 +189,7 @@ char *get_dom_domid(struct xs_handle *h, if (val == NULL) continue; - if (strcmp(val, name) == 0) { + if (strcmp(val, DOMNAME) == 0) { /* match! */ asprintf(&path, "/local/domain/%s/domid", e[i]); domid = xs_read(h, xth, path, &len); @@ -249,12 +251,12 @@ int convert_dev_name_to_num(char *name) ret = BASE_DEV_VAL; } - free(p_sd); - free(p_hd); - free(p_xvd); - free(p_plx); - free(alpha); - + free(p_sd); + free(p_hd); + free(p_xvd); + free(p_plx); + free(alpha); + return ret; } @@ -281,42 +283,39 @@ int register_xenbus_watch(struct xs_hand { /* Pointer in ascii is the token. */ char token[sizeof(watch) * 2 + 1]; - int er; - + sprintf(token, "%lX", (long)watch); - if (find_watch(token)) - { + if (find_watch(token)) { DPRINTF("watch collision!\n"); return -EINVAL; } - er = xs_watch(h, watch->node, token); - if (er != 0) { - list_add(&watch->list, &watches); - } - - return er; + if (!xs_watch(h, watch->node, token)) { + DPRINTF("unable to set watch!\n"); + return -EINVAL; + } + + list_add(&watch->list, &watches); + + return 0; } int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch) { char token[sizeof(watch) * 2 + 1]; - int er; sprintf(token, "%lX", (long)watch); - if (!find_watch(token)) - { + if (!find_watch(token)) { DPRINTF("no such watch!\n"); return -EINVAL; } - - - er = xs_unwatch(h, watch->node, token); + + if (!xs_unwatch(h, watch->node, token)) + DPRINTF("XENBUS Failed to release watch %s: %i\n", + watch->node, er); + list_del(&watch->list); - if (er == 0) - DPRINTF("XENBUS Failed to release watch %s: %i\n", - watch->node, er); return 0; } @@ -354,14 +353,10 @@ int xs_fire_next_watch(struct xs_handle token = res[XS_WATCH_TOKEN]; w = find_watch(token); - if (!w) - { - DPRINTF("unregistered watch fired\n"); - goto done; - } - w->callback(h, w, node); - - done: + if (w) + w->callback(h, w, node); + free(res); + return 1; } diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xs_api.h --- a/tools/blktap/lib/xs_api.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/blktap/lib/xs_api.h Wed Oct 11 13:04:07 2006 -0400 @@ -42,7 +42,7 @@ int xs_printf(struct xs_handle *h, const int xs_printf(struct xs_handle *h, const char *dir, const char *node, const char *fmt, ...); int xs_exists(struct xs_handle *h, const char *path); -char *get_dom_domid(struct xs_handle *h, const char *name); +char *get_dom_domid(struct xs_handle *h); int convert_dev_name_to_num(char *name); int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch); int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch); diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/block --- a/tools/examples/block Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/block Wed Oct 11 13:04:07 2006 -0400 @@ -377,7 +377,6 @@ mount it read-write in a guest domain." "") claim_lock "block" success - echo happy gun \"$t\" >>/tmp/block.$$ release_lock "block" ;; esac diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/init.d/xendomains --- a/tools/examples/init.d/xendomains Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/init.d/xendomains Wed Oct 11 13:04:07 2006 -0400 @@ -352,9 +352,9 @@ stop() if test $? -ne 0; then rc_failed $? echo -n '!' - kill $WDOG_PIG >/dev/null 2>&1 - else - kill $WDOG_PIG >/dev/null 2>&1 + kill $WDOG_PID >/dev/null 2>&1 + else + kill $WDOG_PID >/dev/null 2>&1 continue fi fi @@ -368,7 +368,7 @@ stop() rc_failed $? echo -n '!' fi - kill $WDOG_PIG >/dev/null 2>&1 + kill $WDOG_PID >/dev/null 2>&1 fi done < <(xm list | grep -v '^Name') diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/locking.sh --- a/tools/examples/locking.sh Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/locking.sh Wed Oct 11 13:04:07 2006 -0400 @@ -21,7 +21,7 @@ LOCK_SLEEPTIME=1 LOCK_SPINNING_RETRIES=5 -LOCK_RETRIES=10 +LOCK_RETRIES=100 LOCK_BASEDIR=/var/run/xen-hotplug diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xen-backend.rules --- a/tools/examples/xen-backend.rules Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/xen-backend.rules Wed Oct 11 13:04:07 2006 -0400 @@ -5,3 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif*" SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline" SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup" KERNEL=="evtchn", NAME="xen/%k" +KERNEL=="blktap[0-9]*", NAME="xen/%k" diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xend-config.sxp --- a/tools/examples/xend-config.sxp Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/xend-config.sxp Wed Oct 11 13:04:07 2006 -0400 @@ -130,3 +130,8 @@ # The tool used for initiating virtual TPM migration #(external-migration-tool '') + +# The interface for VNC servers to listen on. Defaults +# to 127.0.0.1 To restore old 'listen everywhere' behaviour +# set this to 0.0.0.0 +#(vnc-listen '127.0.0.1') diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xmexample.hvm --- a/tools/examples/xmexample.hvm Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/examples/xmexample.hvm Wed Oct 11 13:04:07 2006 -0400 @@ -132,6 +132,11 @@ vnc=1 vnc=1 #---------------------------------------------------------------------------- +# address that should be listened on for the VNC server if vnc is set. +# default is to use 'vnc-listen' setting from /etc/xen/xend-config.sxp +#vnclisten="127.0.0.1" + +#---------------------------------------------------------------------------- # set VNC display number, default = domid #vncdisplay=1 diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Oct 11 13:04:07 2006 -0400 @@ -170,6 +170,9 @@ main(void) init_hypercalls(); + puts("Writing SMBIOS tables ...\n"); + hvm_write_smbios_tables(); + puts("Loading ROMBIOS ...\n"); memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios)); @@ -201,9 +204,6 @@ main(void) } } - puts("Writing SMBIOS tables ...\n"); - hvm_write_smbios_tables(); - if (check_amd()) { /* AMD implies this is SVM */ puts("SVM go ...\n"); diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/firmware/hvmloader/smbios.c Wed Oct 11 13:04:07 2006 -0400 @@ -28,23 +28,15 @@ #include "util.h" #include "hypercall.h" -/* write SMBIOS tables starting at 'start', without writing more - than 'max_size' bytes. - - Return the number of bytes written -*/ static size_t -write_smbios_tables(void *start, size_t max_size, +write_smbios_tables(void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, uint32_t xen_major_version, uint32_t xen_minor_version); static void get_cpu_manufacturer(char *buf, int len); -static size_t -smbios_table_size(uint32_t vcpus, const char *xen_version, - const char *processor_manufacturer); -static void * +static void smbios_entry_point_init(void *start, uint16_t max_structure_size, uint16_t structure_table_length, @@ -71,7 +63,7 @@ smbios_type_20_init(void *start, uint32_ smbios_type_20_init(void *start, uint32_t memory_size_mb); static void * smbios_type_32_init(void *start); -void * +static void * smbios_type_127_init(void *start); static void @@ -80,7 +72,8 @@ get_cpu_manufacturer(char *buf, int len) char id[12]; uint32_t eax = 0; - cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], (uint32_t *)&id[4]); + cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], + (uint32_t *)&id[4]); if (memcmp(id, "GenuineIntel", 12) == 0) strncpy(buf, "Intel", len); @@ -90,90 +83,51 @@ get_cpu_manufacturer(char *buf, int len) strncpy(buf, "unknown", len); } - -/* Calculate the size of the SMBIOS structure table. -*/ static size_t -smbios_table_size(uint32_t vcpus, const char *xen_version, - const char *processor_manufacturer) -{ - size_t size; - - /* first compute size without strings or terminating 0 bytes */ - size = sizeof(struct smbios_type_0) + sizeof(struct smbios_type_1) + - sizeof(struct smbios_type_3) + sizeof(struct smbios_type_4)*vcpus + - sizeof(struct smbios_type_16) + sizeof(struct smbios_type_17) + - sizeof(struct smbios_type_19) + sizeof(struct smbios_type_20) + - sizeof(struct smbios_type_32) + sizeof(struct smbios_type_127); - - /* 5 structures with no strings, 2 null bytes each */ - size += 10; - - /* Need to include 1 null byte per structure with strings (first - terminating null byte comes from the string terminator of the - last string). */ - size += 4 + vcpus; - - /* type 0: "Xen", xen_version, and release_date */ - size += strlen("Xen") + strlen(xen_version) + 2; - /* type 1: "Xen", xen_version, "HVM domU", UUID as string for - serial number */ - size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) + - 36 + 4; - /* type 3: "Xen" */ - size += strlen("Xen") + 1; - /* type 4: socket designation ("CPU n"), processor_manufacturer */ - size += vcpus * (strlen("CPU n") + strlen(processor_manufacturer) + 2); - /* Make room for two-digit CPU numbers if necessary -- doesn't handle - vcpus > 99 */ - if (vcpus > 9) - size += vcpus - 9; - /* type 17: device locator string ("DIMM 1") */ - size += strlen("DIMM 1") + 1; - - return size; -} - -static size_t -write_smbios_tables(void *start, size_t max_size, +write_smbios_tables(void *start, uint32_t vcpus, uint64_t memsize, uint8_t uuid[16], char *xen_version, uint32_t xen_major_version, uint32_t xen_minor_version) { - unsigned cpu_num; - void *p = start; + unsigned cpu_num, nr_structs = 0, max_struct_size = 0; + char *p, *q; char cpu_manufacturer[15]; size_t structure_table_length; get_cpu_manufacturer(cpu_manufacturer, 15); - - structure_table_length = smbios_table_size(vcpus, xen_version, - cpu_manufacturer); - - if (structure_table_length + sizeof(struct smbios_entry_point) > max_size) - return 0; - - p = smbios_entry_point_init(p, sizeof(struct smbios_type_4), - structure_table_length, - (uint32_t)start + - sizeof(struct smbios_entry_point), - 9 + vcpus); - - p = smbios_type_0_init(p, xen_version, xen_major_version, - xen_minor_version); - p = smbios_type_1_init(p, xen_version, uuid); - p = smbios_type_3_init(p); - for (cpu_num = 1; cpu_num <= vcpus; ++cpu_num) - p = smbios_type_4_init(p, cpu_num, cpu_manufacturer); - p = smbios_type_16_init(p, memsize); - p = smbios_type_17_init(p, memsize); - p = smbios_type_19_init(p, memsize); - p = smbios_type_20_init(p, memsize); - p = smbios_type_32_init(p); - p = smbios_type_127_init(p); - - return (size_t)((char*)p - (char*)start); + p = (char *)start + sizeof(struct smbios_entry_point); + +#define do_struct(fn) do { \ + q = (fn); \ + nr_structs++; \ + if ((q - p) > max_struct_size) \ + max_struct_size = q - p; \ + p = q; \ +} while (0) + + do_struct(smbios_type_0_init(p, xen_version, xen_major_version, + xen_minor_version)); + do_struct(smbios_type_1_init(p, xen_version, uuid)); + do_struct(smbios_type_3_init(p)); + for (cpu_num = 1; cpu_num <= vcpus; cpu_num++) + do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer)); + do_struct(smbios_type_16_init(p, memsize)); + do_struct(smbios_type_17_init(p, memsize)); + do_struct(smbios_type_19_init(p, memsize)); + do_struct(smbios_type_20_init(p, memsize)); + do_struct(smbios_type_32_init(p)); + do_struct(smbios_type_127_init(p)); + +#undef do_struct + + smbios_entry_point_init( + start, max_struct_size, + (p - (char *)start) - sizeof(struct smbios_entry_point), + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), + nr_structs); + + return (size_t)((char *)p - (char *)start); } /* This tries to figure out how much pseudo-physical memory (in MB) @@ -278,10 +232,16 @@ hvm_write_smbios_tables(void) xen_version_str[sizeof(xen_version_str)-1] = '\0'; - write_smbios_tables((void *) SMBIOS_PHYSICAL_ADDRESS, - SMBIOS_SIZE_LIMIT, get_vcpu_nr(), get_memsize(), - uuid, xen_version_str, - xen_major_version, xen_minor_version); + /* NB. 0xC0000 is a safe large memory area for scratch. */ + len = write_smbios_tables((void *)0xC0000, + get_vcpu_nr(), get_memsize(), + uuid, xen_version_str, + xen_major_version, xen_minor_version); + if (len > SMBIOS_SIZE_LIMIT) + goto error_out; + /* Okay, not too large: copy out of scratch to final location. */ + memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); + return; error_out: @@ -290,7 +250,7 @@ hvm_write_smbios_tables(void) } -static void * +static void smbios_entry_point_init(void *start, uint16_t max_structure_size, uint16_t structure_table_length, @@ -327,8 +287,6 @@ smbios_entry_point_init(void *start, for (i = 0x10; i < ep->length; ++i) sum += ((int8_t *)start)[i]; ep->intermediate_checksum = -sum; - - return (char *)start + sizeof(struct smbios_entry_point); } /* Type 0 -- BIOS Information */ @@ -476,7 +434,7 @@ smbios_type_4_init(void *start, unsigned start += strlen(buf) + 1; strcpy((char *)start, cpu_manufacturer); - start += strlen(buf) + 1; + start += strlen(cpu_manufacturer) + 1; *((uint8_t *)start) = 0; return start+1; @@ -597,7 +555,7 @@ smbios_type_32_init(void *start) } /* Type 127 -- End of Table */ -void * +static void * smbios_type_127_init(void *start) { struct smbios_type_127 *p = (struct smbios_type_127 *)start; diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/vmxassist/machine.h --- a/tools/firmware/vmxassist/machine.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/firmware/vmxassist/machine.h Wed Oct 11 13:04:07 2006 -0400 @@ -36,6 +36,7 @@ #define CR4_VME (1 << 0) #define CR4_PVI (1 << 1) #define CR4_PSE (1 << 4) +#define CR4_PAE (1 << 5) #define EFLAGS_ZF (1 << 6) #define EFLAGS_TF (1 << 8) diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/firmware/vmxassist/vm86.c Wed Oct 11 13:04:07 2006 -0400 @@ -52,29 +52,63 @@ static char *rnames[] = { "ax", "cx", "d static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; #endif /* DEBUG */ +#define PDE_PS (1 << 7) #define PT_ENTRY_PRESENT 0x1 +/* We only support access to <=4G physical memory due to 1:1 mapping */ static unsigned -guest_linear_to_real(unsigned long base, unsigned off) -{ - unsigned int gcr3 = oldctx.cr3; - unsigned int l1_mfn; - unsigned int l0_mfn; +guest_linear_to_real(uint32_t base) +{ + uint32_t gcr3 = oldctx.cr3; + uint64_t l2_mfn; + uint64_t l1_mfn; + uint64_t l0_mfn; if (!(oldctx.cr0 & CR0_PG)) - return base + off; - - l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ]; - if (!(l1_mfn & PT_ENTRY_PRESENT)) - panic("l2 entry not present\n"); - l1_mfn = l1_mfn & 0xfffff000 ; - - l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff]; - if (!(l0_mfn & PT_ENTRY_PRESENT)) - panic("l1 entry not present\n"); - l0_mfn = l0_mfn & 0xfffff000; - - return l0_mfn + off + (base & 0xfff); + return base; + + if (!(oldctx.cr4 & CR4_PAE)) { + l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + + if ((oldctx.cr4 & CR4_PSE) && (l1_mfn & PDE_PS)) { + l0_mfn = l1_mfn & 0xffc00000; + return l0_mfn + (base & 0x3fffff); + } + + l1_mfn &= 0xfffff000; + + l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0xfffff000; + + return l0_mfn + (base & 0xfff); + } else { + l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3]; + if (!(l2_mfn & PT_ENTRY_PRESENT)) + panic("l3 entry not present\n"); + l2_mfn &= 0x3fffff000ULL; + + l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 0x1ff]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + + if (l1_mfn & PDE_PS) { /* CR4.PSE is ignored in PAE mode */ + l0_mfn = l1_mfn & 0x3ffe00000ULL; + return l0_mfn + (base & 0x1fffff); + } + + l1_mfn &= 0x3fffff000ULL; + + l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 0x1ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0x3fffff000ULL; + + return l0_mfn + (base & 0xfff); + } } static unsigned @@ -95,7 +129,8 @@ address(struct regs *regs, unsigned seg, (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg)) return ((seg & 0xFFFF) << 4) + off; - entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[seg >> 3]; + entry = ((unsigned long long *) + guest_linear_to_real(oldctx.gdtr_base))[seg >> 3]; entry_high = entry >> 32; entry_low = entry & 0xFFFFFFFF; @@ -780,7 +815,8 @@ load_seg(unsigned long sel, uint32_t *ba return 1; } - entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[sel >> 3]; + entry = ((unsigned long long *) + guest_linear_to_real(oldctx.gdtr_base))[sel >> 3]; /* Check the P bit first */ if (!((entry >> (15+32)) & 0x1) && sel != 0) @@ -1193,6 +1229,18 @@ pushrm(struct regs *regs, int prefix, un } enum { OPC_INVALID, OPC_EMULATED }; + +#define rdmsr(msr,val1,val2) \ + __asm__ __volatile__( \ + "rdmsr" \ + : "=a" (val1), "=d" (val2) \ + : "c" (msr)) + +#define wrmsr(msr,val1,val2) \ + __asm__ __volatile__( \ + "wrmsr" \ + : /* no outputs */ \ + : "c" (msr), "a" (val1), "d" (val2)) /* * Emulate a single instruction, including all its prefixes. We only implement @@ -1252,6 +1300,12 @@ opcode(struct regs *regs) if (!movcr(regs, prefix, opc)) goto invalid; return OPC_EMULATED; + case 0x30: /* WRMSR */ + wrmsr(regs->ecx, regs->eax, regs->edx); + return OPC_EMULATED; + case 0x32: /* RDMSR */ + rdmsr(regs->ecx, regs->eax, regs->edx); + return OPC_EMULATED; default: goto invalid; } @@ -1376,12 +1430,14 @@ opcode(struct regs *regs) { int addr, data; int seg = segment(prefix, regs, regs->vds); + int offset = prefix & ADDR32? fetch32(regs) : fetch16(regs); + if (prefix & DATA32) { - addr = address(regs, seg, fetch32(regs)); + addr = address(regs, seg, offset); data = read32(addr); setreg32(regs, 0, data); } else { - addr = address(regs, seg, fetch16(regs)); + addr = address(regs, seg, offset); data = read16(addr); setreg16(regs, 0, data); } diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/serial.c --- a/tools/ioemu/hw/serial.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/hw/serial.c Wed Oct 11 13:04:07 2006 -0400 @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "vl.h" +#include <sys/time.h> +#include <time.h> +#include <assert.h> //#define DEBUG_SERIAL @@ -138,6 +141,67 @@ static void serial_update_parameters(Ser printf("speed=%d parity=%c data=%d stop=%d\n", speed, parity, data_bits, stop_bits); #endif +} + +/* Rate limit serial requests so that e.g. grub on a serial console + doesn't kill dom0. Simple token bucket. If we get some actual + data from the user, instantly refil the bucket. */ + +/* How long it takes to generate a token, in microseconds. */ +#define TOKEN_PERIOD 1000 +/* Maximum and initial size of token bucket */ +#define TOKENS_MAX 100000 + +static int tokens_avail; + +static void serial_get_token(void) +{ + static struct timeval last_refil_time; + static int started; + + assert(tokens_avail >= 0); + if (!tokens_avail) { + struct timeval delta, now; + int generated; + + if (!started) { + gettimeofday(&last_refil_time, NULL); + tokens_avail = TOKENS_MAX; + started = 1; + return; + } + retry: + gettimeofday(&now, NULL); + delta.tv_sec = now.tv_sec - last_refil_time.tv_sec; + delta.tv_usec = now.tv_usec - last_refil_time.tv_usec; + if (delta.tv_usec < 0) { + delta.tv_usec += 1000000; + delta.tv_sec--; + } + assert(delta.tv_usec >= 0 && delta.tv_sec >= 0); + if (delta.tv_usec < TOKEN_PERIOD) { + struct timespec ts; + /* Wait until at least one token is available. */ + ts.tv_sec = TOKEN_PERIOD / 1000000; + ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000; + while (nanosleep(&ts, &ts) < 0 && errno == EINTR) + ; + goto retry; + } + generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD; + generated += + ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / TOKEN_PERIOD; + assert(generated > 0); + + last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000; + last_refil_time.tv_sec += last_refil_time.tv_usec / 1000000; + last_refil_time.tv_usec %= 1000000; + last_refil_time.tv_sec += (generated * TOKEN_PERIOD) / 1000000; + if (generated > TOKENS_MAX) + generated = TOKENS_MAX; + tokens_avail = generated; + } + tokens_avail--; } static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -245,9 +309,11 @@ static uint32_t serial_ioport_read(void ret = s->mcr; break; case 5: + serial_get_token(); ret = s->lsr; break; case 6: + serial_get_token(); if (s->mcr & UART_MCR_LOOP) { /* in loopback, the modem output pins are connected to the inputs */ @@ -296,12 +362,14 @@ static void serial_receive1(void *opaque static void serial_receive1(void *opaque, const uint8_t *buf, int size) { SerialState *s = opaque; + tokens_avail = TOKENS_MAX; serial_receive_byte(s, buf[0]); } static void serial_event(void *opaque, int event) { SerialState *s = opaque; + tokens_avail = TOKENS_MAX; if (event == CHR_EVENT_BREAK) serial_receive_break(s); } diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/hw/vga.c Wed Oct 11 13:04:07 2006 -0400 @@ -1463,14 +1463,15 @@ void check_sse2(void) */ static void vga_draw_graphic(VGAState *s, int full_update) { - int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask; + int y1, y, update, linesize, y_start, double_scan, mask; int width, height, shift_control, line_offset, bwidth; ram_addr_t page0, page1; int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; - + ram_addr_t page_min, page_max; + full_update |= update_basic_params(s); s->get_resolution(s, &width, &height); @@ -1561,8 +1562,8 @@ static void vga_draw_graphic(VGAState *s addr1 = (s->start_addr * 4); bwidth = width * 4; y_start = -1; - page_min = 0x7fffffff; - page_max = -1; + page_min = 0; + page_max = 0; d = s->ds->data; linesize = s->ds->linesize; y1 = 0; @@ -1592,9 +1593,9 @@ static void vga_draw_graphic(VGAState *s if (update) { if (y_start < 0) y_start = y; - if (page0 < page_min) + if (page_min == 0 || page0 < page_min) page_min = page0; - if (page1 > page_max) + if (page_max == 0 || page1 > page_max) page_max = page1; vga_draw_line(s, d, s->vram_ptr + addr, width); if (s->cursor_draw_line) diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/xen_platform.c --- a/tools/ioemu/hw/xen_platform.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/hw/xen_platform.c Wed Oct 11 13:04:07 2006 -0400 @@ -116,10 +116,10 @@ void pci_xen_platform_init(PCIBus *bus) d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL, NULL); pch = (struct pci_config_header *)d->config; - pch->vendor_id = 0xfffd; - pch->device_id = 0x0101; + pch->vendor_id = 0x5853; + pch->device_id = 0x0001; pch->command = 3; /* IO and memory access */ - pch->revision = 0; + pch->revision = 1; pch->api = 0; pch->subclass = 0x80; /* Other */ pch->class = 0xff; /* Unclassified device class */ diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/domain-timeoffset --- a/tools/ioemu/patches/domain-timeoffset Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/domain-timeoffset Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/hw/mc146818rtc.c Index: ioemu/hw/mc146818rtc.c =================================================================== ---- ioemu.orig/hw/mc146818rtc.c 2006-08-17 19:58:03.222720593 +0100 -+++ ioemu/hw/mc146818rtc.c 2006-08-17 19:58:08.528134087 +0100 +--- ioemu.orig/hw/mc146818rtc.c 2006-09-21 19:33:25.000000000 +0100 ++++ ioemu/hw/mc146818rtc.c 2006-09-21 19:33:30.000000000 +0100 @@ -178,10 +178,27 @@ } } @@ -46,8 +46,8 @@ Index: ioemu/hw/mc146818rtc.c static void rtc_copy_date(RTCState *s) Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:58:08.252164595 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:58:08.529133976 +0100 +--- ioemu.orig/hw/pc.c 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/hw/pc.c 2006-09-21 19:33:30.000000000 +0100 @@ -159,7 +159,7 @@ } @@ -117,8 +117,8 @@ Index: ioemu/hw/pc.c QEMUMachine pc_machine = { Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:58:08.395148788 +0100 -+++ ioemu/vl.c 2006-08-17 19:58:08.532133645 +0100 +--- ioemu.orig/vl.c 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:30.000000000 +0100 @@ -163,6 +163,8 @@ int xc_handle; @@ -174,8 +174,8 @@ Index: ioemu/vl.c if (usb_enabled) { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:58:08.257164042 +0100 -+++ ioemu/vl.h 2006-08-17 19:58:08.532133645 +0100 +--- ioemu.orig/vl.h 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:30.000000000 +0100 @@ -576,7 +576,7 @@ int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-bootorder --- a/tools/ioemu/patches/qemu-bootorder Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/qemu-bootorder Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-20 22:22:36.000000000 +0100 -+++ ioemu/vl.c 2006-08-20 23:22:25.000000000 +0100 +--- ioemu.orig/vl.c 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100 @@ -124,7 +124,7 @@ int vncunused; const char* keyboard_layout = NULL; @@ -11,7 +11,7 @@ Index: ioemu/vl.c uint64_t ram_size; int pit_min_timer_count = 0; int nb_nics; -@@ -6057,14 +6057,14 @@ +@@ -6063,14 +6063,14 @@ break; #endif /* !CONFIG_DM */ case QEMU_OPTION_boot: @@ -32,7 +32,7 @@ Index: ioemu/vl.c exit(1); } break; -@@ -6328,6 +6328,7 @@ +@@ -6334,6 +6334,7 @@ fd_filename[0] == '\0') help(); @@ -40,7 +40,7 @@ Index: ioemu/vl.c /* boot to cd by default if no hard disk */ if (hd_filename[0] == '\0' && boot_device == 'c') { if (fd_filename[0] != '\0') -@@ -6335,6 +6336,7 @@ +@@ -6341,6 +6342,7 @@ else boot_device = 'd'; } @@ -48,7 +48,7 @@ Index: ioemu/vl.c #endif /* !CONFIG_DM */ setvbuf(stdout, NULL, _IOLBF, 0); -@@ -6593,6 +6595,7 @@ +@@ -6599,6 +6601,7 @@ ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, initrd_filename, timeoffset); @@ -58,9 +58,9 @@ Index: ioemu/vl.c if (usb_enabled) { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-20 22:22:36.000000000 +0100 -+++ ioemu/vl.h 2006-08-20 23:22:25.000000000 +0100 -@@ -575,7 +575,7 @@ +--- ioemu.orig/vl.h 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100 +@@ -576,7 +576,7 @@ #ifndef QEMU_TOOL typedef void QEMUMachineInitFunc(uint64_t ram_size, int vga_ram_size, @@ -69,7 +69,7 @@ Index: ioemu/vl.h DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, time_t timeoffset); -@@ -1020,7 +1020,7 @@ +@@ -1021,7 +1021,7 @@ uint32_t start, uint32_t count); int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, const unsigned char *arch, @@ -80,8 +80,8 @@ Index: ioemu/vl.h uint32_t initrd_image, uint32_t initrd_size, Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-20 22:22:36.000000000 +0100 -+++ ioemu/hw/pc.c 2006-08-20 23:27:55.000000000 +0100 +--- ioemu.orig/hw/pc.c 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/hw/pc.c 2006-09-21 19:33:32.000000000 +0100 @@ -158,8 +158,23 @@ rtc_set_memory(s, info_ofs + 8, sectors); } diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-daemonize --- a/tools/ioemu/patches/qemu-daemonize Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/qemu-daemonize Wed Oct 11 13:04:07 2006 -0400 @@ -2,9 +2,9 @@ Changes required because qemu-dm runs da Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-16 15:11:32.575865776 +0100 -+++ ioemu/vl.c 2006-08-16 15:11:36.217465702 +0100 -@@ -6036,10 +6036,11 @@ +--- ioemu.orig/vl.c 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100 +@@ -6042,10 +6042,11 @@ } break; case QEMU_OPTION_nographic: diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-pci --- a/tools/ioemu/patches/qemu-pci Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/qemu-pci Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,8 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci. -diff -r d5eb5205ff35 tools/ioemu/hw/pci.c ---- a/tools/ioemu/hw/pci.c Thu Aug 24 16:25:49 2006 +0100 -+++ b/tools/ioemu/hw/pci.c Fri Aug 25 11:00:03 2006 +0800 -@@ -286,6 +286,7 @@ void pci_default_write_config(PCIDevice +Index: ioemu/hw/pci.c +=================================================================== +--- ioemu.orig/hw/pci.c 2006-09-21 11:31:14.000000000 +0100 ++++ ioemu/hw/pci.c 2006-09-21 11:31:32.000000000 +0100 +@@ -286,6 +286,7 @@ case 0x0b: case 0x0e: case 0x10 ... 0x27: /* base */ @@ -9,7 +10,7 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci. case 0x30 ... 0x33: /* rom */ case 0x3d: can_write = 0; -@@ -318,6 +319,18 @@ void pci_default_write_config(PCIDevice +@@ -318,6 +319,18 @@ break; } if (can_write) { @@ -28,10 +29,11 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci. d->config[addr] = val; } addr++; -diff -r d5eb5205ff35 tools/ioemu/hw/rtl8139.c ---- a/tools/ioemu/hw/rtl8139.c Thu Aug 24 16:25:49 2006 +0100 -+++ b/tools/ioemu/hw/rtl8139.c Fri Aug 25 11:00:03 2006 +0800 -@@ -3423,6 +3423,8 @@ void pci_rtl8139_init(PCIBus *bus, NICIn +Index: ioemu/hw/rtl8139.c +=================================================================== +--- ioemu.orig/hw/rtl8139.c 2006-09-21 11:31:14.000000000 +0100 ++++ ioemu/hw/rtl8139.c 2006-09-21 11:31:32.000000000 +0100 +@@ -3423,6 +3423,8 @@ pci_conf[0x0e] = 0x00; /* header_type */ pci_conf[0x3d] = 1; /* interrupt pin 0 */ pci_conf[0x34] = 0xdc; @@ -40,10 +42,11 @@ diff -r d5eb5205ff35 tools/ioemu/hw/rtl8 s = &d->rtl8139; -diff -r d5eb5205ff35 tools/ioemu/hw/usb-uhci.c ---- a/tools/ioemu/hw/usb-uhci.c Thu Aug 24 16:25:49 2006 +0100 -+++ b/tools/ioemu/hw/usb-uhci.c Fri Aug 25 11:00:03 2006 +0800 -@@ -659,6 +659,8 @@ void usb_uhci_init(PCIBus *bus, int devf +Index: ioemu/hw/usb-uhci.c +=================================================================== +--- ioemu.orig/hw/usb-uhci.c 2006-09-21 11:31:14.000000000 +0100 ++++ ioemu/hw/usb-uhci.c 2006-09-21 11:31:32.000000000 +0100 +@@ -659,6 +659,8 @@ pci_conf[0x0e] = 0x00; // header_type pci_conf[0x3d] = 4; // interrupt pin 3 pci_conf[0x60] = 0x10; // release number diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-target-i386-dm --- a/tools/ioemu/patches/qemu-target-i386-dm Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/qemu-target-i386-dm Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-08 11:24:33.479955101 +0100 -+++ ioemu/Makefile.target 2006-08-08 11:24:39.008338255 +0100 +--- ioemu.orig/Makefile.target 2006-09-21 11:30:11.000000000 +0100 ++++ ioemu/Makefile.target 2006-09-21 18:54:22.000000000 +0100 @@ -62,6 +62,8 @@ QEMU_SYSTEM=qemu-fast endif @@ -32,8 +32,8 @@ Index: ioemu/Makefile.target DEFINES += -DHAS_AUDIO Index: ioemu/configure =================================================================== ---- ioemu.orig/configure 2006-08-08 11:24:33.480954990 +0100 -+++ ioemu/configure 2006-08-08 11:24:38.122437102 +0100 +--- ioemu.orig/configure 2006-09-21 11:30:11.000000000 +0100 ++++ ioemu/configure 2006-09-21 18:54:21.000000000 +0100 @@ -373,6 +373,8 @@ if [ "$user" = "yes" ] ; then target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list" @@ -45,8 +45,8 @@ Index: ioemu/configure fi Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-08-08 11:24:33.484954543 +0100 -+++ ioemu/monitor.c 2006-08-08 11:24:39.253310921 +0100 +--- ioemu.orig/monitor.c 2006-09-21 11:30:11.000000000 +0100 ++++ ioemu/monitor.c 2006-09-21 18:54:23.000000000 +0100 @@ -1262,6 +1262,10 @@ "", "show profiling information", }, { "capture", "", do_info_capture, @@ -60,8 +60,8 @@ Index: ioemu/monitor.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-08 11:24:33.486954320 +0100 -+++ ioemu/vl.c 2006-08-08 11:24:39.454288496 +0100 +--- ioemu.orig/vl.c 2006-09-21 11:30:11.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 18:54:23.000000000 +0100 @@ -87,7 +87,7 @@ #include "exec-all.h" @@ -98,8 +98,8 @@ Index: ioemu/vl.c { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-08 11:24:31.082222636 +0100 -+++ ioemu/vl.h 2006-08-08 11:24:39.454288496 +0100 +--- ioemu.orig/vl.h 2006-09-21 11:30:11.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 18:54:23.000000000 +0100 @@ -37,6 +37,8 @@ #include <unistd.h> #include <fcntl.h> @@ -132,7 +132,7 @@ Index: ioemu/target-i386-dm/cpu.h Index: ioemu/target-i386-dm/cpu.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/cpu.h 2006-08-08 11:24:39.099328102 +0100 ++++ ioemu/target-i386-dm/cpu.h 2006-09-21 18:54:22.000000000 +0100 @@ -0,0 +1,86 @@ +/* + * i386 virtual CPU header @@ -223,7 +223,7 @@ Index: ioemu/target-i386-dm/exec-dm.c Index: ioemu/target-i386-dm/exec-dm.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/exec-dm.c 2006-08-08 11:24:39.099328102 +0100 ++++ ioemu/target-i386-dm/exec-dm.c 2006-09-21 18:54:22.000000000 +0100 @@ -0,0 +1,516 @@ +/* + * virtual page mapping and translated block handling @@ -744,7 +744,7 @@ Index: ioemu/target-i386-dm/helper2.c Index: ioemu/target-i386-dm/helper2.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/helper2.c 2006-08-08 11:24:44.888682140 +0100 ++++ ioemu/target-i386-dm/helper2.c 2006-09-21 18:55:31.000000000 +0100 @@ -0,0 +1,469 @@ +/* + * i386 helpers (without register variable usage) @@ -1205,8 +1205,8 @@ Index: ioemu/target-i386-dm/helper2.c + break; + } + -+ /* Wait up to 10 msec. */ -+ main_loop_wait(10); ++ /* Wait up to 100 msec. */ ++ main_loop_wait(100); + + if (env->send_event) { + env->send_event = 0; @@ -1218,7 +1218,7 @@ Index: ioemu/target-i386-dm/i8259-dm.c Index: ioemu/target-i386-dm/i8259-dm.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/i8259-dm.c 2006-08-08 11:24:33.505952200 +0100 ++++ ioemu/target-i386-dm/i8259-dm.c 2006-09-21 11:30:11.000000000 +0100 @@ -0,0 +1,107 @@ +/* Xen 8259 stub for interrupt controller emulation + * @@ -1330,7 +1330,7 @@ Index: ioemu/target-i386-dm/qemu-dm.debu Index: ioemu/target-i386-dm/qemu-dm.debug =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/qemu-dm.debug 2006-08-08 11:24:33.505952200 +0100 ++++ ioemu/target-i386-dm/qemu-dm.debug 2006-09-21 11:30:11.000000000 +0100 @@ -0,0 +1,5 @@ +#!/bin/sh + @@ -1340,7 +1340,7 @@ Index: ioemu/target-i386-dm/qemu-ifup Index: ioemu/target-i386-dm/qemu-ifup =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/qemu-ifup 2006-08-08 11:24:33.505952200 +0100 ++++ ioemu/target-i386-dm/qemu-ifup 2006-09-21 11:30:11.000000000 +0100 @@ -0,0 +1,10 @@ +#!/bin/sh + diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/series --- a/tools/ioemu/patches/series Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/series Wed Oct 11 13:04:07 2006 -0400 @@ -29,12 +29,14 @@ acpi-support acpi-support acpi-timer-support acpi-poweroff-support +fix-vga-scanning-code-overflow vnc-cleanup vnc-fixes vnc-start-vncviewer vnc-title-domain-name vnc-access-monitor-vt vnc-display-find-unused +vnc-backoff-screen-scan xenstore-block-device-config xenstore-write-vnc-port qemu-allow-disable-sdl @@ -44,4 +46,4 @@ xen-platform-device xen-platform-device qemu-bootorder qemu-tunable-ide-write-cache -qemu-pci -p3 +qemu-pci diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-access-monitor-vt --- a/tools/ioemu/patches/vnc-access-monitor-vt Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-access-monitor-vt Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:50:14.623519661 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:15.956372339 +0100 +--- ioemu.orig/vnc.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:33:31.000000000 +0100 @@ -32,6 +32,10 @@ #include "vnc_keysym.h" #include "keymaps.c" @@ -22,7 +22,7 @@ Index: ioemu/vnc.c }; #define DIRTY_PIXEL_BITS 64 -@@ -794,16 +800,80 @@ +@@ -791,16 +797,80 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) { diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-cleanup --- a/tools/ioemu/patches/vnc-cleanup Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-cleanup Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:37:36.091553839 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:10.313996001 +0100 +--- ioemu.orig/vnc.c 2006-09-21 18:54:22.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:05:39.000000000 +0100 @@ -143,13 +143,16 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) { @@ -30,7 +30,16 @@ Index: ioemu/vnc.c if (vs->need_update && vs->csock != -1) { int y; -@@ -390,7 +394,7 @@ +@@ -383,6 +387,8 @@ + int saved_offset; + int has_dirty = 0; + ++ qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL); ++ + vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS); + + /* Walk through the dirty map and eliminate tiles that +@@ -390,7 +396,7 @@ row = vs->ds->data; old_row = vs->old_data; @@ -39,34 +48,50 @@ Index: ioemu/vnc.c if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) { int x; char *ptr, *old_ptr; -@@ -415,10 +419,8 @@ +@@ -415,10 +421,8 @@ old_row += vs->ds->linesize; } - if (!has_dirty) { - qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL); -- return; ++ if (!has_dirty) + return; - } -+ if (!has_dirty) -+ goto out; /* Count rectangles */ n_rectangles = 0; -@@ -456,7 +458,9 @@ +@@ -454,17 +458,13 @@ + vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; + vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF; vnc_flush(vs); - +- } - qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL); -+ -+ out: -+ qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL); } static void vnc_timer_init(VncState *vs) + { +- if (vs->timer == NULL) { ++ if (vs->timer == NULL) + vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs); +- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); +- } + } + + static void vnc_dpy_refresh(DisplayState *ds) +@@ -736,6 +736,8 @@ + old_row += vs->ds->linesize; + } + } ++ ++ qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); + } + + static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:02.410869542 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:10.316995669 +0100 +--- ioemu.orig/vl.c 2006-09-21 18:55:38.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:00:48.000000000 +0100 @@ -5120,10 +5120,10 @@ /* XXX: better handling of removal */ for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-display-find-unused --- a/tools/ioemu/patches/vnc-display-find-unused Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-display-find-unused Wed Oct 11 13:04:07 2006 -0400 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:50:15.956372339 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:17.083247783 +0100 -@@ -1183,7 +1183,7 @@ +--- ioemu.orig/vnc.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:33:31.000000000 +0100 +@@ -1182,7 +1182,7 @@ } } @@ -11,7 +11,7 @@ Index: ioemu/vnc.c { struct sockaddr_in addr; int reuse_addr, ret; -@@ -1214,10 +1214,6 @@ +@@ -1213,10 +1213,6 @@ exit(1); } @@ -22,7 +22,7 @@ Index: ioemu/vnc.c reuse_addr = 1; ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_addr, sizeof(reuse_addr)); -@@ -1226,7 +1222,16 @@ +@@ -1225,7 +1221,16 @@ exit(1); } @@ -39,7 +39,7 @@ Index: ioemu/vnc.c fprintf(stderr, "bind() failed\n"); exit(1); } -@@ -1247,6 +1252,8 @@ +@@ -1246,6 +1251,8 @@ vs->ds->dpy_refresh = vnc_dpy_refresh; vnc_dpy_resize(vs->ds, 640, 400); @@ -50,8 +50,8 @@ Index: ioemu/vnc.c int vnc_start_viewer(int port) Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:13.152682236 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:17.086247452 +0100 +--- ioemu.orig/vl.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:31.000000000 +0100 @@ -121,6 +121,7 @@ static DisplayState display_state; int nographic; @@ -115,8 +115,8 @@ Index: ioemu/vl.c } else { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:13.153682125 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:17.087247341 +0100 +--- ioemu.orig/vl.h 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:31.000000000 +0100 @@ -785,7 +785,7 @@ void cocoa_display_init(DisplayState *ds, int full_screen); diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-fixes --- a/tools/ioemu/patches/vnc-fixes Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-fixes Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:10.316995669 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:12.100798502 +0100 +--- ioemu.orig/vl.c 2006-09-21 19:08:18.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:26:24.000000000 +0100 @@ -6534,8 +6534,10 @@ } } @@ -17,8 +17,8 @@ Index: ioemu/vl.c if (use_gdbstub) { Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:50:10.313996001 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:12.101798392 +0100 +--- ioemu.orig/vnc.c 2006-09-21 19:08:18.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:26:38.000000000 +0100 @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Anthony Liguori <anthony@xxxxxxxxxxxxx> @@ -240,7 +240,7 @@ Index: ioemu/vnc.c { VncState *vs = opaque; int64_t now = qemu_get_clock(rt_clock); -@@ -382,12 +445,16 @@ +@@ -382,14 +445,18 @@ int y; char *row; char *old_row; @@ -252,6 +252,8 @@ Index: ioemu/vnc.c + int maxx, maxy; + int tile_bytes = vs->depth * DP2X(vs, 1); + qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL); + - vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS); + if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS)) + width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1; @@ -260,7 +262,7 @@ Index: ioemu/vnc.c /* Walk through the dirty map and eliminate tiles that really aren't dirty */ -@@ -395,23 +462,25 @@ +@@ -397,23 +464,25 @@ old_row = vs->old_data; for (y = 0; y < vs->ds->height; y++) { @@ -295,17 +297,17 @@ Index: ioemu/vnc.c } } -@@ -419,7 +488,8 @@ +@@ -421,7 +490,8 @@ old_row += vs->ds->linesize; } - if (!has_dirty) + if (!vs->has_update || vs->visible_y >= vs->ds->height || + vs->visible_x >= vs->ds->width) - goto out; + return; /* Count rectangles */ -@@ -429,40 +499,61 @@ +@@ -431,34 +501,56 @@ saved_offset = vs->output.offset; vnc_write_u16(vs, 0); @@ -354,32 +356,26 @@ Index: ioemu/vnc.c } vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF; -- vnc_flush(vs); - -- } ++ + vs->has_update = 0; + vs->need_update = 0; -+ vnc_flush(vs); + vnc_flush(vs); +- } + vs->slow_client = 0; + } else + vs->slow_client = 1; - - out: - qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL); - } - ++} ++ +static void vnc_update_client(void *opaque) +{ + VncState *vs = opaque; + + vs->ds->dpy_refresh(vs->ds); + _vnc_update_client(vs); -+} -+ + } + static void vnc_timer_init(VncState *vs) - { - if (vs->timer == NULL) { -@@ -473,8 +564,6 @@ +@@ -469,8 +561,6 @@ static void vnc_dpy_refresh(DisplayState *ds) { @@ -388,7 +384,7 @@ Index: ioemu/vnc.c vga_hw_update(); } -@@ -510,7 +599,7 @@ +@@ -506,7 +596,7 @@ static void buffer_reset(Buffer *buffer) { @@ -397,7 +393,7 @@ Index: ioemu/vnc.c } static void buffer_append(Buffer *buffer, const void *data, size_t len) -@@ -551,12 +640,12 @@ +@@ -547,12 +637,12 @@ if (!ret) return; @@ -413,7 +409,7 @@ Index: ioemu/vnc.c } static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting) -@@ -588,11 +677,11 @@ +@@ -584,11 +674,11 @@ return; if (!ret) { @@ -428,7 +424,7 @@ Index: ioemu/vnc.c } } -@@ -600,9 +689,9 @@ +@@ -596,9 +686,9 @@ { buffer_reserve(&vs->output, len); @@ -441,7 +437,7 @@ Index: ioemu/vnc.c buffer_append(&vs->output, data, len); } -@@ -724,22 +813,25 @@ +@@ -720,22 +810,25 @@ do_key_event(vs, down, sym); } @@ -475,10 +471,10 @@ Index: ioemu/vnc.c + vs->visible_y = y_position; + vs->visible_w = w; + vs->visible_h = h; - } - - static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) -@@ -845,8 +937,6 @@ + + qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); + } +@@ -843,8 +936,6 @@ } vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); @@ -487,7 +483,7 @@ Index: ioemu/vnc.c vga_hw_invalidate(); vga_hw_update(); -@@ -1012,11 +1102,11 @@ +@@ -1010,11 +1101,11 @@ vnc_write(vs, "RFB 003.003\n", 12); vnc_flush(vs); vnc_read_when(vs, protocol_version, 12); @@ -501,7 +497,7 @@ Index: ioemu/vnc.c } } -@@ -1073,17 +1163,15 @@ +@@ -1071,17 +1162,15 @@ exit(1); } @@ -524,8 +520,8 @@ Index: ioemu/vnc.c } Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:02.411869432 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:12.102798281 +0100 +--- ioemu.orig/vl.h 2006-09-21 19:00:48.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:26:24.000000000 +0100 @@ -319,6 +319,7 @@ int is_graphic_console(void); CharDriverState *text_console_init(DisplayState *ds); diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-start-vncviewer --- a/tools/ioemu/patches/vnc-start-vncviewer Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-start-vncviewer Wed Oct 11 13:04:07 2006 -0400 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:50:12.101798392 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:13.149682567 +0100 -@@ -1175,3 +1175,25 @@ +--- ioemu.orig/vnc.c 2006-09-21 19:26:38.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:29:58.000000000 +0100 +@@ -1174,3 +1174,25 @@ vnc_dpy_resize(vs->ds, 640, 400); } @@ -20,7 +20,7 @@ Index: ioemu/vnc.c + exit(1); + + case 0: /* child */ -+ execlp("vncviewer", "vncviewer", s, 0); ++ execlp("vncviewer", "vncviewer", s, NULL); + fprintf(stderr, "vncviewer execlp failed\n"); + exit(1); + @@ -30,8 +30,8 @@ Index: ioemu/vnc.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:12.100798502 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:13.152682236 +0100 +--- ioemu.orig/vl.c 2006-09-21 19:26:24.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:29:50.000000000 +0100 @@ -120,6 +120,7 @@ int bios_size; static DisplayState display_state; @@ -93,8 +93,8 @@ Index: ioemu/vl.c sdl_display_init(ds, full_screen); Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:12.102798281 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:13.153682125 +0100 +--- ioemu.orig/vl.h 2006-09-21 19:26:24.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:29:50.000000000 +0100 @@ -786,6 +786,7 @@ /* vnc.c */ diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-title-domain-name --- a/tools/ioemu/patches/vnc-title-domain-name Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/vnc-title-domain-name Wed Oct 11 13:04:07 2006 -0400 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-08-17 19:50:13.149682567 +0100 -+++ ioemu/vnc.c 2006-08-17 19:50:14.623519661 +0100 -@@ -1014,6 +1014,7 @@ +--- ioemu.orig/vnc.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vnc.c 2006-09-21 19:33:31.000000000 +0100 +@@ -1013,6 +1013,7 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) { @@ -10,7 +10,7 @@ Index: ioemu/vnc.c char pad[3] = { 0, 0, 0 }; vs->width = vs->ds->width; -@@ -1059,8 +1060,10 @@ +@@ -1058,8 +1059,10 @@ vnc_write(vs, pad, 3); /* padding */ diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xen-platform-device --- a/tools/ioemu/patches/xen-platform-device Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/xen-platform-device Wed Oct 11 13:04:07 2006 -0400 @@ -3,8 +3,8 @@ will come later. Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-17 19:50:18.866050726 +0100 -+++ ioemu/Makefile.target 2006-08-17 19:55:35.776020218 +0100 +--- ioemu.orig/Makefile.target 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/Makefile.target 2006-09-21 19:33:32.000000000 +0100 @@ -359,6 +359,7 @@ VL_OBJS+= usb-uhci.o VL_OBJS+= piix4acpi.o @@ -15,8 +15,8 @@ Index: ioemu/Makefile.target ifeq ($(TARGET_BASE_ARCH), ppc) Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:50:02.406869984 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:55:35.777020107 +0100 +--- ioemu.orig/hw/pc.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/hw/pc.c 2006-09-21 19:33:32.000000000 +0100 @@ -823,6 +823,9 @@ } #endif /* !CONFIG_DM */ @@ -30,7 +30,7 @@ Index: ioemu/hw/xen_platform.c Index: ioemu/hw/xen_platform.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/hw/xen_platform.c 2006-08-17 19:55:35.777020107 +0100 ++++ ioemu/hw/xen_platform.c 2006-09-21 19:33:32.000000000 +0100 @@ -0,0 +1,138 @@ +/* + * XEN platform fake pci device, formerly known as the event channel device @@ -150,10 +150,10 @@ Index: ioemu/hw/xen_platform.c + d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL, + NULL); + pch = (struct pci_config_header *)d->config; -+ pch->vendor_id = 0xfffd; -+ pch->device_id = 0x0101; ++ pch->vendor_id = 0x5853; ++ pch->device_id = 0x0001; + pch->command = 3; /* IO and memory access */ -+ pch->revision = 0; ++ pch->revision = 1; + pch->api = 0; + pch->subclass = 0x80; /* Other */ + pch->class = 0xff; /* Unclassified device class */ @@ -172,9 +172,9 @@ Index: ioemu/hw/xen_platform.c +} Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:22.278673522 +0100 -+++ ioemu/vl.h 2006-08-17 19:55:35.778019997 +0100 -@@ -1209,6 +1209,9 @@ +--- ioemu.orig/vl.h 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100 +@@ -1210,6 +1210,9 @@ void xenstore_check_new_media_present(int timeout); void xenstore_write_vncport(int vnc_display); diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xen-support-buffered-ioreqs --- a/tools/ioemu/patches/xen-support-buffered-ioreqs Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/xen-support-buffered-ioreqs Wed Oct 11 13:04:07 2006 -0400 @@ -1,8 +1,8 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:22.277673633 +0100 -+++ ioemu/vl.c 2006-08-17 19:55:21.878556486 +0100 -@@ -5838,6 +5838,7 @@ +--- ioemu.orig/vl.c 2006-09-21 19:33:32.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100 +@@ -5844,6 +5844,7 @@ unsigned long nr_pages, tmp_nr_pages, shared_page_nr; xen_pfn_t *page_array; extern void *shared_page; @@ -10,7 +10,7 @@ Index: ioemu/vl.c char qemu_dm_logfilename[64]; -@@ -6419,6 +6420,18 @@ +@@ -6425,6 +6426,18 @@ fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", shared_page_nr, (uint64_t)(page_array[shared_page_nr])); @@ -31,8 +31,8 @@ Index: ioemu/vl.c #elif defined(__ia64__) Index: ioemu/target-i386-dm/helper2.c =================================================================== ---- ioemu.orig/target-i386-dm/helper2.c 2006-08-17 19:49:44.491850141 +0100 -+++ ioemu/target-i386-dm/helper2.c 2006-08-17 19:50:41.490549986 +0100 +--- ioemu.orig/target-i386-dm/helper2.c 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/target-i386-dm/helper2.c 2006-09-21 19:33:32.000000000 +0100 @@ -76,6 +76,10 @@ shared_iopage_t *shared_page = NULL; diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xenstore-block-device-config --- a/tools/ioemu/patches/xenstore-block-device-config Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/xenstore-block-device-config Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-17 19:50:02.405870095 +0100 -+++ ioemu/Makefile.target 2006-08-17 19:50:18.866050726 +0100 +--- ioemu.orig/Makefile.target 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/Makefile.target 2006-09-21 19:33:31.000000000 +0100 @@ -358,6 +358,7 @@ VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o @@ -13,7 +13,7 @@ Index: ioemu/xenstore.c Index: ioemu/xenstore.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/xenstore.c 2006-08-17 19:50:18.867050616 +0100 ++++ ioemu/xenstore.c 2006-09-21 19:33:31.000000000 +0100 @@ -0,0 +1,187 @@ +/* + * This file is subject to the terms and conditions of the GNU General @@ -204,9 +204,9 @@ Index: ioemu/xenstore.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:17.086247452 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:18.870050284 +0100 -@@ -5243,9 +5243,11 @@ +--- ioemu.orig/vl.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:31.000000000 +0100 +@@ -5249,9 +5249,11 @@ "Standard options:\n" "-M machine select emulated machine (-M ? for list)\n" "-fda/-fdb file use 'file' as floppy disk 0/1 image\n" @@ -218,7 +218,7 @@ Index: ioemu/vl.c "-boot [a|c|d] boot on floppy (a), hard disk (c) or CD-ROM (d)\n" "-snapshot write to temporary files instead of disk image files\n" #ifdef TARGET_I386 -@@ -5372,11 +5374,13 @@ +@@ -5378,11 +5380,13 @@ QEMU_OPTION_M, QEMU_OPTION_fda, QEMU_OPTION_fdb, @@ -232,7 +232,7 @@ Index: ioemu/vl.c QEMU_OPTION_boot, QEMU_OPTION_snapshot, #ifdef TARGET_I386 -@@ -5448,11 +5452,13 @@ +@@ -5454,11 +5458,13 @@ { "M", HAS_ARG, QEMU_OPTION_M }, { "fda", HAS_ARG, QEMU_OPTION_fda }, { "fdb", HAS_ARG, QEMU_OPTION_fdb }, @@ -246,7 +246,7 @@ Index: ioemu/vl.c { "boot", HAS_ARG, QEMU_OPTION_boot }, { "snapshot", 0, QEMU_OPTION_snapshot }, #ifdef TARGET_I386 -@@ -5801,10 +5807,16 @@ +@@ -5807,10 +5813,16 @@ #ifdef CONFIG_GDBSTUB int use_gdbstub, gdbstub_port; #endif @@ -265,7 +265,7 @@ Index: ioemu/vl.c const char *kernel_filename, *kernel_cmdline; DisplayState *ds = &display_state; int cyls, heads, secs, translation; -@@ -5865,8 +5877,10 @@ +@@ -5871,8 +5883,10 @@ initrd_filename = NULL; for(i = 0; i < MAX_FD; i++) fd_filename[i] = NULL; @@ -276,7 +276,7 @@ Index: ioemu/vl.c ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; vga_ram_size = VGA_RAM_SIZE; bios_size = BIOS_SIZE; -@@ -5880,11 +5894,13 @@ +@@ -5886,11 +5900,13 @@ vncunused = 0; kernel_filename = NULL; kernel_cmdline = ""; @@ -290,7 +290,7 @@ Index: ioemu/vl.c cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; pstrcpy(monitor_device, sizeof(monitor_device), "vc"); -@@ -5917,7 +5933,11 @@ +@@ -5923,7 +5939,11 @@ break; r = argv[optind]; if (r[0] != '-') { @@ -302,7 +302,7 @@ Index: ioemu/vl.c } else { const QEMUOption *popt; -@@ -5961,6 +5981,7 @@ +@@ -5967,6 +5987,7 @@ case QEMU_OPTION_initrd: initrd_filename = optarg; break; @@ -310,7 +310,7 @@ Index: ioemu/vl.c case QEMU_OPTION_hda: case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: -@@ -5973,6 +5994,7 @@ +@@ -5979,6 +6000,7 @@ cdrom_index = -1; } break; @@ -318,7 +318,7 @@ Index: ioemu/vl.c case QEMU_OPTION_snapshot: snapshot = 1; break; -@@ -6025,11 +6047,13 @@ +@@ -6031,11 +6053,13 @@ case QEMU_OPTION_append: kernel_cmdline = optarg; break; @@ -332,7 +332,7 @@ Index: ioemu/vl.c case QEMU_OPTION_boot: boot_device = optarg[0]; if (boot_device != 'a' && -@@ -6284,12 +6308,18 @@ +@@ -6290,12 +6314,18 @@ } } @@ -351,7 +351,7 @@ Index: ioemu/vl.c if (!linux_boot && hd_filename[0] == '\0' && (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') && -@@ -6303,6 +6333,7 @@ +@@ -6309,6 +6339,7 @@ else boot_device = 'd'; } @@ -359,7 +359,7 @@ Index: ioemu/vl.c setvbuf(stdout, NULL, _IOLBF, 0); -@@ -6435,6 +6466,7 @@ +@@ -6441,6 +6472,7 @@ #endif /* !CONFIG_DM */ @@ -367,7 +367,7 @@ Index: ioemu/vl.c /* we always create the cdrom drive, even if no disk is there */ bdrv_init(); if (cdrom_index >= 0) { -@@ -6461,6 +6493,7 @@ +@@ -6467,6 +6499,7 @@ } } } @@ -375,7 +375,7 @@ Index: ioemu/vl.c /* we always create at least one floppy disk */ fd_table[0] = bdrv_new("fda"); -@@ -6539,6 +6572,8 @@ +@@ -6545,6 +6578,8 @@ } } @@ -386,8 +386,8 @@ Index: ioemu/vl.c kernel_filename, kernel_cmdline, initrd_filename, Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-08-17 19:49:44.491850141 +0100 -+++ ioemu/monitor.c 2006-08-17 19:50:18.871050174 +0100 +--- ioemu.orig/monitor.c 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/monitor.c 2006-09-21 19:33:31.000000000 +0100 @@ -24,6 +24,7 @@ #include "vl.h" #include "disas.h" @@ -416,8 +416,8 @@ Index: ioemu/monitor.c int i; Index: ioemu/block.c =================================================================== ---- ioemu.orig/block.c 2006-08-17 19:37:35.865578948 +0100 -+++ ioemu/block.c 2006-08-17 19:50:18.872050063 +0100 +--- ioemu.orig/block.c 2006-09-21 19:33:25.000000000 +0100 ++++ ioemu/block.c 2006-09-21 19:33:31.000000000 +0100 @@ -758,6 +758,7 @@ static void raw_close(BlockDriverState *bs) { @@ -428,9 +428,9 @@ Index: ioemu/block.c Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:17.087247341 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:18.872050063 +0100 -@@ -1188,6 +1188,8 @@ +--- ioemu.orig/vl.h 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:31.000000000 +0100 +@@ -1189,6 +1189,8 @@ void term_print_help(void); void monitor_readline(const char *prompt, int is_password, char *buf, int buf_size); @@ -439,7 +439,7 @@ Index: ioemu/vl.h /* readline.c */ typedef void ReadLineFunc(void *opaque, const char *str); -@@ -1200,6 +1202,13 @@ +@@ -1201,6 +1203,13 @@ void readline_start(const char *prompt, int is_password, ReadLineFunc *readline_func, void *opaque); @@ -455,8 +455,8 @@ Index: ioemu/vl.h extern char domain_name[]; Index: ioemu/hw/ide.c =================================================================== ---- ioemu.orig/hw/ide.c 2006-08-17 19:49:57.830375828 +0100 -+++ ioemu/hw/ide.c 2006-08-17 19:50:18.874049842 +0100 +--- ioemu.orig/hw/ide.c 2006-09-21 19:33:30.000000000 +0100 ++++ ioemu/hw/ide.c 2006-09-21 19:33:31.000000000 +0100 @@ -1158,6 +1158,7 @@ } else { ide_atapi_cmd_error(s, SENSE_NOT_READY, diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xenstore-write-vnc-port --- a/tools/ioemu/patches/xenstore-write-vnc-port Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/patches/xenstore-write-vnc-port Wed Oct 11 13:04:07 2006 -0400 @@ -1,7 +1,7 @@ Index: ioemu/xenstore.c Index: ioemu/xenstore.c =================================================================== ---- ioemu.orig/xenstore.c 2006-08-17 19:50:18.867050616 +0100 -+++ ioemu/xenstore.c 2006-08-17 19:50:22.274673964 +0100 +--- ioemu.orig/xenstore.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/xenstore.c 2006-09-21 19:33:32.000000000 +0100 @@ -185,3 +185,31 @@ free(image); free(vec); @@ -36,9 +36,9 @@ Index: ioemu/xenstore.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:50:18.870050284 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:22.277673633 +0100 -@@ -6529,6 +6529,7 @@ +--- ioemu.orig/vl.c 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100 +@@ -6535,6 +6535,7 @@ vnc_display = vnc_display_init(ds, vnc_display, vncunused); if (vncviewer) vnc_start_viewer(vnc_display); @@ -48,9 +48,9 @@ Index: ioemu/vl.c sdl_display_init(ds, full_screen); Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:50:18.872050063 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:22.278673522 +0100 -@@ -1207,6 +1207,7 @@ +--- ioemu.orig/vl.h 2006-09-21 19:33:31.000000000 +0100 ++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100 +@@ -1208,6 +1208,7 @@ int xenstore_fd(void); void xenstore_process_event(void *opaque); void xenstore_check_new_media_present(int timeout); diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/usb-linux.c --- a/tools/ioemu/usb-linux.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/usb-linux.c Wed Oct 11 13:04:07 2006 -0400 @@ -26,7 +26,9 @@ #if defined(__linux__) #include <dirent.h> #include <sys/ioctl.h> -#include <linux/compiler.h> +/* Some versions of usbdevice_fs.h need __user to be defined for them. */ +/* This may (harmlessly) conflict with a definition in linux/compiler.h. */ +#define __user #include <linux/usbdevice_fs.h> #include <linux/version.h> diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vl.c --- a/tools/ioemu/vl.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/vl.c Wed Oct 11 13:04:07 2006 -0400 @@ -122,6 +122,7 @@ int nographic; int nographic; int vncviewer; int vncunused; +struct sockaddr_in vnclisten_addr; const char* keyboard_layout = NULL; int64_t ticks_per_sec; char *boot_device = NULL; @@ -723,6 +724,12 @@ void qemu_del_timer(QEMUTimer *ts) } pt = &t->next; } +} + +void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time) +{ + if (ts->expire_time > expire_time || !qemu_timer_pending(ts)) + qemu_mod_timer(ts, expire_time); } /* modify the current timer so that it will be fired when current_time @@ -2777,10 +2784,22 @@ fail: return -1; } +int parse_host(struct sockaddr_in *saddr, const char *buf) +{ + struct hostent *he; + + if ((he = gethostbyname(buf)) != NULL) { + saddr->sin_addr = *(struct in_addr *)he->h_addr; + } else { + if (!inet_aton(buf, &saddr->sin_addr)) + return -1; + } + return 0; +} + int parse_host_port(struct sockaddr_in *saddr, const char *str) { char buf[512]; - struct hostent *he; const char *p, *r; int port; @@ -2791,14 +2810,8 @@ int parse_host_port(struct sockaddr_in * if (buf[0] == '\0') { saddr->sin_addr.s_addr = 0; } else { - if (isdigit(buf[0])) { - if (!inet_aton(buf, &saddr->sin_addr)) - return -1; - } else { - if ((he = gethostbyname(buf)) == NULL) - return - 1; - saddr->sin_addr = *(struct in_addr *)he->h_addr; - } + if (parse_host(&saddr, buf) == -1) + return -1; } port = strtol(p, (char **)&r, 0); if (r == p) @@ -5346,6 +5359,7 @@ void help(void) "-vnc display start a VNC server on display\n" "-vncviewer start a vncviewer process for this domain\n" "-vncunused bind the VNC server to an unused port\n" + "-vnclisten bind the VNC server to this address\n" "-timeoffset time offset (in seconds) from local time\n" "-acpi disable or enable ACPI of HVM domain \n" "\n" @@ -5438,6 +5452,7 @@ enum { QEMU_OPTION_acpi, QEMU_OPTION_vncviewer, QEMU_OPTION_vncunused, + QEMU_OPTION_vnclisten, }; typedef struct QEMUOption { @@ -5516,6 +5531,7 @@ const QEMUOption qemu_options[] = { { "vnc", HAS_ARG, QEMU_OPTION_vnc }, { "vncviewer", 0, QEMU_OPTION_vncviewer }, { "vncunused", 0, QEMU_OPTION_vncunused }, + { "vnclisten", HAS_ARG, QEMU_OPTION_vnclisten }, /* temporary options */ { "usb", 0, QEMU_OPTION_usb }, @@ -5922,6 +5938,8 @@ int main(int argc, char **argv) nb_nics = 0; /* default mac address of the first network interface */ + + memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr)); /* init debug */ sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid()); @@ -6304,7 +6322,10 @@ int main(int argc, char **argv) case QEMU_OPTION_vncunused: vncunused++; if (vnc_display == -1) - vnc_display = -2; + vnc_display = 0; + break; + case QEMU_OPTION_vnclisten: + parse_host(&vnclisten_addr, optarg); break; } } @@ -6542,7 +6563,7 @@ int main(int argc, char **argv) if (nographic) { dumb_display_init(ds); } else if (vnc_display != -1) { - vnc_display = vnc_display_init(ds, vnc_display, vncunused); + vnc_display = vnc_display_init(ds, vnc_display, vncunused, &vnclisten_addr); if (vncviewer) vnc_start_viewer(vnc_display); xenstore_write_vncport(vnc_display); diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vl.h --- a/tools/ioemu/vl.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/vl.h Wed Oct 11 13:04:07 2006 -0400 @@ -37,6 +37,8 @@ #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> +#include <sys/socket.h> +#include <sys/types.h> #include "xenctrl.h" #include "xs.h" #include <xen/hvm/e820.h> @@ -405,6 +407,7 @@ void qemu_free_timer(QEMUTimer *ts); void qemu_free_timer(QEMUTimer *ts); void qemu_del_timer(QEMUTimer *ts); void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time); +void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time); int qemu_timer_pending(QEMUTimer *ts); extern int64_t ticks_per_sec; @@ -785,7 +788,7 @@ void cocoa_display_init(DisplayState *ds void cocoa_display_init(DisplayState *ds, int full_screen); /* vnc.c */ -int vnc_display_init(DisplayState *ds, int display, int find_unused); +int vnc_display_init(DisplayState *ds, int display, int find_unused, struct sockaddr_in *addr); int vnc_start_viewer(int port); /* ide.c */ diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/ioemu/vnc.c Wed Oct 11 13:04:07 2006 -0400 @@ -26,8 +26,21 @@ #include "vl.h" #include "qemu_socket.h" - -#define VNC_REFRESH_INTERVAL (1000 / 30) +#include <assert.h> + +/* The refresh interval starts at BASE. If we scan the buffer and + find no change, we increase by INC, up to MAX. If the mouse moves + or we get a keypress, the interval is set back to BASE. If we find + an update, halve the interval. + + All times in milliseconds. */ +#define VNC_REFRESH_INTERVAL_BASE 30 +#define VNC_REFRESH_INTERVAL_INC 50 +#define VNC_REFRESH_INTERVAL_MAX 2000 + +/* Wait at most one second between updates, so that we can detect a + minimised vncviewer reasonably quickly. */ +#define VNC_MAX_UPDATE_INTERVAL 5000 #include "vnc_keysym.h" #include "keymaps.c" @@ -64,10 +77,11 @@ struct VncState struct VncState { QEMUTimer *timer; + int timer_interval; + int64_t last_update_time; int lsock; int csock; DisplayState *ds; - int need_update; int width; int height; uint64_t *dirty_row; /* screen regions which are possibly dirty */ @@ -97,8 +111,6 @@ struct VncState int visible_y; int visible_w; int visible_h; - - int slow_client; int ctl_keys; /* Ctrl+Alt starts calibration */ }; @@ -380,7 +392,7 @@ static void vnc_copy(DisplayState *ds, i int y = 0; int pitch = ds->linesize; VncState *vs = ds->opaque; - int updating_client = !vs->slow_client; + int updating_client = 1; if (src_x < vs->visible_x || src_y < vs->visible_y || dst_x < vs->visible_x || dst_y < vs->visible_y || @@ -390,10 +402,8 @@ static void vnc_copy(DisplayState *ds, i (dst_y + h) > (vs->visible_y + vs->visible_h)) updating_client = 0; - if (updating_client) { - vs->need_update = 1; + if (updating_client) _vnc_update_client(vs); - } if (dst_y > src_y) { y = h - 1; @@ -445,111 +455,149 @@ static void _vnc_update_client(void *opa static void _vnc_update_client(void *opaque) { VncState *vs = opaque; - int64_t now = qemu_get_clock(rt_clock); - - if (vs->need_update && vs->csock != -1) { - int y; - char *row; - char *old_row; - uint64_t width_mask; - int n_rectangles; - int saved_offset; - int maxx, maxy; - int tile_bytes = vs->depth * DP2X(vs, 1); - - if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS)) - width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1; - else - width_mask = ~(0ULL); - - /* Walk through the dirty map and eliminate tiles that - really aren't dirty */ - row = vs->ds->data; - old_row = vs->old_data; - - for (y = 0; y < vs->ds->height; y++) { - if (vs->dirty_row[y] & width_mask) { - int x; - char *ptr, *old_ptr; - - ptr = row; - old_ptr = old_row; - - for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) { - if (vs->dirty_row[y] & (1ULL << x)) { - if (memcmp(old_ptr, ptr, tile_bytes)) { - vs->has_update = 1; - vs->update_row[y] |= (1ULL << x); - memcpy(old_ptr, ptr, tile_bytes); - } - vs->dirty_row[y] &= ~(1ULL << x); + int64_t now; + int y; + char *row; + char *old_row; + uint64_t width_mask; + int n_rectangles; + int saved_offset; + int maxx, maxy; + int tile_bytes = vs->depth * DP2X(vs, 1); + + if (vs->csock == -1) + return; + + now = qemu_get_clock(rt_clock); + + if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS)) + width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1; + else + width_mask = ~(0ULL); + + /* Walk through the dirty map and eliminate tiles that really + aren't dirty */ + row = vs->ds->data; + old_row = vs->old_data; + + for (y = 0; y < vs->ds->height; y++) { + if (vs->dirty_row[y] & width_mask) { + int x; + char *ptr, *old_ptr; + + ptr = row; + old_ptr = old_row; + + for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) { + if (vs->dirty_row[y] & (1ULL << x)) { + if (memcmp(old_ptr, ptr, tile_bytes)) { + vs->has_update = 1; + vs->update_row[y] |= (1ULL << x); + memcpy(old_ptr, ptr, tile_bytes); } - - ptr += tile_bytes; - old_ptr += tile_bytes; + vs->dirty_row[y] &= ~(1ULL << x); } + + ptr += tile_bytes; + old_ptr += tile_bytes; } - - row += vs->ds->linesize; - old_row += vs->ds->linesize; - } - - if (!vs->has_update || vs->visible_y >= vs->ds->height || - vs->visible_x >= vs->ds->width) - goto out; - - /* Count rectangles */ - n_rectangles = 0; - vnc_write_u8(vs, 0); /* msg id */ - vnc_write_u8(vs, 0); - saved_offset = vs->output.offset; - vnc_write_u16(vs, 0); - - maxy = vs->visible_y + vs->visible_h; - if (maxy > vs->ds->height) - maxy = vs->ds->height; - maxx = vs->visible_x + vs->visible_w; - if (maxx > vs->ds->width) - maxx = vs->ds->width; - - for (y = vs->visible_y; y < maxy; y++) { - int x; - int last_x = -1; - for (x = X2DP_DOWN(vs, vs->visible_x); - x < X2DP_UP(vs, maxx); x++) { - if (vs->update_row[y] & (1ULL << x)) { - if (last_x == -1) - last_x = x; - vs->update_row[y] &= ~(1ULL << x); - } else { - if (last_x != -1) { - int h = find_update_height(vs, y, maxy, last_x, x); + } + + row += vs->ds->linesize; + old_row += vs->ds->linesize; + } + + if (!vs->has_update || vs->visible_y >= vs->ds->height || + vs->visible_x >= vs->ds->width) + goto backoff; + + /* Count rectangles */ + n_rectangles = 0; + vnc_write_u8(vs, 0); /* msg id */ + vnc_write_u8(vs, 0); + saved_offset = vs->output.offset; + vnc_write_u16(vs, 0); + + maxy = vs->visible_y + vs->visible_h; + if (maxy > vs->ds->height) + maxy = vs->ds->height; + maxx = vs->visible_x + vs->visible_w; + if (maxx > vs->ds->width) + maxx = vs->ds->width; + + for (y = vs->visible_y; y < maxy; y++) { + int x; + int last_x = -1; + for (x = X2DP_DOWN(vs, vs->visible_x); + x < X2DP_UP(vs, maxx); x++) { + if (vs->update_row[y] & (1ULL << x)) { + if (last_x == -1) + last_x = x; + vs->update_row[y] &= ~(1ULL << x); + } else { + if (last_x != -1) { + int h = find_update_height(vs, y, maxy, last_x, x); + if (h != 0) { send_framebuffer_update(vs, DP2X(vs, last_x), y, DP2X(vs, (x - last_x)), h); n_rectangles++; } - last_x = -1; } + last_x = -1; } - if (last_x != -1) { - int h = find_update_height(vs, y, maxy, last_x, x); + } + if (last_x != -1) { + int h = find_update_height(vs, y, maxy, last_x, x); + if (h != 0) { send_framebuffer_update(vs, DP2X(vs, last_x), y, DP2X(vs, (x - last_x)), h); n_rectangles++; } } - vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; - vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF; - - vs->has_update = 0; - vs->need_update = 0; - vnc_flush(vs); - vs->slow_client = 0; - } else - vs->slow_client = 1; - - out: - qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL); + } + vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; + vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF; + + if (n_rectangles == 0) + goto backoff; + + vs->has_update = 0; + vnc_flush(vs); + vs->last_update_time = now; + + vs->timer_interval /= 2; + if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE) + vs->timer_interval = VNC_REFRESH_INTERVAL_BASE; + + return; + + backoff: + /* No update -> back off a bit */ + vs->timer_interval += VNC_REFRESH_INTERVAL_INC; + if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) { + vs->timer_interval = VNC_REFRESH_INTERVAL_MAX; + if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) { + /* Send a null update. If the client is no longer + interested (e.g. minimised) it'll ignore this, and we + can stop scanning the buffer until it sends another + update request. */ + /* It turns out that there's a bug in realvncviewer 4.1.2 + which means that if you send a proper null update (with + no update rectangles), it gets a bit out of sync and + never sends any further requests, regardless of whether + it needs one or not. Fix this by sending a single 1x1 + update rectangle instead. */ + vnc_write_u8(vs, 0); + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + send_framebuffer_update(vs, 0, 0, 1, 1); + vnc_flush(vs); + vs->last_update_time = now; + return; + } + } + qemu_mod_timer(vs->timer, now + vs->timer_interval); + return; } static void vnc_update_client(void *opaque) @@ -564,7 +612,7 @@ static void vnc_timer_init(VncState *vs) { if (vs->timer == NULL) { vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs); - qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); + vs->timer_interval = VNC_REFRESH_INTERVAL_BASE; } } @@ -625,7 +673,6 @@ static int vnc_client_io_error(VncState vs->csock = -1; buffer_reset(&vs->input); buffer_reset(&vs->output); - vs->need_update = 0; return 0; } return ret; @@ -686,8 +733,10 @@ static void vnc_client_read(void *opaque memmove(vs->input.buffer, vs->input.buffer + len, vs->input.offset - len); vs->input.offset -= len; - } else + } else { + assert(ret > vs->read_handler_expect); vs->read_handler_expect = ret; + } } } @@ -895,13 +944,14 @@ static void framebuffer_update_request(V int x_position, int y_position, int w, int h) { - vs->need_update = 1; if (!incremental) framebuffer_set_updated(vs, x_position, y_position, w, h); vs->visible_x = x_position; vs->visible_y = y_position; vs->visible_w = w; vs->visible_h = h; + + qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); } static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) @@ -1016,6 +1066,7 @@ static int protocol_client_msg(VncState { int i; uint16_t limit; + int64_t now; switch (data[0]) { case 0: @@ -1032,8 +1083,12 @@ static int protocol_client_msg(VncState if (len == 1) return 4; - if (len == 4) - return 4 + (read_u16(data, 2) * 4); + if (len == 4) { + uint16_t v; + v = read_u16(data, 2); + if (v) + return 4 + v * 4; + } limit = read_u16(data, 2); for (i = 0; i < limit; i++) { @@ -1055,20 +1110,30 @@ static int protocol_client_msg(VncState if (len == 1) return 8; + vs->timer_interval = VNC_REFRESH_INTERVAL_BASE; + qemu_advance_timer(vs->timer, + qemu_get_clock(rt_clock) + vs->timer_interval); key_event(vs, read_u8(data, 1), read_u32(data, 4)); break; case 5: if (len == 1) return 6; + vs->timer_interval = VNC_REFRESH_INTERVAL_BASE; + qemu_advance_timer(vs->timer, + qemu_get_clock(rt_clock) + vs->timer_interval); pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4)); break; case 6: if (len == 1) return 8; - if (len == 8) - return 8 + read_u32(data, 4); + if (len == 8) { + uint32_t v; + v = read_u32(data, 4); + if (v) + return 8 + v; + } client_cut_text(vs, read_u32(data, 4), data + 8); break; @@ -1086,6 +1151,8 @@ static int protocol_client_init(VncState { size_t l; char pad[3] = { 0, 0, 0 }; + + vga_hw_update(); vs->width = vs->ds->width; vs->height = vs->ds->height; @@ -1183,9 +1250,8 @@ static void vnc_listen_read(void *opaque } } -int vnc_display_init(DisplayState *ds, int display, int find_unused) -{ - struct sockaddr_in addr; +int vnc_display_init(DisplayState *ds, int display, int find_unused, struct sockaddr_in *addr) +{ int reuse_addr, ret; VncState *vs; @@ -1223,11 +1289,10 @@ int vnc_display_init(DisplayState *ds, i } retry: - addr.sin_family = AF_INET; - addr.sin_port = htons(5900 + display); - memset(&addr.sin_addr, 0, sizeof(addr.sin_addr)); - - if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + addr->sin_family = AF_INET; + addr->sin_port = htons(5900 + display); + + if (bind(vs->lsock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) { if (find_unused && errno == EADDRINUSE) { display++; goto retry; @@ -1269,7 +1334,7 @@ int vnc_start_viewer(int port) exit(1); case 0: /* child */ - execlp("vncviewer", "vncviewer", s, 0); + execlp("vncviewer", "vncviewer", s, NULL); fprintf(stderr, "vncviewer execlp failed\n"); exit(1); diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/libxc/xc_linux.c Wed Oct 11 13:04:07 2006 -0400 @@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, priv (unsigned long)hypercall); } +#define MTAB "/proc/mounts" +#define MAX_PATH 255 +#define _STR(x) #x +#define STR(x) _STR(x) + +static int find_sysfsdir(char *sysfsdir) +{ + FILE *fp; + char type[MAX_PATH + 1]; + + if ( (fp = fopen(MTAB, "r")) == NULL ) + return -1; + + while ( fscanf(fp, "%*s %" + STR(MAX_PATH) + "s %" + STR(MAX_PATH) + "s %*s %*d %*d\n", + sysfsdir, type) == 2 ) + { + if ( strncmp(type, "sysfs", 5) == 0 ) + break; + } + + fclose(fp); + + return ((strncmp(type, "sysfs", 5) == 0) ? 0 : -1); +} + +int xc_find_device_number(const char *name) +{ + FILE *fp; + int i, major, minor; + char sysfsdir[MAX_PATH + 1]; + static char *classlist[] = { "xen", "misc" }; + + for ( i = 0; i < (sizeof(classlist) / sizeof(classlist[0])); i++ ) + { + if ( find_sysfsdir(sysfsdir) < 0 ) + goto not_found; + + /* <base>/class/<classname>/<devname>/dev */ + strncat(sysfsdir, "/class/", MAX_PATH); + strncat(sysfsdir, classlist[i], MAX_PATH); + strncat(sysfsdir, "/", MAX_PATH); + strncat(sysfsdir, name, MAX_PATH); + strncat(sysfsdir, "/dev", MAX_PATH); + + if ( (fp = fopen(sysfsdir, "r")) != NULL ) + goto found; + } + + not_found: + errno = -ENOENT; + return -1; + + found: + if ( fscanf(fp, "%d:%d", &major, &minor) != 2 ) + { + fclose(fp); + goto not_found; + } + + fclose(fp); + + return makedev(major, minor); +} + #define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 int xc_evtchn_open(void) { struct stat st; int fd; + int devnum; + + devnum = xc_find_device_number("evtchn"); /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) + if ( (lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || + (st.st_rdev != devnum) ) (void)unlink(EVTCHN_DEV_NAME); -reopen: + reopen: if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 ) { if ( (errno == ENOENT) && ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) ) + (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) ) goto reopen; PERROR("Could not open event channel interface"); diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_load_elf.c --- a/tools/libxc/xc_load_elf.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/libxc/xc_load_elf.c Wed Oct 11 13:04:07 2006 -0400 @@ -364,7 +364,7 @@ static int parseelfimage(const char *ima if ( p != NULL && strncmp(p, "yes", 3) == 0 ) { dsi->pae_kernel = PAEKERN_yes; - if ( !strncmp(p+4, "[extended-cr3]", 14) ) + if ( !strncmp(p+3, "[extended-cr3]", 14) ) dsi->pae_kernel = PAEKERN_extended_cr3; } } diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/libxc/xc_ptrace.c Wed Oct 11 13:04:07 2006 -0400 @@ -251,7 +251,7 @@ map_domain_va_pae( if ( !(l2e & _PAGE_PRESENT) ) return NULL; l1p = to_ma(cpu, l2e); - l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT); + l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l1p >> PAGE_SHIFT); if ( l1 == NULL ) return NULL; @@ -281,7 +281,6 @@ map_domain_va_64( uint64_t *l4, *l3, *l2, *l1; static void *v[MAX_VIRT_CPUS]; - if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */ return map_domain_va_32(xc_handle, cpu, guest_va, perm); @@ -309,7 +308,6 @@ map_domain_va_64( if ( l2 == NULL ) return NULL; - l1 = NULL; l2e = l2[l2_table_offset(va)]; munmap(l2, PAGE_SIZE); if ( !(l2e & _PAGE_PRESENT) ) @@ -318,11 +316,12 @@ map_domain_va_64( if (l2e & 0x80) { /* 2M pages */ p = to_ma(cpu, (l1p + l1_table_offset(va)) << PAGE_SHIFT); } else { /* 4K pages */ - l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT); + l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l1p >> PAGE_SHIFT); if ( l1 == NULL ) return NULL; l1e = l1[l1_table_offset(va)]; + munmap(l1, PAGE_SIZE); if ( !(l1e & _PAGE_PRESENT) ) return NULL; p = to_ma(cpu, l1e); @@ -330,8 +329,6 @@ map_domain_va_64( if ( v[cpu] != NULL ) munmap(v[cpu], PAGE_SIZE); v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT); - if (l1) - munmap(l1, PAGE_SIZE); if ( v[cpu] == NULL ) return NULL; @@ -611,17 +608,12 @@ xc_ptrace( online_vcpus_changed(cpumap); break; - case PTRACE_SETFPREGS: - case PTRACE_SETFPXREGS: - case PTRACE_PEEKUSER: - case PTRACE_POKEUSER: - case PTRACE_SYSCALL: - case PTRACE_KILL: - goto out_unsupported; /* XXX not yet supported */ - case PTRACE_TRACEME: IPRINTF("PTRACE_TRACEME is an invalid request under Xen\n"); goto out_error; + + default: + goto out_unsupported; /* XXX not yet supported */ } return retval; diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/libxc/xenctrl.h Wed Oct 11 13:04:07 2006 -0400 @@ -92,6 +92,16 @@ int xc_interface_close(int xc_handle); int xc_interface_close(int xc_handle); /* + * KERNEL INTERFACES + */ + +/* + * Resolve a kernel device name (e.g., "evtchn", "blktap0") into a kernel + * device number. Returns -1 on error (and sets errno). + */ +int xc_find_device_number(const char *name); + +/* * DOMAIN DEBUGGING FUNCTIONS */ diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/Makefile --- a/tools/misc/mbootpack/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/misc/mbootpack/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -20,12 +20,8 @@ install: build # Tools etc. RM := rm -f -GDB := gdb INCS := -I. -I- DEFS := -LDFLAGS := -CFLAGS += -Wpointer-arith -Wcast-qual -Wno-unused -Wno-format -CFLAGS += -Wmissing-prototypes -pipe # What object files need building for the program OBJS := mbootpack.o buildimage.o @@ -35,22 +31,22 @@ DEPS = .*.d DEPS = .*.d mbootpack: $(OBJS) - $(HOSTCC) -o $@ $(filter-out %.a, $^) + $(HOSTCC) $(HOSTCFLAGS) -o $@ $(filter-out %.a, $^) .PHONY: clean clean: $(RM) mbootpack *.o $(DEPS) bootsect setup bzimage_header.c bin2c bootsect: bootsect.S - $(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o + $(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o $(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary bootsect.o -o $@ setup: setup.S - $(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o + $(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o $(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary setup.o -o $@ bin2c: bin2c.o - $(HOSTCC) -o $@ $^ + $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ bzimage_header.c: bootsect setup bin2c ./bin2c -n 8 -b1 -a bzimage_bootsect bootsect > bzimage_header.c @@ -59,11 +55,8 @@ buildimage.c: bzimage_header.c buildimage.c: bzimage_header.c @ -%.o: %.S - $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ - %.o: %.c - $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ + $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(INCS) $(DEFS) -c $< -o $@ .PRECIOUS: $(OBJS) $(OBJS:.o=.c) $(DEPS) .SUFFIXES: diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/buildimage.c --- a/tools/misc/mbootpack/buildimage.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/misc/mbootpack/buildimage.c Wed Oct 11 13:04:07 2006 -0400 @@ -24,8 +24,6 @@ * $Id: buildimage.c,v 1.2 2005/03/23 10:39:19 tjd21 Exp $ * */ - - #include <assert.h> #include <stdio.h> @@ -77,20 +75,22 @@ /* Bring in the bzImage boot sector and setup code */ #include "bzimage_header.c" +#define _p(x) ((void *)(unsigned long)(x)) + address_t place_mbi(long int size) /* Find space at the top of *low* memory for the MBI and associated red tape */ { address_t start; start = 0xa000 - size; if (start < 0x9000 + sizeof(bzimage_bootsect) + sizeof(bzimage_setup)) { - printf("Fatal: command-lines too long: need %i, have %i bytes\n", + printf("Fatal: command-lines too long: need %ld, have %ld bytes\n", size, - 0x1000 - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup))); - exit(1); + 0x1000L - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup))); + exit(1); } if (!quiet) { printf("Placed MBI and strings (%p+%p)\n", - start, size); + _p(start), _p(size)); } return start; } @@ -108,7 +108,7 @@ void make_bzImage(section_t *sections, /* Patch the kernel and mbi addresses into the setup code */ *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = eswap(entry); *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = eswap(mbi); - if (!quiet) printf("Kernel entry is %p, MBI is %p.\n", entry, mbi); + if (!quiet) printf("Kernel entry is %p, MBI is %p.\n",_p(entry), _p(mbi)); /* Write out header and trampoline */ if (fseek(fp, 0, SEEK_SET) < 0) { @@ -127,8 +127,9 @@ void make_bzImage(section_t *sections, exit(1); } - if (!quiet) printf("Wrote bzImage header: %i + %i bytes.\n", - sizeof(bzimage_bootsect), sizeof(bzimage_setup)); + if (!quiet) printf("Wrote bzImage header: %ld + %ld bytes.\n", + (long)sizeof(bzimage_bootsect), + (long)sizeof(bzimage_setup)); /* Sorted list of sections below 1MB: write them out */ for (s = sections, i = 0; s; s = s->next) { diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/mbootpack.c --- a/tools/misc/mbootpack/mbootpack.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/misc/mbootpack/mbootpack.c Wed Oct 11 13:04:07 2006 -0400 @@ -128,6 +128,7 @@ static void usage(void) exit(1); } +#define _p(x) ((void *)(unsigned long)(x)) static void place_kernel_section(address_t start, long int size) /* Place the kernel in memory, checking for the memory hole. */ @@ -136,7 +137,8 @@ static void place_kernel_section(address /* Above the memory hole: easy */ next_free_space = MAX(next_free_space, start + size); if (!quiet) { - printf("Placed kernel section (%p+%p)\n", start, size); + printf("Placed kernel section (%p+%p)\n", + _p(start), _p(size)); } return; } @@ -144,14 +146,14 @@ static void place_kernel_section(address if (start >= MEM_HOLE_START) { /* In the memory hole. Not so good */ printf("Fatal: kernel load address (%p) is in the memory hole.\n", - start); + _p(start)); exit(1); } if (start + size > MEM_HOLE_START) { /* Too big for low memory */ printf("Fatal: kernel (%p+%p) runs into the memory hole.\n", - start, size); + _p(start), _p(size)); exit(1); } @@ -159,7 +161,7 @@ static void place_kernel_section(address next_free_space = MAX(next_free_space, start + size); if (!quiet) { - printf("Placed kernel section (%p+%p)\n", start, size); + printf("Placed kernel section (%p+%p)\n", _p(start), _p(size)); } } @@ -182,12 +184,10 @@ static address_t place_section(long int if (!quiet) { printf("Placed section (%p+%p), align=%p\n", - start, size, align); + _p(start), _p(size), _p(align)); } return start; } - - static address_t load_kernel(const char *filename) @@ -296,7 +296,7 @@ static address_t load_kernel(const char size = loadsize; if (loadsize > size) { - printf("Fatal: can't load %i bytes of kernel into %i bytes " + printf("Fatal: can't load %ld bytes of kernel into %ld bytes " "of memory.\n", loadsize, size); exit(1); } @@ -466,8 +466,6 @@ static address_t load_kernel(const char } - - int main(int argc, char **argv) { char *buffer, *imagename, *command_line, *p; @@ -480,7 +478,7 @@ int main(int argc, char **argv) struct mod_list *modp; address_t start, kernel_entry; long int size, mod_command_line_space, command_line_len; - int modules, opt, mbi_reloc_offset, make_multiboot; + int modules, opt, mbi_reloc_offset; static const char short_options[] = "hc:m:o:qM"; static const struct option options[] = { diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/miniterm/miniterm.c --- a/tools/misc/miniterm/miniterm.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/misc/miniterm/miniterm.c Wed Oct 11 13:04:07 2006 -0400 @@ -32,10 +32,11 @@ #include <signal.h> #include <sys/types.h> #include <sys/wait.h> +#include <string.h> #define DEFAULT_BAUDRATE 115200 #define DEFAULT_SERDEVICE "/dev/ttyS0" -#define ENDMINITERM 2 /* ctrl-b to quit miniterm */ +#define ENDMINITERM 0x1d volatile int stop = 0; @@ -76,7 +77,11 @@ int main(int argc, char **argv) char *sername = DEFAULT_SERDEVICE; struct termios oldsertio, newsertio, oldstdtio, newstdtio; struct sigaction sa; - + static char start_str[] = + "************ REMOTE CONSOLE: CTRL-] TO QUIT ********\r\n"; + static char end_str[] = + "\n************ REMOTE CONSOLE EXITED *****************\n"; + while ( --argc != 0 ) { char *p = argv[argc]; @@ -121,7 +126,7 @@ int main(int argc, char **argv) newsertio.c_iflag = IGNBRK | IGNPAR; /* Raw output. */ - newsertio.c_oflag = 0; + newsertio.c_oflag = OPOST; /* No echo and no signals. */ newsertio.c_lflag = 0; @@ -137,7 +142,13 @@ int main(int argc, char **argv) /* next stop echo and buffering for stdin */ tcgetattr(0,&oldstdtio); tcgetattr(0,&newstdtio); /* get working stdtio */ - newstdtio.c_lflag &= ~(ICANON | ECHO); + newstdtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + newstdtio.c_oflag &= ~OPOST; + newstdtio.c_cflag &= ~(CSIZE | PARENB); + newstdtio.c_cflag |= CS8; + newstdtio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + newstdtio.c_cc[VMIN]=1; + newstdtio.c_cc[VTIME]=0; tcsetattr(0,TCSANOW,&newstdtio); /* Terminal settings done: now enter the main I/O loops. */ @@ -145,7 +156,7 @@ int main(int argc, char **argv) { case 0: close(1); /* stdout not needed */ - for ( c = getchar(); c != ENDMINITERM ; c = getchar() ) + for ( c = (char)getchar(); c != ENDMINITERM; c = (char)getchar() ) write(fd,&c,1); tcsetattr(fd,TCSANOW,&oldsertio); tcsetattr(0,TCSANOW,&oldstdtio); @@ -158,7 +169,7 @@ int main(int argc, char **argv) close(fd); exit(-1); default: - printf("** ctrl-b quits miniterm **\n"); + write(1, start_str, strlen(start_str)); close(0); /* stdin not needed */ sa.sa_handler = child_handler; sa.sa_flags = 0; @@ -166,9 +177,11 @@ int main(int argc, char **argv) while ( !stop ) { read(fd,&c,1); /* modem */ + c = (char)c; write(1,&c,1); /* stdout */ } wait(NULL); /* wait for child to die or it will become a zombie */ + write(1, end_str, strlen(end_str)); break; } diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/Makefile --- a/tools/pygrub/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/pygrub/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -12,9 +12,11 @@ ifndef XEN_PYTHON_NATIVE_INSTALL ifndef XEN_PYTHON_NATIVE_INSTALL install: all CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" + $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen else install: all CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" + $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen endif .PHONY: clean diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/fsys/ext2/__init__.py --- a/tools/pygrub/src/fsys/ext2/__init__.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/pygrub/src/fsys/ext2/__init__.py Wed Oct 11 13:04:07 2006 -0400 @@ -23,7 +23,7 @@ class Ext2FileSystemType(FileSystemType) fd = os.open(fn, os.O_RDONLY) os.lseek(fd, offset, 0) buf = os.read(fd, 2048) - + os.close(fd) if len(buf) > 1082 and \ struct.unpack("<H", buf[1080:1082]) == (0xef53,): return True diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/fsys/reiser/__init__.py --- a/tools/pygrub/src/fsys/reiser/__init__.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/pygrub/src/fsys/reiser/__init__.py Wed Oct 11 13:04:07 2006 -0400 @@ -26,6 +26,7 @@ class ReiserFileSystemType(FileSystemTyp fd = os.open(fn, os.O_RDONLY) os.lseek(fd, 0x10000, 0) buf = os.read(fd, 0x40) + os.close(fd) if len(buf) == 0x40 and (buf[0x34:0x3B] in [FSMAGIC2, FSMAGIC3]) : return True return False diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/pygrub --- a/tools/pygrub/src/pygrub Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/pygrub/src/pygrub Wed Oct 11 13:04:07 2006 -0400 @@ -25,7 +25,18 @@ import grub.GrubConf import grub.GrubConf import grub.fsys -PYGRUB_VER = 0.4 +PYGRUB_VER = 0.5 + +def enable_cursor(ison): + if ison: + val = 2 + else: + val = 0 + + try: + curses.curs_set(val) + except _curses.error: + pass def is_disk_image(file): fd = os.open(file, os.O_RDONLY) @@ -141,10 +152,7 @@ class Grub: self.screen.timeout(1000) if hasattr(curses, 'use_default_colors'): curses.use_default_colors() - try: - curses.curs_set(0) - except _curses.error: - pass + enable_cursor(False) self.entry_win = curses.newwin(10, 74, 2, 1) self.text_win = curses.newwin(10, 70, 12, 5) @@ -247,6 +255,7 @@ class Grub: self.screen.refresh() t = GrubLineEditor(self.screen, 5, 2, line) + enable_cursor(True) ret = t.edit() if ret: return ret @@ -262,6 +271,7 @@ class Grub: lines = [] while 1: t = GrubLineEditor(self.screen, y, 2) + enable_cursor(True) ret = t.edit() if ret: if ret in ("quit", "return"): diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/util/blkif.py --- a/tools/python/xen/util/blkif.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/util/blkif.py Wed Oct 11 13:04:07 2006 -0400 @@ -7,7 +7,7 @@ def expand_dev_name(name): def expand_dev_name(name): if not name: return name - if re.match( '^/dev/', name ): + if re.match( '^/', name ): return name else: return '/dev/' + name @@ -64,9 +64,11 @@ def blkdev_uname_to_file(uname): """Take a blkdev uname and return the corresponding filename.""" fn = None if uname.find(":") != -1: - (typ, fn) = uname.split(":") - if typ == "phy" and not fn.startswith("/dev/"): + (typ, fn) = uname.split(":", 1) + if typ == "phy" and not fn.startswith("/"): fn = "/dev/%s" %(fn,) + if typ == "tap": + (typ, fn) = fn.split(":", 1) return fn def mount_mode(name): diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendBootloader.py --- a/tools/python/xen/xend/XendBootloader.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/XendBootloader.py Wed Oct 11 13:04:07 2006 -0400 @@ -15,6 +15,7 @@ import os, select, errno import os, select, errno import random import sxp +import shlex from XendLogging import log from XendError import VmError @@ -49,7 +50,7 @@ def bootloader(blexec, disk, quiet = 0, args.append("-q") args.append("--output=%s" %(fifo,)) if blargs is not None: - args.extend(blargs.split()) + args.extend(shlex.split(blargs)) args.append(disk) try: diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Oct 11 13:04:07 2006 -0400 @@ -161,8 +161,8 @@ def restore(xd, fd): if handler.store_mfn is None or handler.console_mfn is None: raise XendError('Could not read store/console MFN') - #Block until src closes connection - os.read(fd, 1) + os.read(fd, 1) # Wait for source to close connection + dominfo.waitForDevices() # Wait for backends to set up dominfo.unpause() dominfo.completeRestore(handler.store_mfn, handler.console_mfn) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/XendDomain.py Wed Oct 11 13:04:07 2006 -0400 @@ -487,10 +487,19 @@ class XendDomain: if not dominfo: raise XendInvalidDomain(str(domid)) - try: - return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap) - except Exception, ex: - raise XendError(str(ex)) + # if vcpu is keyword 'all', apply the cpumap to all vcpus + vcpus = [ vcpu ] + if str(vcpu).lower() == "all": + vcpus = range(0, int(dominfo.getVCpuCount())) + + # set the same cpumask for all vcpus + rc = 0 + for v in vcpus: + try: + rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap) + except Exception, ex: + raise XendError(str(ex)) + return rc def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime, weight): @@ -560,13 +569,23 @@ class XendDomain: except Exception, ex: raise XendError(str(ex)) - def domain_sched_credit_set(self, domid, weight, cap): + def domain_sched_credit_set(self, domid, weight = None, cap = None): """Set credit scheduler parameters for a domain. """ dominfo = self.domain_lookup_by_name_or_id_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) try: + if weight is None: + weight = int(0) + elif weight < 1 or weight > 65535: + raise XendError("weight is out of range") + + if cap is None: + cap = int(~0) + elif cap < 0 or cap > dominfo.getVCpuCount() * 100: + raise XendError("cap is out of range") + return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap) except Exception, ex: raise XendError(str(ex)) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 11 13:04:07 2006 -0400 @@ -600,6 +600,8 @@ class XendDomainInfo: if self.info['memory'] == 0: if self.infoIsSet('mem_kb'): self.info['memory'] = (self.info['mem_kb'] + 1023) / 1024 + if self.info['memory'] <= 0: + raise VmError('Invalid memory size') if self.info['maxmem'] < self.info['memory']: self.info['maxmem'] = self.info['memory'] @@ -990,14 +992,18 @@ class XendDomainInfo: this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time, self.info['name'], self.domid) + + if os.path.isdir(corefile): + raise XendError("Cannot dump core in a directory: %s" % + corefile) + xc.domain_dumpcore(self.domid, corefile) - - except: + except RuntimeError, ex: corefile_incomp = corefile+'-incomplete' os.rename(corefile, corefile_incomp) log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s", self.domid, self.info['name']) - + raise XendError("Failed to dump core: %s" % str(ex)) ## public: @@ -1005,6 +1011,9 @@ class XendDomainInfo: """Set the memory target of this domain. @param target In MiB. """ + if target <= 0: + raise XendError('Invalid memory size') + log.debug("Setting memory target of domain %s (%d) to %d MiB.", self.info['name'], self.domid, target) @@ -1097,15 +1106,16 @@ class XendDomainInfo: ## public: def destroyDevice(self, deviceClass, devid): - if type(devid) is str: - devicePath = '%s/device/%s' % (self.dompath, deviceClass) - for entry in xstransact.List(devicePath): - backend = xstransact.Read('%s/%s' % (devicePath, entry), "backend") - devName = xstransact.Read(backend, "dev") - if devName == devid: - # We found the integer matching our devid, use it instead - devid = entry - break + if type(devid) is str: + devicePath = '%s/device/%s' % (self.dompath, deviceClass) + for entry in xstransact.List(devicePath): + backend = xstransact.Read('%s/%s' % (devicePath, entry), + "backend") + devName = xstransact.Read(backend, "dev") + if devName == devid: + # We found the integer matching our devid, use it instead + devid = entry + break return self.getDeviceController(deviceClass).destroyDevice(devid) @@ -1742,7 +1752,7 @@ class XendDomainInfo: blcfg = None # FIXME: this assumes that we want to use the first disk device for (n,c) in self.info['device']: - if not n or not c or n != "vbd": + if not n or not c or not(n in ["vbd", "tap"]): continue disk = sxp.child_value(c, "uname") if disk is None: diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendRoot.py --- a/tools/python/xen/xend/XendRoot.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/XendRoot.py Wed Oct 11 13:04:07 2006 -0400 @@ -95,6 +95,9 @@ class XendRoot: dom0_min_mem_default = '0' dom0_vcpus_default = '0' + + """Default interface to listen for VNC connections on""" + xend_vnc_listen_default = '127.0.0.1' components = {} @@ -272,6 +275,9 @@ class XendRoot: def get_console_limit(self): return self.get_config_int('console-limit', 1024) + def get_vnclisten_address(self): + return self.get_config_value('vnc-listen', self.xend_vnc_listen_default) + def instance(): """Get an instance of XendRoot. Use this instead of the constructor. diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/image.py Wed Oct 11 13:04:07 2006 -0400 @@ -252,7 +252,8 @@ class HVMImageHandler(ImageHandler): info = xc.xeninfo() if not 'hvm' in info['xen_caps']: - raise VmError("Not an HVM capable platform, we stop creating!") + raise VmError("HVM guest support is unavailable: is VT/AMD-V " + "supported by your CPU and enabled in your BIOS?") self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig) self.device_model = sxp.child_value(imageConfig, 'device_model') @@ -362,10 +363,17 @@ class HVMImageHandler(ImageHandler): if vnc: vncdisplay = sxp.child_value(config, 'vncdisplay', int(self.vm.getDomid())) - ret = ret + ['-vnc', '%d' % vncdisplay, '-k', 'en-us'] vncunused = sxp.child_value(config, 'vncunused') if vncunused: ret += ['-vncunused'] + else: + ret += ['-vnc', '%d' % vncdisplay] + ret += ['-k', 'en-us'] + vnclisten = sxp.child_value(config, 'vnclisten') + if not(vnclisten): + vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address() + if vnclisten: + ret += ['-vnclisten', vnclisten] return ret def createDeviceModel(self): diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/server/DevController.py Wed Oct 11 13:04:07 2006 -0400 @@ -25,7 +25,7 @@ from xen.xend.xenstore.xstransact import from xen.xend.xenstore.xstransact import xstransact, complete from xen.xend.xenstore.xswatch import xswatch -DEVICE_CREATE_TIMEOUT = 10 +DEVICE_CREATE_TIMEOUT = 100 HOTPLUG_STATUS_NODE = "hotplug-status" HOTPLUG_ERROR_NODE = "hotplug-error" HOTPLUG_STATUS_ERROR = "error" diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/server/SrvDomain.py --- a/tools/python/xen/xend/server/SrvDomain.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xend/server/SrvDomain.py Wed Oct 11 13:04:07 2006 -0400 @@ -97,7 +97,7 @@ class SrvDomain(SrvDir): def op_pincpu(self, _, req): fn = FormFn(self.xd.domain_pincpu, [['dom', 'int'], - ['vcpu', 'int'], + ['vcpu', 'str'], ['cpumap', 'str']]) val = fn(req.args, {'dom': self.dom.domid}) return val diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/addlabel.py Wed Oct 11 13:04:07 2006 -0400 @@ -19,19 +19,23 @@ """Labeling a domain configuration file or a resoruce. """ -import sys, os +import os +import sys + from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]" - print " xm addlabel <label> res <resource> [<policy>]\n" - print " This program adds an acm_label entry into the 'configfile'" - print " for a domain or to the global resource label file for a" - print " resource. It derives the policy from the running hypervisor" - print " if it is not given (optional parameter). If a label already" - print " exists for the given domain or resource, then addlabel fails.\n" - security.err("Usage") +def help(): + return """ + Format: xm addlabel <label> dom <configfile> [<policy>] + xm addlabel <label> res <resource> [<policy>] + + This program adds an acm_label entry into the 'configfile' + for a domain or to the global resource label file for a + resource. It derives the policy from the running hypervisor + if it is not given (optional parameter). If a label already + exists for the given domain or resource, then addlabel fails.""" def validate_config_file(configfile): @@ -111,44 +115,45 @@ def add_domain_label(label, configfile, config_fd.close() -def main (argv): +def main(argv): + policyref = None + if len(argv) not in (4, 5): + raise OptionError('Needs either 2 or 3 arguments') + + label = argv[1] + + if len(argv) == 5: + policyref = argv[4] + elif security.on(): + policyref = security.active_policy + else: + raise OptionError("No active policy. Must specify policy on the " + "command line.") + + if argv[2].lower() == "dom": + configfile = argv[3] + if configfile[0] != '/': + for prefix in [".", "/etc/xen"]: + configfile = prefix + "/" + configfile + if os.path.isfile(configfile): + break + if not validate_config_file(configfile): + raise OptionError('Invalid config file') + else: + add_domain_label(label, configfile, policyref) + elif argv[2].lower() == "res": + resource = argv[3] + add_resource_label(label, resource, policyref) + else: + raise OptionError('Need to specify either "dom" or "res" as ' + 'object to add label to.') + +if __name__ == '__main__': try: - policyref = None - if len(argv) not in [4,5]: - usage() - return + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) + - label = argv[1] - if len(argv) == 5: - policyref = argv[4] - elif security.on(): - policyref = security.active_policy - else: - security.err("No active policy. Policy must be specified in command line.") - - if argv[2].lower() == "dom": - configfile = argv[3] - if configfile[0] != '/': - for prefix in [".", "/etc/xen"]: - configfile = prefix + "/" + configfile - if os.path.isfile(configfile): - break - if not validate_config_file(configfile): - usage() - else: - add_domain_label(label, configfile, policyref) - elif argv[2].lower() == "res": - resource = argv[3] - add_resource_label(label, resource, policyref) - else: - usage() - - except security.ACMError: - sys.exit(-1) - - -if __name__ == '__main__': - main(sys.argv) - - diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/cfgbootpolicy.py --- a/tools/python/xen/xm/cfgbootpolicy.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/cfgbootpolicy.py Wed Oct 11 13:04:07 2006 -0400 @@ -28,20 +28,17 @@ from xen.util.security import policy_dir from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re from xen.util.security import empty_line_re, binary_name_re, policy_name_re +from xen.xm.opts import OptionError - -def usage(): - print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n" - print " Adds a 'module' line to the Xen grub.conf entry" - print " so that xen boots into a specific access control" - print " policy. If kernelversion is not given, then this" - print " script tries to determine it by looking for a grub" - print " entry with a line kernel xen.* If there are multiple" - print " Xen entries, then it must be called with an explicit" - print " version (it will fail otherwise).\n" - err("Usage") - - +def help(): + return """ + Adds a 'module' line to the Xen grub.conf entry + so that xen boots into a specific access control + policy. If kernelversion is not given, then this + script tries to determine it by looking for a grub + entry with a line kernel xen.* If there are multiple + Xen entries, then it must be called with an explicit + version (it will fail otherwise).\n""" def determine_kernelversion(user_specified): within_xen_title = 0 @@ -143,44 +140,41 @@ def insert_policy(boot_file, kernel_vers def main(argv): - try: - user_kver = None - policy = None - if len(argv) == 2: - policy = argv[1] - elif len(argv) == 3: - policy = argv[1] - user_kver = argv[2] + user_kver = None + policy = None + if len(argv) == 2: + policy = argv[1] + elif len(argv) == 3: + policy = argv[1] + user_kver = argv[2] + else: + raise OptionError('Invalid number of arguments') + + if not policy_name_re.match(policy): + raise OptionError("Illegal policy name: '%s'" % policy) + + policy_file = '/'.join([policy_dir_prefix] + policy.split('.')) + src_binary_policy_file = policy_file + ".bin" + #check if .bin exists or if policy file exists + if not os.path.isfile(src_binary_policy_file): + if not os.path.isfile(policy_file + "-security_policy.xml"): + raise OptionError("Unknown policy '%s'" % policy) else: - usage() - - if not policy_name_re.match(policy): - err("Illegal policy name \'" + policy + "\'") - - policy_file = policy_dir_prefix + "/" + string.join(string.split(policy, "."), "/") - src_binary_policy_file = policy_file + ".bin" - #check if .bin exists or if policy file exists - if not os.path.isfile(src_binary_policy_file): - if not os.path.isfile(policy_file + "-security_policy.xml"): - err("Unknown policy \'" + policy +"\'") - else: - err("Cannot find binary file for policy \'" + policy + - "\'. Please use makepolicy to create binary file.") - dst_binary_policy_file = "/boot/" + policy + ".bin" - shutil.copyfile(src_binary_policy_file, dst_binary_policy_file) - - kernel_version = determine_kernelversion(user_kver) - insert_policy(boot_filename, kernel_version, policy) - print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin") - - except ACMError: - sys.exit(-1) - except: - traceback.print_exc(limit=1) - sys.exit(-1) - - + err_msg = "Cannot find binary file for policy '%s'." % policy + err_msg += " Please use makepolicy to create binary file." + raise OptionError(err_msg) + + dst_binary_policy_file = "/boot/" + policy + ".bin" + shutil.copyfile(src_binary_policy_file, dst_binary_policy_file) + + kernel_version = determine_kernelversion(user_kver) + insert_policy(boot_filename, kernel_version, policy) + print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin") if __name__ == '__main__': - main(sys.argv) - + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: ' + str(e) + '\n') + sys.exit(-1) + diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/console.py --- a/tools/python/xen/xm/console.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/console.py Wed Oct 11 13:04:07 2006 -0400 @@ -18,9 +18,7 @@ XENCONSOLE = "xenconsole" - import xen.util.auxbin - def execConsole(domid): xen.util.auxbin.execute(XENCONSOLE, [str(domid)]) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/create.py Wed Oct 11 13:04:07 2006 -0400 @@ -25,7 +25,6 @@ import socket import socket import re import xmlrpclib -import traceback from xen.xend import sxp from xen.xend import PrettyPrint @@ -57,7 +56,8 @@ gopts.opt('help', short='h', gopts.opt('help_config', fn=set_true, default=0, - use="Print help for the configuration script.") + use="Print the available configuration variables (vars) for the " + "configuration script.") gopts.opt('quiet', short='q', fn=set_true, default=0, @@ -65,35 +65,36 @@ gopts.opt('quiet', short='q', gopts.opt('path', val='PATH', fn=set_value, default='.:/etc/xen', - use="""Search path for configuration scripts. - The value of PATH is a colon-separated directory list.""") + use="Search path for configuration scripts. " + "The value of PATH is a colon-separated directory list.") gopts.opt('defconfig', short='f', val='FILE', fn=set_value, default='xmdefconfig', - use="""Use the given Python configuration script. - The configuration script is loaded after arguments have been processed. - Each command-line option sets a configuration variable named after - its long option name, and these variables are placed in the - environment of the script before it is loaded. - Variables for options that may be repeated have list values. - Other variables can be set using VAR=VAL on the command line. - - After the script is loaded, option values that were not set on the - command line are replaced by the values set in the script.""") + use="Use the given Python configuration script." + "The configuration script is loaded after arguments have been " + "processed. Each command-line option sets a configuration " + "variable named after its long option name, and these " + "variables are placed in the environment of the script before " + "it is loaded. Variables for options that may be repeated have " + "list values. Other variables can be set using VAR=VAL on the " + "command line. " + "After the script is loaded, option values that were not set " + "on the command line are replaced by the values set in the script.") gopts.default('defconfig') gopts.opt('config', short='F', val='FILE', fn=set_value, default=None, - use="""Domain configuration to use (SXP). - SXP is the underlying configuration format used by Xen. - SXP configurations can be hand-written or generated from Python configuration - scripts, using the -n (dryrun) option to print the configuration.""") + use="Domain configuration to use (SXP).\n" + "SXP is the underlying configuration format used by Xen.\n" + "SXP configurations can be hand-written or generated from Python " + "configuration scripts, using the -n (dryrun) option to print " + "the configuration.") gopts.opt('dryrun', short='n', fn=set_true, default=0, - use="""Dry run - print the configuration but don't create the domain. - Loads the configuration script, creates the SXP configuration and prints it.""") + use="Dry run - prints the resulting configuration in SXP but " + "does not create the domain.") gopts.opt('paused', short='p', fn=set_true, default=0, @@ -105,18 +106,16 @@ gopts.opt('console_autoconnect', short=' gopts.var('vncviewer', val='no|yes', fn=set_bool, default=None, - use="""Spawn a vncviewer listening for a vnc server in the domain. - The address of the vncviewer is passed to the domain on the kernel command - line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY. - A display value with a free port is chosen if possible. - Only valid when vnc=1. - """) + use="Spawn a vncviewer listening for a vnc server in the domain.\n" + "The address of the vncviewer is passed to the domain on the " + "kernel command line using 'VNC_SERVER=<host>:<port>'. The port " + "used by vnc is 5500 + DISPLAY. A display value with a free port " + "is chosen if possible.\nOnly valid when vnc=1.") gopts.var('vncconsole', val='no|yes', fn=set_bool, default=None, - use="""Spawn a vncviewer process for the domain's graphical console. - Only valid when vnc=1. - """) + use="Spawn a vncviewer process for the domain's graphical console.\n" + "Only valid when vnc=1.") gopts.var('name', val='NAME', fn=set_value, default=None, @@ -420,6 +419,10 @@ gopts.var('vncdisplay', val='', fn=set_value, default=None, use="""VNC display to use""") +gopts.var('vnclisten', val='', + fn=set_value, default=None, + use="""Address for VNC server to listen on.""") + gopts.var('vncunused', val='', fn=set_bool, default=1, use="""Try to find an unused port for the VNC server. @@ -443,7 +446,6 @@ gopts.var('uuid', val='', will be randomly generated if this option is not set, just like MAC addresses for virtual network interfaces. This must be a unique value across the entire cluster.""") - def err(msg): """Print an error to stderr and exit. @@ -494,7 +496,6 @@ def configure_disks(config_devs, vals): """Create the config for disks (virtual block devices). """ for (uname, dev, mode, backend) in vals.disk: - if uname.startswith('tap:'): cls = 'tap' else: @@ -640,8 +641,9 @@ def configure_hvm(config_image, vals): """ args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', - 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'sdl', 'display', - 'acpi', 'apic', 'xauthority', 'usb', 'usbdevice' ] + 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', + 'sdl', 'display', 'xauthority', + 'acpi', 'apic', 'usb', 'usbdevice' ] for a in args: if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) @@ -700,7 +702,7 @@ def make_config(vals): config_image = run_bootloader(vals, config_image) config.append(['bootloader', vals.bootloader]) if vals.bootargs: - config.append(['bootloader_args'], vals.bootargs) + config.append(['bootloader_args', vals.bootargs]) config.append(['image', config_image]) config_devs = [] @@ -855,7 +857,6 @@ def choose_vnc_display(): if port in ports: continue return d return None - vncpid = None def daemonize(prog, args): @@ -889,7 +890,6 @@ def daemonize(prog, args): w.write(str(pid2 or 0)) w.close() os._exit(0) - os.close(w) r = os.fdopen(r) daemon_pid = int(r.read()) @@ -908,6 +908,7 @@ def spawn_vnc(display): vncpid = daemonize("vncviewer", vncargs) if vncpid == 0: return 0 + return VNC_BASE_PORT + display def preprocess_vnc(vals): @@ -1023,11 +1024,10 @@ def parseCommandLine(argv): def parseCommandLine(argv): gopts.reset() args = gopts.parse(argv) - if gopts.vals.help: - gopts.usage() + if gopts.vals.help or gopts.vals.help_config: - gopts.load_defconfig(help=1) - if gopts.vals.help or gopts.vals.help_config: + if gopts.vals.help_config: + print gopts.val_usage() return (None, None) if not gopts.vals.display: @@ -1095,7 +1095,6 @@ def check_domain_label(config, verbose): return answer - def config_security_check(config, verbose): """Checks each resource listed in the config to see if the active policy will permit creation of a new domain using the config. @@ -1149,7 +1148,6 @@ def config_security_check(config, verbos return answer - def create_security_check(config): passed = 0 try: @@ -1162,7 +1160,9 @@ def create_security_check(config): sys.exit(-1) return passed - + +def help(): + return str(gopts) def main(argv): try: @@ -1180,11 +1180,11 @@ def main(argv): PrettyPrint.prettyprint(config) else: if not create_security_check(config): - err("Security configuration prevents domain from starting.") + raise OptionError('Security Configuration prevents domain from starting') else: dom = make_domain(opts, config) if opts.vals.console_autoconnect: - console.execConsole(dom) - + console.execConsole(dom) + if __name__ == '__main__': main(sys.argv) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/dry-run.py --- a/tools/python/xen/xm/dry-run.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/dry-run.py Wed Oct 11 13:04:07 2006 -0400 @@ -22,38 +22,36 @@ from xen.util import security from xen.util import security from xen.xm import create from xen.xend import sxp +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm dry-run <configfile>\n" - print "This program checks each resource listed in the configfile" - print "to see if the domain created by the configfile can access" - print "the resources. The status of each resource is listed" - print "individually along with the final security decision.\n" - security.err("Usage") - +def help(): + return """ + This program checks each resource listed in the configfile + to see if the domain created by the configfile can access + the resources. The status of each resource is listed + individually along with the final security decision.""" def main (argv): - try: - if len(argv) != 2: - usage() - - passed = 0 - (opts, config) = create.parseCommandLine(argv) - if create.check_domain_label(config, verbose=1): - if create.config_security_check(config, verbose=1): - passed = 1 - else: - print "Checking resources: (skipped)" - - if passed: - print "Dry Run: PASSED" - else: - print "Dry Run: FAILED" - sys.exit(-1) - - except security.ACMError: + if len(argv) != 2: + raise OptionError('Invalid number of arguments') + + passed = 0 + (opts, config) = create.parseCommandLine(argv) + if create.check_domain_label(config, verbose=1): + if create.config_security_check(config, verbose=1): + passed = 1 + else: + print "Checking resources: (skipped)" + + if passed: + print "Dry Run: PASSED" + else: + print "Dry Run: FAILED" sys.exit(-1) - if __name__ == '__main__': - main(sys.argv) + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/dumppolicy.py --- a/tools/python/xen/xm/dumppolicy.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/dumppolicy.py Wed Oct 11 13:04:07 2006 -0400 @@ -19,27 +19,24 @@ """ import sys from xen.util.security import ACMError, err, dump_policy +from xen.xm.opts import OptionError - -def usage(): - print "\nUsage: xm dumppolicy\n" - print " Retrieve and print currently enforced" - print " hypervisor policy information (low-level).\n" - err("Usage") - +def help(): + return """ + Retrieve and print currently enforced hypervisor policy information + (low-level).""" def main(argv): + if len(argv) != 1: + raise OptionError("No arguments expected.") + + dump_policy() + +if __name__ == '__main__': try: - if len(argv) != 1: - usage() - - dump_policy() - - except ACMError: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) -if __name__ == '__main__': - main(sys.argv) - - diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/getlabel.py --- a/tools/python/xen/xm/getlabel.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/getlabel.py Wed Oct 11 13:04:07 2006 -0400 @@ -21,13 +21,14 @@ import sys, os, re import sys, os, re from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm getlabel dom <configfile>" - print " xm getlabel res <resource>\n" - print " This program shows the label for a domain or resource.\n" - security.err("Usage") - +def help(): + return """ + Usage: xm getlabel dom <configfile> + xm getlabel res <resource> + + This program shows the label for a domain or resource.""" def get_resource_label(resource): """Gets the resource label @@ -37,7 +38,7 @@ def get_resource_label(resource): try: access_control = dictio.dict_read("resources", file) except: - security.err("Resource label file not found") + raise OptionError("Resource label file not found") # get the entry and print label if access_control.has_key(resource): @@ -45,23 +46,22 @@ def get_resource_label(resource): label = access_control[resource][1] print "policy="+policy+",label="+label else: - security.err("Resource not labeled") + raise security.ACMError("Resource not labeled") def get_domain_label(configfile): # open the domain config file fd = None - file = None if configfile[0] == '/': fd = open(configfile, "rb") else: for prefix in [".", "/etc/xen"]: - file = prefix + "/" + configfile - if os.path.isfile(file): - fd = open(file, "rb") + abs_file = prefix + "/" + configfile + if os.path.isfile(abs_file): + fd = open(abs_file, "rb") break if not fd: - security.err("Configuration file '"+configfile+"' not found.") + raise OptionError("Configuration file '%s' not found." % configfile) # read in the domain config file, finding the label line ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) @@ -79,7 +79,7 @@ def get_domain_label(configfile): # send error message if we didn't find anything if acline == "": - security.err("Domain not labeled") + raise security.ACMError("Domain not labeled") # print out the label (title, data) = acline.split("=", 1) @@ -89,24 +89,25 @@ def get_domain_label(configfile): print data -def main (argv): - try: - if len(argv) != 3: - usage() +def main(argv): + if len(argv) != 3: + raise OptionError('Requires 2 arguments') - if argv[1].lower() == "dom": - configfile = argv[2] - get_domain_label(configfile) - elif argv[1].lower() == "res": - resource = argv[2] - get_resource_label(resource) - else: - usage() - - except security.ACMError: - sys.exit(-1) + if argv[1].lower() == "dom": + configfile = argv[2] + get_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + get_resource_label(resource) + else: + raise OptionError('First subcommand argument must be "dom" or "res"') if __name__ == '__main__': - main(sys.argv) + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) + diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/labels.py --- a/tools/python/xen/xm/labels.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/labels.py Wed Oct 11 13:04:07 2006 -0400 @@ -23,49 +23,46 @@ import string import string from xen.util.security import ACMError, err, list_labels, active_policy from xen.util.security import vm_label_re, res_label_re, all_label_re +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n" - print " Prints labels of the specified type (default is dom)" - print " that are defined in policy (default is current" - print " hypervisor policy).\n" - err("Usage") +def help(): + return """ + Prints labels of the specified type (default is dom) + that are defined in policy (default is current hypervisor policy).""" def main(argv): + policy = None + ptype = None + for arg in argv[1:]: + key_val = arg.split('=') + if len(key_val) == 2 and key_val[0] == 'type': + if ptype: + raise OptionError('type is definied twice') + ptype = key_val[1].lower() + + elif len(key_val) == 1: + if policy: + raise OptionError('policy is defined twice') + policy = arg + else: + raise OptionError('Unrecognised option: %s' % arg) + + if not policy: + policy = active_policy + if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']: + raise OptionError('No policy active, you must specify a <policy>') + + if not ptype or ptype == 'dom': + condition = vm_label_re + elif ptype == 'res': + condition = res_label_re + elif ptype == 'any': + condition = all_label_re + else: + err("Unknown label type \'" + ptype + "\'") + try: - policy = None - type = None - for i in argv[1:]: - i_s = string.split(i, '=') - if len(i_s) > 1: - if (i_s[0] == 'type') and (len(i_s) == 2): - if not type: - type = i_s[1] - else: - usage() - else: - usage() - else: - if not policy: - policy = i - else: - usage() - - if not policy: - policy = active_policy - if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']: - err("No policy active. Please specify the <policy> parameter.") - - if not type or (type in ['DOM', 'dom']): - condition = vm_label_re - elif type in ['RES', 'res']: - condition = res_label_re - elif type in ['ANY', 'any']: - condition = all_label_re - else: - err("Unknown label type \'" + type + "\'") - labels = list_labels(policy, condition) labels.sort() for label in labels: @@ -74,9 +71,7 @@ def main(argv): except ACMError: sys.exit(-1) except: - traceback.print_exc(limit=1) - sys.exit(-1) - + traceback.print_exc(limit = 1) if __name__ == '__main__': main(sys.argv) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/loadpolicy.py --- a/tools/python/xen/xm/loadpolicy.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/loadpolicy.py Wed Oct 11 13:04:07 2006 -0400 @@ -21,28 +21,22 @@ import sys import sys import traceback from xen.util.security import ACMError, err, load_policy +from xen.xm.opts import OptionError - -def usage(): - print "\nUsage: xm loadpolicy <policy>\n" - print " Load the compiled binary (.bin) policy" - print " into the running hypervisor.\n" - err("Usage") +def help(): + return """Load the compiled binary (.bin) policy into the running + hypervisor.""" def main(argv): - try: - if len(argv) != 2: - usage() - load_policy(argv[1]) - - except ACMError: - sys.exit(-1) - except: - traceback.print_exc(limit=1) - sys.exit(-1) - + if len(argv) != 2: + raise OptionError('No policy defined') + + load_policy(argv[1]) if __name__ == '__main__': - main(sys.argv) - - + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) + diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/main.py Wed Oct 11 13:04:07 2006 -0400 @@ -22,28 +22,27 @@ """Grand unified management application for Xen. """ import os -import os.path import sys import re import getopt import socket -import warnings -warnings.filterwarnings('ignore', category=FutureWarning) +import traceback import xmlrpclib import traceback import datetime - -import xen.xend.XendProtocol +from select import select + +import warnings +warnings.filterwarnings('ignore', category=FutureWarning) from xen.xend import PrettyPrint from xen.xend import sxp -from xen.xm.opts import * - -import console -import xen.xend.XendClient +from xen.xend import XendClient from xen.xend.XendClient import server + +from xen.xm.opts import OptionError, Opts, wrap, set_true +from xen.xm import console from xen.util import security -from select import select # getopt.gnu_getopt is better, but only exists in Python 2.3+. Use # getopt.getopt if gnu_getopt is not available. This will mean that options @@ -51,93 +50,148 @@ if not hasattr(getopt, 'gnu_getopt'): if not hasattr(getopt, 'gnu_getopt'): getopt.gnu_getopt = getopt.getopt - -# Strings for shorthelp -console_help = "console <DomId> Attach to domain DomId's console." -create_help = """create [-c] <ConfigFile> - [Name=Value].. Create a domain based on Config File""" -destroy_help = "destroy <DomId> Terminate a domain immediately" -dump_core_help = """dump-core [-L|--live][-C|--crash] - <DomId> [FileName] Dump core of the specified domain""" - -help_help = "help Display this message" -list_help = "list [--long] [DomId, ...] List information about domains" -list_label_help = "list [--label] [DomId, ...] List information about domains including their labels" - -mem_max_help = "mem-max <DomId> <Mem> Set maximum memory reservation for a domain" -mem_set_help = "mem-set <DomId> <Mem> Adjust the current memory usage for a domain" -migrate_help = "migrate <DomId> <Host> Migrate a domain to another machine" -pause_help = "pause <DomId> Pause execution of a domain" -reboot_help = "reboot <DomId> [-w][-a] Reboot a domain" -restore_help = "restore <File> Create a domain from a saved state file" -save_help = "save <DomId> <File> Save domain state (and config) to file" -shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain" -top_help = "top Monitor system and domains in real-time" -unpause_help = "unpause <DomId> Unpause a paused domain" -uptime_help = "uptime [-s|--short] [DomId, ...] List uptime for domains" - -help_spacer = """ - """ - -# Strings for longhelp -sysrq_help = "sysrq <DomId> <letter> Send a sysrq to a domain" -domid_help = "domid <DomName> Converts a domain name to a domain id" -domname_help = "domname <DomId> Convert a domain id to a domain name" -vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of active VCPUs for a domain - within the range allowed by the domain - configuration""" -vcpu_list_help = "vcpu-list <DomId> List the VCPUs for a domain (or all domains)" -vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs> Set which cpus a VCPU can use" -dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buffer" -info_help = "info Get information about the xen host" -rename_help = "rename <DomId> <New Name> Rename a domain" -log_help = "log Print the xend log" -sched_sedf_help = "sched-sedf [DOM] [OPTIONS] Show|Set simple EDF parameters\n" + \ -" -p, --period Relative deadline(ms).\n\ - -s, --slice Worst-case execution time(ms)\n\ - (slice < period).\n\ - -l, --latency scaled period(ms) in case the domain\n\ - is doing heavy I/O.\n\ - -e, --extra flag (0/1) which controls whether the\n\ - domain can run in extra-time\n\ - -w, --weight mutually exclusive with period/slice and\n\ - specifies another way of setting a domain's\n\ - cpu period/slice." - -sched_credit_help = "sched-credit Set or get credit scheduler parameters" -block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode> - [BackDomId] Create a new virtual block device""" -block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device, - where <DevId> may either be the device ID - or the device name as mounted in the guest""" - -block_list_help = "block-list <DomId> [--long] List virtual block devices for a domain" -block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode> - [BackDomId] Change block device configuration""" -network_attach_help = """network-attach <DomID> [script=<script>] [ip=<ip>] [mac=<mac>] - [bridge=<bridge>] [backend=<backDomID>] - Create a new virtual network device """ -network_detach_help = """network-detach <DomId> <DevId> Destroy a domain's virtual network - device, where <DevId> is the device ID.""" - -network_list_help = "network-list <DomId> [--long] List virtual network interfaces for a domain" -vnet_list_help = "vnet-list [-l|--long] list vnets" -vnet_create_help = "vnet-create <config> create a vnet from a config file" -vnet_delete_help = "vnet-delete <vnetid> delete a vnet" -vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices" -addlabel_help = "addlabel <label> dom <configfile> Add security label to domain\n <label> res <resource> or resource" -rmlabel_help = "rmlabel dom <configfile> Remove security label from domain\n res <resource> or resource" -getlabel_help = "getlabel dom <configfile> Show security label for domain\n res <resource> or resource" -dry_run_help = "dry-run <configfile> Tests if domain can access its resources" -resources_help = "resources Show info for each labeled resource" -cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration " -dumppolicy_help = "dumppolicy Print hypervisor ACM state information" -loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor" -makepolicy_help = "makepolicy <policy> Build policy and create .bin/.map files" -labels_help = "labels [policy] [type=DOM|..] List <type> labels for (active) policy." -serve_help = "serve Proxy Xend XML-RPC over stdio" - -short_command_list = [ +# General help message + +USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \ + "Control, list, and manipulate Xen guest instances.\n" + +USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \ + 'For more help on \'xm\' see the xm(1) man page.\n' \ + 'For more help on \'xm create\' see the xmdomain.cfg(5) '\ + ' man page.\n' + +# Help strings are indexed by subcommand name in this way: +# 'subcommand': (argstring, description) + +SUBCOMMAND_HELP = { + # common commands + + 'console' : ('<Domain>', + 'Attach to <Domain>\'s console.'), + 'create' : ('<ConfigFile> [options] [vars]', + 'Create a domain based on <ConfigFile>.'), + 'destroy' : ('<Domain>', + 'Terminate a domain immediately.'), + 'help' : ('', 'Display this message.'), + 'list' : ('[options] [Domain, ...]', + 'List information about all/some domains.'), + 'mem-max' : ('<Domain> <Mem>', + 'Set the maximum amount reservation for a domain.'), + 'mem-set' : ('<Domain> <Mem>', + 'Set the current memory usage for a domain.'), + 'migrate' : ('<Domain> <Host>', + 'Migrate a domain to another machine.'), + 'pause' : ('<Domain>', 'Pause execution of a domain.'), + 'reboot' : ('<Domain> [-wa]', 'Reboot a domain.'), + 'restore' : ('<CheckpointFile>', + 'Restore a domain from a saved state.'), + 'save' : ('<Domain> <CheckpointFile>', + 'Save a domain state to restore later.'), + 'shutdown' : ('<Domain> [-waRH]', 'Shutdown a domain.'), + 'top' : ('', 'Monitor a host and the domains in real time.'), + 'unpause' : ('<Domain>', 'Unpause a paused domain.'), + 'uptime' : ('[-s] <Domain>', 'Print uptime for a domain.'), + + # less used commands + + 'dmesg' : ('[-c|--clear]', + 'Read and/or clear Xend\'s message buffer.'), + 'domid' : ('<DomainName>', 'Convert a domain name to domain id.'), + 'domname' : ('<DomId>', 'Convert a domain id to domain name.'), + 'dump-core' : ('[-L|--live] [-C|--crash] <Domain> [Filename]', + 'Dump core for a specific domain.'), + 'info' : ('', 'Get information about Xen host.'), + 'log' : ('', 'Print Xend log'), + 'rename' : ('<Domain> <NewDomainName>', 'Rename a domain.'), + 'sched-sedf' : ('<Domain> [options]', 'Get/set EDF parameters.'), + 'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]', + 'Get/set credit scheduler parameters.'), + 'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'), + 'vcpu-list' : ('[<Domain>]', + 'List the VCPUs for a domain or all domains.'), + 'vcpu-pin' : ('<Domain> <VCPU> <CPUs>', + 'Set which CPUs a VCPU can use.'), + 'vcpu-set' : ('<Domain> <vCPUs>', + 'Set the number of active VCPUs for allowed for the' + ' domain.'), + + # device commands + + 'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode>', + 'Create a new virtual block device.'), + 'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]', + 'Change block device configuration'), + 'block-detach' : ('<Domain> <DevId>', + 'Destroy a domain\'s virtual block device.'), + 'block-list' : ('<Domain> [--long]', + 'List virtual block devices for a domain.'), + 'network-attach': ('<Domain> [--script=<script>] [--ip=<ip>] ' + '[--mac=<mac>]', + 'Create a new virtual network device.'), + 'network-detach': ('<Domain> <DevId>', + 'Destroy a domain\'s virtual network device.'), + 'network-list' : ('<Domain> [--long]', + 'List virtual network interfaces for a domain.'), + 'vnet-create' : ('<ConfigFile>','Create a vnet from ConfigFile.'), + 'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'), + 'vnet-list' : ('[-l|--long]', 'List Vnets.'), + 'vtpm-list' : ('<Domain> [--long]', 'List virtual TPM devices.'), + + # security + + 'addlabel' : ('<label> {dom <ConfigFile>|res <resource>} [<policy>]', + 'Add security label to domain.'), + 'rmlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'Remove a security label from domain.'), + 'getlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'Show security label for domain or resource.'), + 'dry-run' : ('<ConfigFile>', + 'Test if a domain can access its resources.'), + 'resources' : ('', 'Show info for each labeled resource.'), + 'cfgbootpolicy' : ('<policy> [kernelversion]', + 'Add policy to boot configuration.'), + 'dumppolicy' : ('', 'Print hypervisor ACM state information.'), + 'loadpolicy' : ('<policy.bin>', 'Load binary policy into hypervisor.'), + 'makepolicy' : ('<policy>', 'Build policy and create .bin/.map ' + 'files.'), + 'labels' : ('[policy] [type=dom|res|any]', + 'List <type> labels for (active) policy.'), + 'serve' : ('', 'Proxy Xend XMLRPC over stdio.'), +} + +SUBCOMMAND_OPTIONS = { + 'sched-sedf': ( + ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'), + ('-s [MS]', '--slice[=MS]' , + 'Worst-case execution time(ms). (slice < period)'), + ('-l [MS]', '--latency[=MS]', + 'Scaled period (ms) when domain performs heavy I/O'), + ('-e [FLAG]', '--extra[=FLAG]', + 'Flag (0 or 1) controls if domain can run in extra time.'), + ('-w [FLOAT]', '--weight[=FLOAT]', + 'CPU Period/slice (do not set with --period/--slice)'), + ), + 'sched-credit': ( + ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'), + ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'), + ('-c CAP', '--cap=CAP', 'Cap (int)'), + ), + 'list': ( + ('-l', '--long', 'Output all VM details in SXP'), + ('', '--label', 'Include security labels'), + ), + 'dmesg': ( + ('-c', '--clear', 'Clear dmesg buffer'), + ), + 'vnet-list': ( + ('-l', '--long', 'List Vnets as SXP'), + ), + 'network-list': ( + ('-l', '--long', 'List resources as SXP'), + ), +} + +common_commands = [ "console", "create", "destroy", @@ -165,7 +219,6 @@ domain_commands = [ "domname", "dump-core", "list", - "list_label", "mem-max", "mem-set", "migrate", @@ -223,67 +276,110 @@ acm_commands = [ "makepolicy", "loadpolicy", "cfgbootpolicy", - "dumppolicy" + "dumppolicy", ] all_commands = (domain_commands + host_commands + scheduler_commands + device_commands + vnet_commands + acm_commands) - -def commandToHelp(cmd): - return eval(cmd.replace("-", "_") + "_help") - - -shorthelp = """Usage: xm <subcommand> [args] - Control, list, and manipulate Xen guest instances - -xm common subcommands: - """ + help_spacer.join(map(commandToHelp, short_command_list)) + """ - -<DomName> can be substituted for <DomId> in xm subcommands. - -For a complete list of subcommands run 'xm help --long' -For more help on xm see the xm(1) man page -For more help on xm create, see the xmdomain.cfg(5) man page""" - -longhelp = """Usage: xm <subcommand> [args] - Control, list, and manipulate Xen guest instances - -xm full list of subcommands: - - Domain Commands: - """ + help_spacer.join(map(commandToHelp, domain_commands)) + """ - - Xen Host Commands: - """ + help_spacer.join(map(commandToHelp, host_commands)) + """ - - Scheduler Commands: - """ + help_spacer.join(map(commandToHelp, scheduler_commands)) + """ - - Virtual Device Commands: - """ + help_spacer.join(map(commandToHelp, device_commands)) + """ - - Vnet commands: - """ + help_spacer.join(map(commandToHelp, vnet_commands)) + """ - - Access Control commands: - """ + help_spacer.join(map(commandToHelp, acm_commands)) + """ - -<DomName> can be substituted for <DomId> in xm subcommands. - -For a short list of subcommands run 'xm help' -For more help on xm see the xm(1) man page -For more help on xm create, see the xmdomain.cfg(5) man page""" - -# array for xm help <command> -help = { - "--long": longhelp - } - -for command in all_commands: - # create is handled specially - if (command != 'create'): - help[command] = commandToHelp(command) +#################################################################### +# +# Help/usage printing functions +# +#################################################################### + +def cmdHelp(cmd): + """Print help for a specific subcommand.""" + + for fc in SUBCOMMAND_HELP.keys(): + if fc[:len(cmd)] == cmd: + cmd = fc + break + + try: + args, desc = SUBCOMMAND_HELP[cmd] + except KeyError: + shortHelp() + return + + print 'Usage: xm %s %s' % (cmd, args) + print + print desc + + try: + # If options help message is defined, print this. + for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]: + if shortopt and longopt: + optdesc = '%s, %s' % (shortopt, longopt) + elif shortopt: + optdesc = shortopt + elif longopt: + optdesc = longopt + + wrapped_desc = wrap(desc, 43) + print ' %-30s %-43s' % (optdesc, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 33 + line + print + except KeyError: + # if the command is an external module, we grab usage help + # from the module itself. + if cmd in IMPORTED_COMMANDS: + try: + cmd_module = __import__(cmd, globals(), locals(), 'xen.xm') + cmd_usage = getattr(cmd_module, "help", None) + if cmd_usage: + print cmd_usage() + except ImportError: + pass + +def shortHelp(): + """Print out generic help when xm is called without subcommand.""" + + print USAGE_HELP + print 'Common \'xm\' commands:\n' + + for command in common_commands: + try: + args, desc = SUBCOMMAND_HELP[command] + except KeyError: + continue + wrapped_desc = wrap(desc, 50) + print ' %-20s %-50s' % (command, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 22 + line + + print + print USAGE_FOOTER + print 'For a complete list of subcommands run \'xm help\'.' + +def longHelp(): + """Print out full help when xm is called with xm --help or xm help""" + + print USAGE_HELP + print 'xm full list of subcommands:\n' + + for command in all_commands: + try: + args, desc = SUBCOMMAND_HELP[command] + except KeyError: + continue + + wrapped_desc = wrap(desc, 50) + print ' %-20s %-50s' % (command, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 22 + line + + print + print USAGE_FOOTER + +def usage(cmd = None): + """ Print help usage information and exits """ + if cmd: + cmdHelp(cmd) + else: + shortHelp() + sys.exit(1) #################################################################### @@ -298,7 +394,7 @@ def arg_check(args, name, lo, hi = -1): if hi == -1: if n != lo: err("'xm %s' requires %d argument%s.\n" % (name, lo, - lo > 1 and 's' or '')) + lo == 1 and '' or 's')) usage(name) else: if n < lo or n > hi: @@ -345,14 +441,19 @@ def xm_save(args): def xm_save(args): arg_check(args, "save", 2) - dom = args[0] # TODO: should check if this exists + try: + dominfo = parse_doms_info(server.xend.domain(args[0])) + except xmlrpclib.Fault, ex: + raise ex + + domid = dominfo['domid'] savefile = os.path.abspath(args[1]) if not os.access(os.path.dirname(savefile), os.W_OK): err("xm save: Unable to create file %s" % savefile) sys.exit(1) - server.xend.domain.save(dom, savefile) + server.xend.domain.save(domid, savefile) def xm_restore(args): arg_check(args, "restore", 1) @@ -366,9 +467,9 @@ def xm_restore(args): server.xend.domain.restore(savefile) -def getDomains(domain_names): +def getDomains(domain_names, full = 0): if domain_names: - return map(server.xend.domain, domain_names) + return [server.xend.domain(dom) for dom in domain_names] else: return server.xend.domains(1) @@ -378,9 +479,11 @@ def xm_list(args): show_vcpus = 0 show_labels = 0 try: - (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label']) + (options, params) = getopt.gnu_getopt(args, 'lv', + ['long','vcpus','label']) except getopt.GetoptError, opterr: err(opterr) + usage('list') sys.exit(1) for (k, v) in options: @@ -397,7 +500,7 @@ def xm_list(args): xm_vcpu_list(params) return - doms = getDomains(params) + doms = getDomains(params, use_long) if use_long: map(PrettyPrint.prettyprint, doms) @@ -412,7 +515,7 @@ def parse_doms_info(info): return t(sxp.child_value(info, n, d)) return { - 'dom' : get_info('domid', int, -1), + 'domid' : get_info('domid', int, -1), 'name' : get_info('name', str, '??'), 'mem' : get_info('memory', int, 0), 'vcpus' : get_info('online_vcpus', int, 0), @@ -428,7 +531,7 @@ def parse_sedf_info(info): return t(sxp.child_value(info, n, d)) return { - 'dom' : get_info('domain', int, -1), + 'domid' : get_info('domain', int, -1), 'period' : get_info('period', int, -1), 'slice' : get_info('slice', int, -1), 'latency' : get_info('latency', int, -1), @@ -436,34 +539,40 @@ def parse_sedf_info(info): 'weight' : get_info('weight', int, -1), } - def xm_brief_list(doms): - print 'Name ID Mem(MiB) VCPUs State Time(s)' + print '%-40s %3s %8s %5s %5s %9s' % \ + ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)') + + format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \ + "%(cpu_time)8.1f" + for dom in doms: d = parse_doms_info(dom) - print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d) - + print format % d def xm_label_list(doms): + print '%-32s %3s %8s %5s %5s %9s %-8s' % \ + ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label') + output = [] - print 'Name ID Mem(MiB) VCPUs State Time(s) Label' + format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \ + '%(cpu_time)8.1f %(seclabel)9s' + for dom in doms: d = parse_doms_info(dom) - l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f " % d if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']: - if d['seclabel']: - line = (l, d['seclabel']) - else: - line = (l, "ERROR") + if not d['seclabel']: + d['seclabel'] = 'ERROR' elif security.active_policy in ['DEFAULT']: - line = (l, "DEFAULT") + d['seclabel'] = 'DEFAULT' else: - line = (l, "INACTIVE") - output.append(line) + d['seclabel'] = 'INACTIVE' + output.append((format % d, d['seclabel'])) + #sort by labels output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower())) - for l in output: - print l[0] + l[1] + for line, label in output: + print line def xm_vcpu_list(args): @@ -474,7 +583,11 @@ def xm_vcpu_list(args): doms = server.xend.domains(False) dominfo = map(server.xend.domain.getVCPUInfo, doms) - print 'Name ID VCPU CPU State Time(s) CPU Affinity' + print '%-32s %3s %5s %5s %5s %9s %s' % \ + ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity') + + format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \ + ' %(cpu_time)8.1f %(cpumap)s' for dom in dominfo: def get_info(n): @@ -568,10 +681,7 @@ def xm_vcpu_list(args): c = "-" s = "--p" - print ( - "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" % - locals()) - + print format % locals() def xm_reboot(args): arg_check(args, "reboot", 1, 3) @@ -596,22 +706,21 @@ def xm_unpause(args): server.xend.domain.unpause(dom) def xm_dump_core(args): - arg_check(args, "dump-core",1,3) live = False crash = False - import getopt - (options, params) = getopt.gnu_getopt(args, 'LC', ['live','crash']) - - for (k, v) in options: - if k in ['-L', '--live']: - live = True - if k in ['-C', '--crash']: - crash = True - - if len(params) == 0 or len(params) > 2: - err("invalid number of parameters") - usage("dump-core") - + try: + (options, params) = getopt.gnu_getopt(args, 'LC', ['live','crash']) + for (k, v) in options: + if k in ('-L', '--live'): + live = True + if k in ('-C', '--crash'): + crash = True + + if len(params) not in (1, 2): + raise OptionError("Expects 1 or 2 argument(s)") + except getopt.GetoptError, e: + raise OptionError(str(e)) + dom = params[0] if len(params) == 2: filename = os.path.abspath(params[1]) @@ -622,45 +731,49 @@ def xm_dump_core(args): server.xend.domain.pause(dom) try: - print "dumping core of domain:%s ..." % str(dom) + print "Dumping core of domain: %s ..." % str(dom) server.xend.domain.dump(dom, filename, live, crash) finally: if not live: server.xend.domain.unpause(dom) if crash: - print "destroying domain:%s ..." % str(dom) + print "Destroying domain: %s ..." % str(dom) server.xend.domain.destroy(dom) def xm_rename(args): arg_check(args, "rename", 2) - + server.xend.domain.setName(args[0], args[1]) -def xm_subcommand(command, args): +def xm_importcommand(command, args): cmd = __import__(command, globals(), locals(), 'xen.xm') cmd.main([command] + args) ############################################################# -def cpu_make_map(cpulist): - cpus = [] - for c in cpulist.split(','): - if c.find('-') != -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() - return cpus - def xm_vcpu_pin(args): arg_check(args, "vcpu-pin", 3) + def cpu_make_map(cpulist): + cpus = [] + for c in cpulist.split(','): + if c.find('-') != -1: + (x,y) = c.split('-') + for i in range(int(x),int(y)+1): + cpus.append(int(i)) + else: + # remove this element from the list + if c[0] == '^': + cpus = [x for x in cpus if x != int(c[1:])] + else: + cpus.append(int(c)) + cpus.sort() + return cpus + dom = args[0] - vcpu = int(args[1]) + vcpu = args[1] cpumap = cpu_make_map(args[2]) server.xend.domain.pincpu(dom, vcpu, cpumap) @@ -719,11 +832,12 @@ def xm_sched_sedf(args): info['period'] = ns_to_ms(info['period']) info['slice'] = ns_to_ms(info['slice']) info['latency'] = ns_to_ms(info['latency']) - print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" + + print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" + " %(latency)7.1f %(extratime)6d %(weight)6d") % info) def domid_match(domid, info): - return domid is None or domid == info['name'] or domid == str(info['dom']) + return domid is None or domid == info['name'] or \ + domid == str(info['domid']) # we want to just display current info if no parameters are passed if len(args) == 0: @@ -757,20 +871,25 @@ def xm_sched_sedf(args): elif k in ['-w', '--weight']: opts['weight'] = v + doms = filter(lambda x : domid_match(domid, x), + [parse_doms_info(dom) for dom in getDomains("")]) + # print header if we aren't setting any parameters if len(opts.keys()) == 0: - print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)', - 'Slice(ms)', 'Lat(ms)', - 'Extra','Weight') - - doms = filter(lambda x : domid_match(domid, x), - [parse_doms_info(dom) for dom in getDomains("")]) + print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \ + ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)', + 'Extra','Weight') + for d in doms: # fetch current values so as not to clobber them - sedf_info = \ - parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom'])) + try: + sedf_raw = server.xend.domain.cpu_sedf_get(d['domid']) + except xmlrpclib.Fault: + # domain does not support sched-sedf? + sedf_raw = {} + + sedf_info = parse_sedf_info(sedf_raw) sedf_info['name'] = d['name'] - # update values in case of call to set if len(opts.keys()) > 0: for k in opts.keys(): @@ -780,7 +899,7 @@ def xm_sched_sedf(args): v = map(int, [sedf_info['period'], sedf_info['slice'], sedf_info['latency'],sedf_info['extratime'], sedf_info['weight']]) - rv = server.xend.domain.cpu_sedf_set(d['dom'], *v) + rv = server.xend.domain.cpu_sedf_set(d['domid'], *v) if int(rv) != 0: err("Failed to set sedf parameters (rv=%d)."%(rv)) @@ -789,17 +908,14 @@ def xm_sched_sedf(args): print_sedf(sedf_info) def xm_sched_credit(args): - usage_msg = """sched-credit: Set or get credit scheduler parameters - Usage: - - sched-credit -d domain [-w weight] [-c cap] - """ + """Get/Set options for Credit Scheduler.""" + try: - opts, args = getopt.getopt(args[0:], "d:w:c:", + opts, params = getopt.getopt(args, "d:w:c:", ["domain=", "weight=", "cap="]) - except getopt.GetoptError: - # print help information and exit: - print usage_msg + except getopt.GetoptError, opterr: + err(opterr) + usage('sched-credit') sys.exit(1) domain = None @@ -816,20 +932,16 @@ def xm_sched_credit(args): if domain is None: # place holder for system-wide scheduler parameters - print usage_msg + err("No domain given.") + usage('sched-credit') sys.exit(1) if weight is None and cap is None: print server.xend.domain.sched_credit_get(domain) else: - if weight is None: - weight = int(0) - if cap is None: - cap = int(~0) - - err = server.xend.domain.sched_credit_set(domain, weight, cap) - if err != 0: - print err + result = server.xend.domain.sched_credit_set(domain, weight, cap) + if result != 0: + err(str(result)) def xm_info(args): arg_check(args, "info", 0) @@ -848,6 +960,8 @@ def xm_console(args): dom = args[0] info = server.xend.domain(dom) domid = int(sxp.child_value(info, 'domid', '-1')) + if domid == -1: + raise Exception("Domain is not started") console.execConsole(domid) def xm_uptime(args): @@ -870,7 +984,7 @@ def xm_uptime(args): for dom in doms: d = parse_doms_info(dom) - if d['dom'] > 0: + if d['domid'] > 0: uptime = int(round(d['up_time'])) else: f=open('/proc/uptime', 'r') @@ -897,12 +1011,18 @@ def xm_uptime(args): if short_mode: now = datetime.datetime.now() upstring = now.strftime(" %H:%M:%S") + " up " + upstring - upstring += ", " + d['name'] + " (" + str(d['dom']) + ")" + upstring += ", " + d['name'] + " (" + str(d['domid']) + ")" else: upstring += ':%(seconds)02d' % vars() - upstring = ("%(name)-32s %(dom)3d " % d) + upstring + upstring = ("%(name)-32s %(domid)3d " % d) + upstring print upstring + +def xm_sysrq(args): + arg_check(args, "sysrq", 2) + dom = args[0] + req = args[1] + server.xend.domain.send_sysrq(dom, req) def xm_top(args): arg_check(args, "top", 0) @@ -925,8 +1045,11 @@ its contents if the [-c|--clear] flag is myargs = args myargs.insert(0, 'dmesg') gopts.parse(myargs) - if not (1 <= len(myargs) <= 2): + + if len(myargs) not in (1, 2): err('Invalid arguments: ' + str(myargs)) + usage('dmesg') + sys.exit(1) if not gopts.vals.clear: print server.xend.node.dmesg.info() @@ -944,7 +1067,7 @@ def xm_serve(args): from fcntl import fcntl, F_SETFL s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(xen.xend.XendClient.XML_RPC_SOCKET) + s.connect(XendClient.XML_RPC_SOCKET) fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK) while True: @@ -1090,7 +1213,7 @@ def parse_block_configuration(args): cls = 'tap' else: cls = 'vbd' - + vbd = [cls, ['uname', args[1]], ['dev', args[2]], @@ -1099,19 +1222,12 @@ def parse_block_configuration(args): vbd.append(['backend', args[4]]) # verify that policy permits attaching this resource - try: - if security.on(): - dominfo = server.xend.domain(dom) - label = security.get_security_printlabel(dominfo) - else: - label = None - security.res_security_check(args[1], label) - except security.ACMError, e: - print e.value - sys.exit(1) - except: - traceback.print_exc(limit=1) - sys.exit(1) + if security.on(): + dominfo = server.xend.domain(dom) + label = security.get_security_printlabel(dominfo) + else: + label = None + security.res_security_check(args[1], label) return (dom, vbd) @@ -1211,11 +1327,12 @@ commands = { "domid": xm_domid, "domname": xm_domname, "dump-core": xm_dump_core, + "reboot": xm_reboot, "rename": xm_rename, "restore": xm_restore, "save": xm_save, - "reboot": xm_reboot, "shutdown": xm_shutdown, + "sysrq": xm_sysrq, "uptime": xm_uptime, "list": xm_list, # memory commands @@ -1254,24 +1371,23 @@ commands = { } ## The commands supported by a separate argument parser in xend.xm. -subcommands = [ +IMPORTED_COMMANDS = [ 'create', 'migrate', - 'sysrq', 'labels', 'addlabel', + 'cfgbootpolicy', + 'makepolicy', + 'loadpolicy', + 'dumppolicy', 'rmlabel', 'getlabel', 'dry-run', 'resources', - 'cfgbootpolicy', - 'makepolicy', - 'loadpolicy', - 'dumppolicy' ] -for c in subcommands: - commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c) +for c in IMPORTED_COMMANDS: + commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c) aliases = { "balloon": "mem-set", @@ -1289,11 +1405,18 @@ def xm_lookup_cmd(cmd): elif aliases.has_key(cmd): deprecated(cmd,aliases[cmd]) return commands[aliases[cmd]] - else: - if len( cmd ) > 1: - matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() ) - if len( matched_commands ) == 1: - return matched_commands[0][1] + elif cmd == 'help': + longHelp() + sys.exit(0) + else: + # simulate getopt's prefix matching behaviour + if len(cmd) > 1: + same_prefix_cmds = [commands[c] for c in commands.keys() \ + if c[:len(cmd)] == cmd] + # only execute if there is only 1 match + if len(same_prefix_cmds) == 1: + return same_prefix_cmds[0] + err('Sub Command %s not found!' % cmd) usage() @@ -1301,27 +1424,18 @@ def deprecated(old,new): print >>sys.stderr, ( "Command %s is deprecated. Please use xm %s instead." % (old, new)) -def usage(cmd=None): - if cmd == 'create': - mycmd = xm_lookup_cmd(cmd) - mycmd( ['--help'] ) - sys.exit(1) - if help.has_key(cmd): - print " " + help[cmd] - else: - print shorthelp - sys.exit(1) - def main(argv=sys.argv): if len(argv) < 2: usage() - - if re.compile('-*help').match(argv[1]): - if len(argv) > 2: - usage(argv[2]) - else: - usage() - sys.exit(0) + + # intercept --help(-h) and output our own help + for help in ['--help', '-h']: + if help in argv[1:]: + if help == argv[1]: + longHelp() + else: + usage(argv[1]) + sys.exit(0) cmd = xm_lookup_cmd(argv[1]) @@ -1334,9 +1448,9 @@ def main(argv=sys.argv): usage() except socket.error, ex: if os.geteuid() != 0: - err("Most commands need root access. Please try again as root.") + err("Most commands need root access. Please try again as root.") else: - err("Error connecting to xend: %s. Is xend running?" % ex[1]) + err("Unable to connect to xend: %s. Is xend running?" % ex[1]) sys.exit(1) except KeyboardInterrupt: print "Interrupted." @@ -1345,16 +1459,16 @@ def main(argv=sys.argv): if os.geteuid() != 0: err("Most commands need root access. Please try again as root.") else: - err("Error connecting to xend: %s." % ex[1]) + err("Unable to connect to xend: %s." % ex[1]) sys.exit(1) except SystemExit: sys.exit(1) except xmlrpclib.Fault, ex: - if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN: - print >>sys.stderr, ( - "Error: the domain '%s' does not exist." % ex.faultString) + if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN: + err("Domain '%s' does not exist." % ex.faultString) else: - print >>sys.stderr, "Error: %s" % ex.faultString + err(ex.faultString) + usage(argv[1]) sys.exit(1) except xmlrpclib.ProtocolError, ex: if ex.errcode == -1: @@ -1369,6 +1483,15 @@ def main(argv=sys.argv): except (ValueError, OverflowError): err("Invalid argument.") usage(argv[1]) + sys.exit(1) + except OptionError, e: + err(str(e)) + usage(argv[1]) + print e.usage() + sys.exit(1) + except security.ACMError, e: + err(str(e)) + sys.exit(1) except: print "Unexpected error:", sys.exc_info()[0] print diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/makepolicy.py --- a/tools/python/xen/xm/makepolicy.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/makepolicy.py Wed Oct 11 13:04:07 2006 -0400 @@ -20,7 +20,7 @@ import sys import sys import traceback from xen.util.security import ACMError, err, make_policy - +from xen.xm.opts import OptionError def usage(): print "\nUsage: xm makepolicy <policy>\n" @@ -29,22 +29,17 @@ def usage(): err("Usage") +def main(argv): + if len(argv) != 2: + raise OptionError('No XML policy file specified') -def main(argv): + make_policy(argv[1]) + +if __name__ == '__main__': try: - if len(argv) != 2: - usage() - make_policy(argv[1]) - - except ACMError: - sys.exit(-1) - except: - traceback.print_exc(limit=1) + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) - -if __name__ == '__main__': - main(sys.argv) - - diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/migrate.py --- a/tools/python/xen/xm/migrate.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/migrate.py Wed Oct 11 13:04:07 2006 -0400 @@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MB fn=set_int, default=0, use="Set level of resource usage for migration.") -def help(argv): - gopts.argv = argv - gopts.usage() +def help(): + return str(gopts) def main(argv): opts = gopts args = opts.parse(argv) - if opts.vals.help: - opts.usage() - return + if len(args) != 2: - opts.usage() - sys.exit(1) + raise OptionError('Invalid number of arguments') + dom = args[0] dst = args[1] - server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port) + server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, + opts.vals.port) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/opts.py --- a/tools/python/xen/xm/opts.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/opts.py Wed Oct 11 13:04:07 2006 -0400 @@ -23,6 +23,42 @@ import os.path import os.path import sys import types + +def _line_wrap(text, width = 70): + lines = [] + current_line = '' + words = text.strip().split() + while words: + word = words.pop(0) + if len(current_line) + len(word) + 1 < width: + current_line += word + ' ' + else: + lines.append(current_line.strip()) + current_line = word + ' ' + + if current_line: + lines.append(current_line.strip()) + return lines + +def wrap(text, width = 70): + """ Really basic textwrap. Useful because textwrap is not available + for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+. + """ + if len(text) < width: + return [text] + + lines = [] + for line in text.split('\n'): + lines += _line_wrap(line, width) + return lines + +class OptionError(Exception): + """Denotes an error in option parsing.""" + def __init__(self, message, usage = ''): + self.message = message + self.usage = usage + def __str__(self): + return self.message class Opt: """An individual option. @@ -72,7 +108,21 @@ class Opt: def __repr__(self): return self.name + '=' + str(self.specified_val) - __str__ = __repr__ + def __str__(self): + """ Formats the option into: + '-k, --key description' + """ + PARAM_WIDTH = 20 + if self.val: + keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys]) + else: + keys = ', '.join(self.optkeys) + desc = wrap(self.use, 55) + if len(keys) > PARAM_WIDTH: + desc = [''] + desc + + wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc) + return keys.ljust(PARAM_WIDTH + 1) + wrapped def set(self, value): """Set the option value. @@ -243,8 +293,24 @@ class Opts: def __repr__(self): return '\n'.join(map(str, self.options)) - __str__ = __repr__ - + def __str__(self): + options = [s for s in self.options if s.optkeys[0][0] == '-'] + output = '' + if options: + output += '\nOptions:\n\n' + output += '\n'.join([str(o) for o in options]) + output += '\n' + return output + + def val_usage(self): + optvals = [s for s in self.options if s.optkeys[0][0] != '-'] + output = '' + if optvals: + output += '\nValues:\n\n' + output += '\n'.join([str(o) for o in optvals]) + output += '\n' + return output + def opt(self, name, **args): """Add an option. @@ -338,14 +404,14 @@ class Opts: self.short_opts(), self.long_opts()) except getopt.GetoptError, err: - self.err(str(err)) + raise OptionError(str(err), self.use) + #self.err(str(err)) for (k, v) in xvals: for opt in self.options: if opt.specify(k, v): break else: - print >>sys.stderr, "Error: Unknown option:", k - self.usage() + raise OptionError('Unknown option: %s' % k, self.use) if not args: break @@ -390,10 +456,10 @@ class Opts: def usage(self): print 'Usage: ', self.argv[0], self.use or 'OPTIONS' print - for opt in self.options: - opt.show() - print if self.options: + for opt in self.options: + opt.show() + print print def var_usage(self): @@ -427,7 +493,9 @@ class Opts: self.load(p, help) break else: - self.err('Cannot open config file "%s"' % self.vals.defconfig) + raise OptionError('Unable to open config file: %s' % \ + self.vals.defconfig, + self.use) def load(self, defconfig, help): """Load a defconfig file. Local variables in the file @@ -478,9 +546,9 @@ def set_bool(opt, k, v): def set_bool(opt, k, v): """Set a boolean option. """ - if v in ['yes']: + if v in ('yes', 'y'): opt.set(1) - elif v in ['no']: + elif v in ('no', 'n'): opt.set(0) else: opt.opts.err('Invalid value:' +v) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/resources.py --- a/tools/python/xen/xm/resources.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/resources.py Wed Oct 11 13:04:07 2006 -0400 @@ -21,13 +21,12 @@ import sys import sys from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm resource\n" - print " This program lists information for each resource in the" - print " global resource label file\n" - security.err("Usage") - +def help(): + return """ + This program lists information for each resource in the + global resource label file.""" def print_resource_data(access_control): """Prints out a resource dictionary to stdout @@ -38,24 +37,21 @@ def print_resource_data(access_control): print " policy: "+policy print " label: "+label +def main (argv): + if len(argv) > 1: + raise OptionError("No arguments required") + + try: + filename = security.res_label_filename + access_control = dictio.dict_read("resources", filename) + except: + raise OptionError("Resource file not found") -def main (argv): - try: - if len(argv) != 1: - usage() - - try: - file = security.res_label_filename - access_control = dictio.dict_read("resources", file) - except: - security.err("Error reading resource file.") - - print_resource_data(access_control) - - except security.ACMError: - sys.exit(-1) + print_resource_data(access_control) if __name__ == '__main__': - main(sys.argv) - - + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/rmlabel.py --- a/tools/python/xen/xm/rmlabel.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/rmlabel.py Wed Oct 11 13:04:07 2006 -0400 @@ -21,15 +21,17 @@ import sys, os, re import sys, os, re from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm rmlabel dom <configfile>" - print " xm rmlabel res <resource>\n" - print " This program removes an acm_label entry from the 'configfile'" - print " for a domain or from the global resource label file for a" - print " resource. If the label does not exist for the given domain or" - print " resource, then rmlabel fails.\n" - security.err("Usage") +def help(): + return """ + Example: xm rmlabel dom <configfile> + xm rmlabel res <resource> + + This program removes an acm_label entry from the 'configfile' + for a domain or from the global resource label file for a + resource. If the label does not exist for the given domain or + resource, then rmlabel fails.""" def rm_resource_label(resource): @@ -40,14 +42,14 @@ def rm_resource_label(resource): try: access_control = dictio.dict_read("resources", file) except: - security.err("Resource file not found, cannot remove label!") + raise security.ACMError("Resource file not found, cannot remove label!") # remove the entry and update file if access_control.has_key(resource): del access_control[resource] dictio.dict_write(access_control, "resources", file) else: - security.err("Resource not labeled.") + raise security.ACMError("Resource not labeled") def rm_domain_label(configfile): @@ -55,7 +57,8 @@ def rm_domain_label(configfile): fd = None file = None if configfile[0] == '/': - fd = open(configfile, "rb") + file = configfile + fd = open(file, "rb") else: for prefix in [".", "/etc/xen"]: file = prefix + "/" + configfile @@ -63,8 +66,8 @@ def rm_domain_label(configfile): fd = open(file, "rb") break if not fd: - security.err("Configuration file '"+configfile+"' not found.") - + raise OptionError("Configuration file '%s' not found." % configfile) + # read in the domain config file, removing label ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) ac_exit_re = re.compile(".*'\].*") @@ -84,7 +87,7 @@ def rm_domain_label(configfile): # send error message if we didn't find anything to remove if not removed: - security.err("Domain not labeled.") + raise security.ACMError('Domain not labeled') # write the data back out to the file fd = open(file, "wb") @@ -93,24 +96,25 @@ def rm_domain_label(configfile): def main (argv): - try: - if len(argv) != 3: - usage() - if argv[1].lower() == "dom": - configfile = argv[2] - rm_domain_label(configfile) - elif argv[1].lower() == "res": - resource = argv[2] - rm_resource_label(resource) - else: - usage() + if len(argv) != 3: + raise OptionError('Requires 2 arguments') + + if argv[1].lower() not in ('dom', 'res'): + raise OptionError('Unrecognised type argument: %s' % argv[1]) - except security.ACMError: - sys.exit(-1) - + if argv[1].lower() == "dom": + configfile = argv[2] + rm_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + rm_resource_label(resource) if __name__ == '__main__': - main(sys.argv) + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/shutdown.py --- a/tools/python/xen/xm/shutdown.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/python/xen/xm/shutdown.py Wed Oct 11 13:04:07 2006 -0400 @@ -120,7 +120,6 @@ def main(argv): opts = gopts args = opts.parse(argv) if opts.vals.help: - opts.usage() return if opts.vals.all: main_all(opts, args) diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/doc/man/vn.pod.1 --- a/tools/vnet/doc/man/vn.pod.1 Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/doc/man/vn.pod.1 Wed Oct 11 13:04:07 2006 -0400 @@ -105,7 +105,7 @@ the vnet device to it. =item B<-v | --vnetif> I<vnetifname> Use I<vnetifname> as the name for the vnet device. If this option -is not specified the default isto name the device vnifN where N +is not specified the default is to name the device vnifN where N is the last field of the vnet id as 4 hex characters. For example vnif0004. Network device names can be at most 14 characters. @@ -173,4 +173,4 @@ This library is free software; you can r This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. \ No newline at end of file +(at your option) any later version. diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/Makefile --- a/tools/vnet/libxutil/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/libxutil/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -30,6 +30,8 @@ PIC_OBJS := $(LIB_SRCS:.c=.opic) PIC_OBJS := $(LIB_SRCS:.c=.opic) CFLAGS += -Werror -fno-strict-aliasing +CFLAGS += -O3 +#CFLAGS += -g # Get gcc to generate the dependencies for us. CFLAGS += -Wp,-MD,.$(@F).d diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/hash_table.c --- a/tools/vnet/libxutil/hash_table.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/libxutil/hash_table.c Wed Oct 11 13:04:07 2006 -0400 @@ -116,7 +116,7 @@ acceptable. Do NOT use for cryptographi -------------------------------------------------------------------- */ -ub4 hash(const ub1 *k, ub4 length, ub4 initval) +static inline ub4 _hash(const ub1 *k, ub4 length, ub4 initval) //register ub1 *k; /* the key */ //register ub4 length; /* the length of the key */ //register ub4 initval; /* the previous hash, or an arbitrary value */ @@ -160,6 +160,11 @@ ub4 hash(const ub1 *k, ub4 length, ub4 i /*-------------------------------------------- report the result */ return c; } + +ub4 hash(const ub1 *k, ub4 length, ub4 initval){ + return _hash(k, length, initval); +} + /*============================================================================*/ /** Get the bucket for a hashcode in a hash table. @@ -381,6 +386,9 @@ inline HTEntry * HashTable_find_entry(Ha * @return 1 if equal, 0 otherwise */ inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){ + if(table->key_size){ + return memcmp(key1, key2, table->key_size) == 0; + } return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == key2); } @@ -393,6 +401,9 @@ inline int HashTable_key_equal(HashTable * @return hashcode */ inline Hashcode HashTable_key_hash(HashTable *table, void *key){ + if(table->key_size){ + return _hash(key, table->key_size, 0); + } return (table->key_hash_fn ? table->key_hash_fn(key) : hash_hvoid(0, &key, sizeof(key))); diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/hash_table.h --- a/tools/vnet/libxutil/hash_table.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/libxutil/hash_table.h Wed Oct 11 13:04:07 2006 -0400 @@ -96,6 +96,7 @@ struct HashTable { int buckets_n; /** Number of entries in the table. */ int entry_count; + unsigned long key_size; /** Function to free keys and values in entries. */ TableFreeFn *entry_free_fn; /** Function to hash keys. */ diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/Makefile.ver --- a/tools/vnet/vnet-module/Makefile.ver Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/Makefile.ver Wed Oct 11 13:04:07 2006 -0400 @@ -18,27 +18,32 @@ # 59 Temple Place, suite 330, Boston, MA 02111-1307 USA #============================================================================ -LINUX_SERIES ?=2.6 -KERNEL_MINOR ?=-xen0 +LINUX_SERIES?=2.6 +KERNEL_MINOR=-xen -LINUX_VERSION ?= $(shell (/bin/ls -ld $(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \ +LINUX_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \ sed -e 's!^.*linux-\(.\+\)!\1!' ) ifeq ($(LINUX_VERSION),) $(error Kernel source for linux $(LINUX_SERIES) not found) endif -KERNEL_VERSION =$(LINUX_VERSION)$(KERNEL_MINOR) +KERNEL_VERSION=$(LINUX_VERSION)$(KERNEL_MINOR) -KERNEL_SRC ?= $(XEN_ROOT)/linux-$(KERNEL_VERSION) +KERNEL_SRC?=$(shell cd $(XEN_ROOT)/linux-$(KERNEL_VERSION) && pwd) + +ifeq ($(KERNEL_SRC),) +$(error Kernel source for kernel $(KERNEL_VERSION) not found) +endif # Get the full kernel release version from its makefile, as the source path # may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 2.6.12.6-xen0. -KERNEL_RELEASE = $(shell make -s -C $(KERNEL_SRC) kernelrelease || \ - make -f $(shell pwd)/Makefile.kver -s -C $(KERNEL_SRC) kernelrelease ) +KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease) -KERNEL_MODULE_DIR = /lib/modules/$(KERNEL_RELEASE)/kernel +KERNEL_MODULE_DIR=/lib/modules/$$(KERNEL_RELEASE)/kernel -$(warning KERNEL_SRC $(KERNEL_SRC)) -#$(warning KERNEL_VERSION $(KERNEL_VERSION)) -$(warning KERNEL_RELEASE $(KERNEL_RELEASE)) +$(warning KERNEL_SRC $(KERNEL_SRC)) +$(warning LINUX_VERSION $(LINUX_VERSION)) +$(warning KERNEL_VERSION $(KERNEL_VERSION)) +$(warning KERNEL_RELEASE $(KERNEL_RELEASE)) +$(warning KERNEL_ MODULE_DIR $(KERNEL_MODULE_DIR)) diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/esp.c --- a/tools/vnet/vnet-module/esp.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/esp.c Wed Oct 11 13:04:07 2006 -0400 @@ -104,7 +104,7 @@ void __exit esp_module_exit(void){ * @param block size to round to a multiple of * @return rounded value */ -static inline int roundup(int n, int block){ +static inline int roundupto(int n, int block){ if(block <= 1) return n; block--; return (n + block) & ~block; @@ -312,9 +312,9 @@ static int esp_sa_send(SAState *sa, stru // header and IP header. plaintext_n = skb->len - ETH_HLEN - ip_n; // Add size of padding fields. - ciphertext_n = roundup(plaintext_n + ESP_PAD_N, esp->cipher.block_n); + ciphertext_n = roundupto(plaintext_n + ESP_PAD_N, esp->cipher.block_n); if(esp->cipher.pad_n > 0){ - ciphertext_n = roundup(ciphertext_n, esp->cipher.pad_n); + ciphertext_n = roundupto(ciphertext_n, esp->cipher.pad_n); } extra_n = ciphertext_n - plaintext_n; iv_n = esp->cipher.iv_n; @@ -502,9 +502,9 @@ static u32 esp_sa_size(SAState *sa, int // Have to add some padding for alignment even if pad_n is zero. ESPState *esp = sa->data; - data_n = roundup(data_n + ESP_PAD_N, esp->cipher.block_n); + data_n = roundupto(data_n + ESP_PAD_N, esp->cipher.block_n); if(esp->cipher.pad_n > 0){ - data_n = roundup(data_n, esp->cipher.pad_n); + data_n = roundupto(data_n, esp->cipher.pad_n); } data_n += esp->digest.icv_n; //data_n += esp->cipher.iv_n; @@ -607,7 +607,7 @@ static int esp_cipher_init(SAState *sa, err = -EINVAL; goto exit; } - esp->cipher.key_n = roundup(sa->cipher.bits, 8); + esp->cipher.key_n = roundupto(sa->cipher.bits, 8); // If cipher is null must use ECB because CBC algo does not support blocksize 1. if(strcmp(sa->cipher.name, "cipher_null")){ cipher_mode = CRYPTO_TFM_MODE_ECB; @@ -617,7 +617,7 @@ static int esp_cipher_init(SAState *sa, err = -ENOMEM; goto exit; } - esp->cipher.block_n = roundup(crypto_tfm_alg_blocksize(esp->cipher.tfm), 4); + esp->cipher.block_n = roundupto(crypto_tfm_alg_blocksize(esp->cipher.tfm), 4); esp->cipher.iv_n = crypto_tfm_alg_ivsize(esp->cipher.tfm); esp->cipher.pad_n = 0; if(esp->cipher.iv_n){ @@ -643,7 +643,7 @@ static int esp_digest_init(SAState *sa, dprintf(">\n"); esp->digest.key = sa->digest.key; - esp->digest.key_n = bits_to_bytes(roundup(sa->digest.bits, 8)); + esp->digest.key_n = bits_to_bytes(roundupto(sa->digest.bits, 8)); esp->digest.tfm = crypto_alloc_tfm(sa->digest.name, 0); if(!esp->digest.tfm){ err = -ENOMEM; diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/etherip.c --- a/tools/vnet/vnet-module/etherip.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/etherip.c Wed Oct 11 13:04:07 2006 -0400 @@ -128,9 +128,27 @@ static void etherip_tunnel_close(Tunnel } +static inline int skb_make_headroom(struct sk_buff **pskb, struct sk_buff *skb, int head_n){ + int err = 0; + dprintf("> skb=%p headroom=%d head_n=%d\n", skb, skb_headroom(skb), head_n); + if(head_n > skb_headroom(skb) || skb_cloned(skb) || skb_shared(skb)){ + // Expand header the way GRE does. + struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16); + if(!new_skb){ + err = -ENOMEM; + goto exit; + } + kfree_skb(skb); + *pskb = new_skb; + } else { + *pskb = skb; + } + exit: + return err; +} + /** Send a packet via an etherip tunnel. - * Adds etherip header, new ip header, new ethernet header around - * ethernet frame. + * Adds etherip header and new ip header around ethernet frame. * * @param tunnel tunnel * @param skb packet @@ -150,7 +168,7 @@ static int etherip_tunnel_send(Tunnel *t if(etherip_in_udp){ head_n += vnet_n + udp_n; } - err = skb_make_room(&skb, skb, head_n, 0); + err = skb_make_headroom(&skb, skb, head_n); if(err) goto exit; // Null the pointer as we are pushing a new IP header. @@ -219,6 +237,20 @@ int etherip_tunnel_create(VnetId *vnet, return Tunnel_create(etherip_tunnel_type, vnet, addr, base, tunnel); } +#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) +/** We need our own copy of this as it is no longer exported from the bridge module. + */ +static inline void _nf_bridge_save_header(struct sk_buff *skb){ + int header_size = 16; + + // Were using this modified to use h_proto instead of skb->protocol. + if(skb->protocol == htons(ETH_P_8021Q)){ + header_size = 18; + } + memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); +} +#endif + /** Do etherip receive processing. * Strips the etherip header to extract the ethernet frame, sets * the vnet from the header and re-receives the frame. @@ -320,10 +352,9 @@ int etherip_protocol_recv(struct sk_buff skb->dst = NULL; nf_reset(skb); #ifdef CONFIG_BRIDGE_NETFILTER - // Stop the eth header being clobbered by nf_bridge_maybe_copy_header(). - // Were using this modified to use h_proto instead of skb->protocol. if(skb->nf_bridge){ - nf_bridge_save_header(skb); + // Stop the eth header being clobbered by nf_bridge_maybe_copy_header(). + _nf_bridge_save_header(skb); } #endif #endif // __KERNEL__ diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/tunnel.c --- a/tools/vnet/vnet-module/tunnel.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/tunnel.c Wed Oct 11 13:04:07 2006 -0400 @@ -50,6 +50,12 @@ rwlock_t tunnel_table_lock = RW_LOCK_UNL #define tunnel_read_unlock(flags) read_unlock_irqrestore(&tunnel_table_lock, (flags)) #define tunnel_write_lock(flags) write_lock_irqsave(&tunnel_table_lock, (flags)) #define tunnel_write_unlock(flags) write_unlock_irqrestore(&tunnel_table_lock, (flags)) + +void Tunnel_free(Tunnel *tunnel){ + tunnel->type->close(tunnel); + Tunnel_decref(tunnel->base); + kfree(tunnel); +} void Tunnel_print(Tunnel *tunnel){ if(tunnel){ @@ -136,6 +142,7 @@ int Tunnel_init(void){ goto exit; } tunnel_table->entry_free_fn = tunnel_table_entry_free_fn; + tunnel_table->key_size = sizeof(TunnelKey); tunnel_table->key_hash_fn = tunnel_table_key_hash_fn; tunnel_table->key_equal_fn = tunnel_table_key_equal_fn; exit: diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/tunnel.h --- a/tools/vnet/vnet-module/tunnel.h Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/tunnel.h Wed Oct 11 13:04:07 2006 -0400 @@ -70,6 +70,8 @@ typedef struct Tunnel { struct Tunnel *base; } Tunnel; +extern void Tunnel_free(struct Tunnel *tunnel); + /** Decrement the reference count, freeing if zero. * * @param tunnel tunnel (may be null) @@ -77,9 +79,7 @@ static inline void Tunnel_decref(struct static inline void Tunnel_decref(struct Tunnel *tunnel){ if(!tunnel) return; if(atomic_dec_and_test(&tunnel->refcount)){ - tunnel->type->close(tunnel); - Tunnel_decref(tunnel->base); - kfree(tunnel); + Tunnel_free(tunnel); } } @@ -87,7 +87,7 @@ static inline void Tunnel_decref(struct * * @param tunnel tunnel (may be null) */ -static inline void Tunnel_incref(Tunnel *tunnel){ +static inline void Tunnel_incref(struct Tunnel *tunnel){ if(!tunnel) return; atomic_inc(&tunnel->refcount); } diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/varp.c --- a/tools/vnet/vnet-module/varp.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/varp.c Wed Oct 11 13:04:07 2006 -0400 @@ -849,6 +849,7 @@ VarpTable * VarpTable_new(void){ if(!vtable) goto exit; vtable->table = HashTable_new(VARP_TABLE_BUCKETS); if(!vtable->table) goto exit; + vtable->table->key_size = sizeof(VarpKey); vtable->table->key_equal_fn = varp_key_equal_fn; vtable->table->key_hash_fn = varp_key_hash_fn; vtable->table->entry_free_fn = varp_entry_free_fn; @@ -1529,8 +1530,12 @@ void varp_exit(void){ dprintf("<\n"); } +#ifdef MODULE_PARM MODULE_PARM(varp_mcaddr, "s"); +MODULE_PARM(varp_device, "s"); +#else +module_param(varp_mcaddr, charp, 0644); +module_param(varp_device, charp, 0644); +#endif MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address"); - -MODULE_PARM(varp_device, "s"); MODULE_PARM_DESC(varp_device, "VARP network device"); diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/varp_socket.c --- a/tools/vnet/vnet-module/varp_socket.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/varp_socket.c Wed Oct 11 13:04:07 2006 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> + * Copyright (C) 2004, 2005, 2006 Mike Wray <mike.wray@xxxxxx> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by the @@ -36,7 +36,7 @@ /* Get macros needed to define system calls as functions in the kernel. */ #define __KERNEL_SYSCALLS__ -static int errno; +int errno=0; #include <linux/unistd.h> #define MODULE_NAME "VARP" @@ -73,7 +73,13 @@ static inline _syscall3(int, fcntl, /* Replicate the user-space socket API. * The parts we need anyway. - */ + * + * Some architectures use socketcall() to multiplex the socket-related calls, + * but others define individual syscalls instead. + * Architectures using socketcall() define __ARCH_WANT_SYS_SOCKETCALL. + */ + +#ifdef __ARCH_WANT_SYS_SOCKETCALL /* Define the socketcall() syscall. * Multiplexes all the socket-related calls. @@ -179,6 +185,66 @@ int getsockname(int fd, struct sockaddr args[2] = (unsigned long)usockaddr_len; return socketcall(SYS_GETSOCKNAME, args); } + +#else /* !__ARCH_WANT_SYS_SOCKETCALL */ + +/* No socketcall - define the individual syscalls. */ + +static inline _syscall3(int, socket, + int, family, + int, type, + int, protocol); + +static inline _syscall3(int, bind, + int, fd, + struct sockaddr *, umyaddr, + int, addrlen); + +static inline _syscall3(int, connect, + int, fd, + struct sockaddr *, uservaddr, + int, addrlen); + +static inline _syscall6(int, sendto, + int, fd, + void *, buff, + size_t, len, + unsigned, flags, + struct sockaddr *, addr, + int, addr_len); + +static inline _syscall6(int, recvfrom, + int, fd, + void *, ubuf, + size_t, size, + unsigned, flags, + struct sockaddr *, addr, + int *, addr_len); + +static inline _syscall5(int, setsockopt, + int, fd, + int, level, + int, optname, + void *, optval, + int, optlen); + +static inline _syscall5(int, getsockopt, + int, fd, + int, level, + int, optname, + void *, optval, + int *, optlen); + +static inline _syscall2(int, shutdown, + int, fd, + int, how); + +static inline _syscall3(int, getsockname, + int, fd, + struct sockaddr *, usockaddr, + int *, usockaddr_len); + +#endif /* __ARCH_WANT_SYS_SOCKETCALL */ /*============================================================================*/ /** Socket flags. */ @@ -418,9 +484,7 @@ int varp_ucast_open(uint32_t addr, u16 p * an error. */ static int handle_varp_skb(struct sk_buff *skb){ - static int count = 0; - int err = 0; - count++; + int err = 0; switch(skb->pkt_type){ case PACKET_BROADCAST: case PACKET_MULTICAST: diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vif.c --- a/tools/vnet/vnet-module/vif.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/vif.c Wed Oct 11 13:04:07 2006 -0400 @@ -366,6 +366,7 @@ int vif_init(void){ goto exit; } vif_table->entry_free_fn = vif_entry_free_fn; + vif_table->key_size = sizeof(VifKey); vif_table->key_hash_fn = vif_key_hash_fn; vif_table->key_equal_fn = vif_key_equal_fn; diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet.c --- a/tools/vnet/vnet-module/vnet.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/vnet.c Wed Oct 11 13:04:07 2006 -0400 @@ -318,6 +318,7 @@ int vnet_table_init(void){ err = -ENOMEM; goto exit; } + vnet_table->key_size = sizeof(VnetId); vnet_table->key_equal_fn = vnet_key_equal_fn; vnet_table->key_hash_fn = vnet_key_hash_fn; vnet_table->entry_free_fn = vnet_entry_free_fn; @@ -431,14 +432,14 @@ inline int _skb_xmit(struct sk_buff *skb ip_send_check(skb->nh.iph); - if(1){ +#if 1 // Output to skb destination. Will use ip_output(), which fragments. // Slightly slower than neigh_compat_output() (marginal - 1%). err = dst_output(skb); - } else { +#else // Sends direct to device via dev_queue_xmit(). No fragmentation? err = neigh_compat_output(skb); - } +#endif #if 0 if(needs_frags){ @@ -447,6 +448,7 @@ inline int _skb_xmit(struct sk_buff *skb err = ip_finish_output(skb); } #endif + exit: dprintf("< err=%d\n", err); return err; @@ -691,7 +693,12 @@ module_exit(vnet_module_exit); module_exit(vnet_module_exit); MODULE_LICENSE("GPL"); +#ifdef MODULE_PARM MODULE_PARM(vnet_encaps, "s"); +#else +module_param(vnet_encaps, charp, 0644); +#endif + MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp."); #endif diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_dev.c --- a/tools/vnet/vnet-module/vnet_dev.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/vnet_dev.c Wed Oct 11 13:04:07 2006 -0400 @@ -49,8 +49,12 @@ #undef DEBUG #include "debug.h" -#ifndef CONFIG_BRIDGE -#warning Should configure ethernet bridging in kernel Network Options +#if !defined(CONFIG_BRIDGE) && !defined(CONFIG_BRIDGE_MODULE) +#warning Should configure Ethernet Bridging in kernel Network Options +#endif + +#ifndef CONFIG_BRIDGE_NETFILTER +#warning Should configure CONFIG_BRIDGE_NETFILTER in kernel #endif static void vnet_dev_destructor(struct net_device *dev){ @@ -254,7 +258,7 @@ static int vnet_dev_setup(Vnet *vnet, st return err; } -static inline int roundup(int n, int k){ +static inline int roundupto(int n, int k){ return k * ((n + k - 1) / k); } @@ -275,7 +279,7 @@ int vnet_dev_add(Vnet *vnet){ vnet->header_n += sizeof(struct VnetMsgHdr); vnet->header_n += sizeof(struct udphdr); } - vnet->header_n = roundup(vnet->header_n, 4); + vnet->header_n = roundupto(vnet->header_n, 4); dev = alloc_netdev(0, vnet->device, vnet_dev_init); if(!dev){ err = -ENOMEM; diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_eval.c --- a/tools/vnet/vnet-module/vnet_eval.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/vnet_eval.c Wed Oct 11 13:04:07 2006 -0400 @@ -188,7 +188,7 @@ int eval_vnet_add(Sxpr exp, IOStream *ou if(err) goto exit; child_string(exp, ovnetif, &device); if(!device){ - snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[7])); + snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1])); device = dev; } csecurity = sxpr_child_value(exp, osecurity, intern("none")); diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_forward.c --- a/tools/vnet/vnet-module/vnet_forward.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnet-module/vnet_forward.c Wed Oct 11 13:04:07 2006 -0400 @@ -370,6 +370,7 @@ int vnet_forward_init(void){ err = -ENOMEM; goto exit; } + vnet_peer_table->key_size = sizeof(struct VarpAddr); vnet_peer_table->key_equal_fn = peer_key_equal_fn; vnet_peer_table->key_hash_fn = peer_key_hash_fn; vnet_peer_table->entry_free_fn = peer_entry_free_fn; diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnetd/Makefile --- a/tools/vnet/vnetd/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnetd/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -24,7 +24,8 @@ all: vnetd #---------------------------------------------------------------------------- -include $(XEN_ROOT)/tools/Rules.mk +# Comment out when outside xen. +#include $(XEN_ROOT)/tools/Rules.mk VNETD_INSTALL_DIR = /usr/sbin @@ -43,6 +44,7 @@ CPPFLAGS += -D __ARCH_I386_ATOMIC__ CPPFLAGS += -D __ARCH_I386_ATOMIC__ #---------------------------------------------------------------------------- +CFLAGS += -O3 CFLAGS += $(INCLUDES) $(LIBS) LDFLAGS += $(LIBS) diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnetd/vnetd.c --- a/tools/vnet/vnetd/vnetd.c Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/vnet/vnetd/vnetd.c Wed Oct 11 13:04:07 2006 -0400 @@ -196,7 +196,7 @@ int vnet_dev_add(struct Vnet *vnet){ if(err){ wprintf("> Unable to open tap device.\n" "The tun module must be loaded and\n" - "the vnet kernel module must not be loaded."); + "the vnet kernel module must not be loaded.\n"); deallocate(dev); goto exit; } @@ -764,7 +764,7 @@ static int vnetd_getopts(Vnetd *vnetd, i * * @param vnetd vnetd */ -int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){ +static int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){ int err = 0; // Use etherip-in-udp encapsulation. @@ -791,7 +791,7 @@ int vnetd_init(Vnetd *vnetd, int argc, c return err; } -void vnet_select(Vnetd *vnetd, SelectSet *set){ +static void vnet_select(Vnetd *vnetd, SelectSet *set){ HashTable_for_decl(entry); HashTable_for_each(entry, vnetd->vnet_table){ @@ -803,7 +803,7 @@ void vnet_select(Vnetd *vnetd, SelectSet } } -void vnet_handle(Vnetd *vnetd, SelectSet *set){ +static void vnet_handle(Vnetd *vnetd, SelectSet *set){ HashTable_for_decl(entry); HashTable_for_each(entry, vnetd->vnet_table){ @@ -820,7 +820,7 @@ void vnet_handle(Vnetd *vnetd, SelectSet } } -int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ +static int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ int err = 0, n = 0; struct sockaddr_in peer, dest; socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest); @@ -851,7 +851,7 @@ int vnetd_handle_udp(Vnetd *vnetd, struc return err; } -int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ +static int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ int err = 0, n = 0; struct sockaddr_in peer, dest; socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest); @@ -883,7 +883,7 @@ typedef struct ConnClient { Parser *parser; } ConnClient; -int conn_handle_fn(Conn *conn, int mode){ +static int conn_handle_fn(Conn *conn, int mode){ int err; ConnClient *client = conn->data; char data[1024] = {}; @@ -923,12 +923,12 @@ int conn_handle_fn(Conn *conn, int mode) return (err < 0 ? err : 0); } -int vnetd_handle_unix(Vnetd *vnetd, int sock){ +static int vnetd_handle_unix(Vnetd *vnetd, int sock){ int err; ConnClient *client = NULL; Conn *conn = NULL; struct sockaddr_un peer = {}; - int peer_n = sizeof(peer); + socklen_t peer_n = sizeof(peer); int peersock; peersock = accept(sock, (struct sockaddr *)&peer, &peer_n); @@ -956,7 +956,7 @@ int vnetd_handle_unix(Vnetd *vnetd, int return err; } -void vnetd_select(Vnetd *vnetd, SelectSet *set){ +static void vnetd_select(Vnetd *vnetd, SelectSet *set){ SelectSet_add(set, vnetd->unix_sock, SELECT_READ); SelectSet_add(set, vnetd->udp_sock, SELECT_READ); SelectSet_add(set, vnetd->mcast_sock, SELECT_READ); @@ -967,7 +967,7 @@ void vnetd_select(Vnetd *vnetd, SelectSe ConnList_select(vnetd->conns, set); } -void vnetd_handle(Vnetd *vnetd, SelectSet *set){ +static void vnetd_handle(Vnetd *vnetd, SelectSet *set){ if(SelectSet_in_read(set, vnetd->unix_sock)){ vnetd_handle_unix(vnetd, vnetd->unix_sock); } @@ -995,7 +995,7 @@ void vnetd_handle(Vnetd *vnetd, SelectSe */ static unsigned timer_alarms = 0; -int vnetd_main(Vnetd *vnetd){ +static int vnetd_main(Vnetd *vnetd){ int err = 0; SelectSet _set = {}, *set = &_set; struct timeval _timeout = {}, *timeout = &_timeout; @@ -1030,12 +1030,12 @@ int vnetd_main(Vnetd *vnetd){ return err; } -int getsockaddr(int sock, struct sockaddr_in *addr){ +static int getsockaddr(int sock, struct sockaddr_in *addr){ socklen_t addr_n = sizeof(struct sockaddr_in); return getsockname(sock, (struct sockaddr*)addr, &addr_n); } -int vnetd_etherip_sock(Vnetd *vnetd){ +static int vnetd_etherip_sock(Vnetd *vnetd){ int err = 0; if(!vnetd->etherip) goto exit; @@ -1051,7 +1051,7 @@ int vnetd_etherip_sock(Vnetd *vnetd){ return err; } -int vnetd_udp_sock(Vnetd *vnetd){ +static int vnetd_udp_sock(Vnetd *vnetd){ int err; uint32_t mcaddr = vnetd_mcast_addr(vnetd); @@ -1087,7 +1087,7 @@ int vnetd_udp_sock(Vnetd *vnetd){ return err; } -int vnetd_raw_sock(Vnetd *vnetd){ +static int vnetd_raw_sock(Vnetd *vnetd){ int err; err = vnetd_raw_socket(vnetd, IPPROTO_RAW, @@ -1101,7 +1101,7 @@ int vnetd_raw_sock(Vnetd *vnetd){ return err; } -int vnetd_unix_sock(Vnetd *vnetd){ +static int vnetd_unix_sock(Vnetd *vnetd){ int err = 0; struct sockaddr_un addr = { .sun_family = AF_UNIX }; socklen_t addr_n; diff -r e7cb3aefc233 -r b53c343b47ae tools/xm-test/tests/vtpm/vtpm_utils.py --- a/tools/xm-test/tests/vtpm/vtpm_utils.py Wed Oct 11 13:01:31 2006 -0400 +++ b/tools/xm-test/tests/vtpm/vtpm_utils.py Wed Oct 11 13:04:07 2006 -0400 @@ -8,12 +8,10 @@ if ENABLE_HVM_SUPPORT: if ENABLE_HVM_SUPPORT: SKIP("vtpm tests not supported for HVM domains") -if not os.path.exists("/dev/tpm0"): - SKIP("This machine has no hardware TPM; cannot run this test") - status, output = traceCommand("ps aux | grep vtpm_manager | grep -v grep") if output == "": - FAIL("virtual TPM manager must be started to run this test") + SKIP("virtual TPM manager must be started to run this test; might " + "need /dev/tpm0") def vtpm_cleanup(domName): traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName) diff -r e7cb3aefc233 -r b53c343b47ae unmodified_drivers/linux-2.6/platform-pci/platform-pci.c --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 11 13:01:31 2006 -0400 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 11 13:04:07 2006 -0400 @@ -231,11 +231,13 @@ static int __devinit platform_pci_init(s return ret; } -#define XEN_PLATFORM_VENDOR_ID 0xfffd -#define XEN_PLATFORM_DEVICE_ID 0x0101 +#define XEN_PLATFORM_VENDOR_ID 0x5853 +#define XEN_PLATFORM_DEVICE_ID 0x0001 static struct pci_device_id platform_pci_tbl[] __devinitdata = { {XEN_PLATFORM_VENDOR_ID, XEN_PLATFORM_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + /* Continue to recognise the old ID for now */ + {0xfffd, 0x0101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} }; diff -r e7cb3aefc233 -r b53c343b47ae xen/Makefile --- a/xen/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -123,19 +123,29 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h SUBDIRS = acm arch/$(TARGET_ARCH) common drivers define all_sources - ( find include/asm-$(TARGET_ARCH) -name SCCS -prune -o -name '*.h' -print; \ - find include -type d -name SCCS -prune -o \( -name "asm-*" -o \ - -name config \) -prune -o -name '*.h' -print; \ - find $(SUBDIRS) -name SCCS -prune -o -name '*.[chS]' -print ) + ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \ + find include -name 'asm-*' -prune -o -name '*.h' -print; \ + find $(SUBDIRS) -name '*.[chS]' -print ) +endef + +define set_exuberant_flags + exuberant_flags=`$1 --version 2>/dev/null | grep -iq exuberant && \ + echo "-I __initdata,__exitdata,__acquires,__releases \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ + --extra=+f --c-kinds=+px"` endef .PHONY: _TAGS _TAGS: - rm -f TAGS && $(all_sources) | xargs etags -a + rm -f TAGS; \ + $(call set_exuberant_flags,etags); \ + $(all_sources) | xargs etags $$exuberant_flags -a .PHONY: _tags _tags: - rm -f TAGS && $(all_sources) | xargs ctags -a + rm -f tags; \ + $(call set_exuberant_flags,ctags); \ + $(all_sources) | xargs ctags $$exuberant_flags -a .PHONY: _cscope _cscope: diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/Makefile --- a/xen/arch/ia64/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/ia64/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -4,22 +4,27 @@ subdir-y += linux-xen subdir-y += linux-xen $(TARGET)-syms: linux-xen/head.o $(ALL_OBJS) xen.lds.s + $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o $(LD) $(LDFLAGS) -T xen.lds.s -N \ - -Map map.out linux-xen/head.o $(ALL_OBJS) -o $@ + -Map map.out linux-xen/head.o $(ALL_OBJS) \ + $(BASEDIR)/common/symbols-dummy.o -o $@ $(NM) -n $@ | $(BASEDIR)/tools/symbols > $(BASEDIR)/xen-syms.S $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o $(LD) $(LDFLAGS) -T xen.lds.s -N \ - -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ + -Map map.out linux-xen/head.o $(ALL_OBJS) \ + $(BASEDIR)/xen-syms.o -o $@ $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o $(LD) $(LDFLAGS) -T xen.lds.s -N \ - -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ + -Map map.out linux-xen/head.o $(ALL_OBJS) \ + $(BASEDIR)/xen-syms.o -o $@ rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o $(TARGET): $(TARGET)-syms $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $@ - $(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)'\ - > $(BASEDIR)/System.map + $(NM) -n $(TARGET)-syms | \ + grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' \ + > $(BASEDIR)/System.map # Headers do not depend on auto-generated header, but object files do. HDRS := $(subst $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h,,$(HDRS)) diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/ia64/xen/domain.c Wed Oct 11 13:04:07 2006 -0400 @@ -54,7 +54,6 @@ static unsigned int dom0_max_vcpus = 1; static unsigned int dom0_max_vcpus = 1; integer_param("dom0_max_vcpus", dom0_max_vcpus); -extern int opt_dom0_vcpus_pin; extern unsigned long running_on_sim; extern char dom0_command_line[]; @@ -1021,12 +1020,9 @@ int construct_dom0(struct domain *d, dom0_max_vcpus = MAX_VIRT_CPUS; printf ("Dom0 max_vcpus=%d\n", dom0_max_vcpus); - for ( i = 1; i < dom0_max_vcpus; i++ ) { + for ( i = 1; i < dom0_max_vcpus; i++ ) if (alloc_vcpu(d, i, i) == NULL) printf ("Cannot allocate dom0 vcpu %d\n", i); - else if (opt_dom0_vcpus_pin) - d->vcpu[i]->cpu_affinity = cpumask_of_cpu(i); - } /* Copy the OS image. */ loaddomainelfimage(d,image_start); diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/ia64/xen/xensetup.c Wed Oct 11 13:04:07 2006 -0400 @@ -18,6 +18,7 @@ #include <xen/domain.h> #include <xen/serial.h> #include <xen/trace.h> +#include <xen/keyhandler.h> #include <asm/meminit.h> #include <asm/page.h> #include <asm/setup.h> @@ -38,7 +39,6 @@ int find_max_pfn (unsigned long, unsigne int find_max_pfn (unsigned long, unsigned long, void *); /* FIXME: which header these declarations should be there ? */ -extern void initialize_keytable(void); extern long is_platform_hp_ski(void); extern void early_setup_arch(char **); extern void late_setup_arch(char **); @@ -48,10 +48,6 @@ extern void mem_init(void); extern void mem_init(void); extern void init_IRQ(void); extern void trap_init(void); - -/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */ -unsigned int opt_dom0_vcpus_pin = 0; -boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin); /* opt_nosmp: If true, secondary processors are ignored. */ static int opt_nosmp = 0; @@ -521,10 +517,6 @@ printk("num_online_cpus=%d, max_cpus=%d\ 0) != 0) panic("Could not set up DOM0 guest OS\n"); - /* PIN domain0 VCPU 0 on CPU 0. */ - if (opt_dom0_vcpus_pin) - dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0); - if (!running_on_sim) // slow on ski and pages are pre-initialized to zero scrub_heap_pages(); diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/powerpc/Makefile --- a/xen/arch/powerpc/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/powerpc/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -100,7 +100,8 @@ TARGET_OPTS += start.o $(ALL_OBJS) TARGET_OPTS += start.o $(ALL_OBJS) .xen-syms: start.o $(ALL_OBJS) xen.lds - $(CC) $(CFLAGS) $(TARGET_OPTS) -o $@ + $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o + $(CC) $(CFLAGS) $(TARGET_OPTS) $(BASEDIR)/common/symbols-dummy.o -o $@ NM=$(CROSS_COMPILE)nm new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/powerpc/setup.c Wed Oct 11 13:04:07 2006 -0400 @@ -88,9 +88,6 @@ struct ns16550_defaults ns16550; extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[]; -/* move us to a header file */ -extern void initialize_keytable(void); - volatile struct processor_area * volatile global_cpu_table[NR_CPUS]; int is_kernel_text(unsigned long addr) diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/x86/Makefile --- a/xen/arch/x86/Makefile Wed Oct 11 13:01:31 2006 -0400 +++ b/xen/arch/x86/Makefile Wed Oct 11 13:04:07 2006 -0400 @@ -46,20 +46,25 @@ obj-$(crash_debug) += gdbstub.o $(TARGET): $(TARGET)-syms boot/mkelf32 ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \ - `$(NM) $(TARGET)-syms | sort | tail -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'` _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |