[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID 432f978d1cd1351c5da6b5b15ff516ec9c07fa3c # Parent da942e577e5e965275644909d91d4a26528c9dba # Parent c4f3f719d997522ae82e065d4f93d5af6494a750 merge with xen-unstable.hg --- patches/linux-2.6.16.13/blktap-aio-16_03_06.patch | 274 - patches/linux-2.6.16.13/device_bind.patch | 14 patches/linux-2.6.16.13/fix-hz-suspend.patch | 25 patches/linux-2.6.16.13/fix-ide-cd-pio-mode.patch | 13 patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch | 35 patches/linux-2.6.16.13/ipv6-no-autoconf.patch | 22 patches/linux-2.6.16.13/net-csum.patch | 57 patches/linux-2.6.16.13/net-gso-0-base.patch | 2510 ---------- patches/linux-2.6.16.13/net-gso-1-check-dodgy.patch | 22 patches/linux-2.6.16.13/net-gso-2-checksum-fix.patch | 400 - patches/linux-2.6.16.13/net-gso-3-fix-errorcheck.patch | 13 patches/linux-2.6.16.13/net-gso-4-kill-warnon.patch | 18 patches/linux-2.6.16.13/pmd-shared.patch | 100 patches/linux-2.6.16.13/rcu_needs_cpu.patch | 31 patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 26 patches/linux-2.6.16.13/series | 23 patches/linux-2.6.16.13/smp-alts.patch | 540 -- patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch | 1381 ----- patches/linux-2.6.16.13/x86-elfnote-as-preprocessor-macro.patch | 28 patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch | 73 patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch | 168 patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch | 71 patches/linux-2.6.16.13/xen-hotplug.patch | 9 patches/linux-2.6.16.13/xenoprof-generic.patch | 568 -- tools/python/xen/xm/sysrq.py | 31 xen/arch/powerpc/dom0_ops.c | 138 .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 buildconfigs/mk.linux-2.6-xen | 2 extras/mini-os/arch/x86/setup.c | 108 extras/mini-os/events.c | 33 extras/mini-os/include/events.h | 7 extras/mini-os/include/x86/os.h | 5 extras/mini-os/include/x86/x86_32/hypercall-x86_32.h | 6 extras/mini-os/kernel.c | 67 linux-2.6-xen-sparse/arch/i386/Kconfig | 3 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 46 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 91 linux-2.6-xen-sparse/arch/ia64/Kconfig | 3 linux-2.6-xen-sparse/arch/ia64/dig/setup.c | 23 linux-2.6-xen-sparse/arch/x86_64/Kconfig | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S | 7 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 49 linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c | 5 linux-2.6-xen-sparse/drivers/char/tty_io.c | 14 linux-2.6-xen-sparse/drivers/serial/Kconfig | 1 linux-2.6-xen-sparse/drivers/xen/console/console.c | 36 linux-2.6-xen-sparse/include/xen/xencons.h | 3 linux-2.6-xen-sparse/mm/Kconfig | 2 linux-2.6-xen-sparse/mm/page_alloc.c | 3 patches/linux-2.6.16.29/blktap-aio-16_03_06.patch | 161 patches/linux-2.6.16.29/device_bind.patch | 9 patches/linux-2.6.16.29/fix-hz-suspend.patch | 9 patches/linux-2.6.16.29/fix-ide-cd-pio-mode.patch | 13 patches/linux-2.6.16.29/i386-mach-io-check-nmi.patch | 30 patches/linux-2.6.16.29/ipv6-no-autoconf.patch | 16 patches/linux-2.6.16.29/net-csum.patch | 40 patches/linux-2.6.16.29/net-gso-0-base.patch | 1906 +++++++ patches/linux-2.6.16.29/net-gso-1-check-dodgy.patch | 16 patches/linux-2.6.16.29/net-gso-2-checksum-fix.patch | 311 + patches/linux-2.6.16.29/net-gso-3-fix-errorcheck.patch | 13 patches/linux-2.6.16.29/net-gso-4-kill-warnon.patch | 26 patches/linux-2.6.16.29/pci-mmconfig-fix-from-2.6.17.patch | 143 patches/linux-2.6.16.29/pmd-shared.patch | 57 patches/linux-2.6.16.29/rcu_needs_cpu.patch | 18 patches/linux-2.6.16.29/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 26 patches/linux-2.6.16.29/series | 24 patches/linux-2.6.16.29/smp-alts.patch | 330 + patches/linux-2.6.16.29/tpm_plugin_2.6.17.patch | 703 ++ patches/linux-2.6.16.29/x86-elfnote-as-preprocessor-macro.patch | 25 patches/linux-2.6.16.29/x86-increase-interrupt-vector-range.patch | 73 patches/linux-2.6.16.29/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch | 39 patches/linux-2.6.16.29/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch | 63 patches/linux-2.6.16.29/xen-hotplug.patch | 10 patches/linux-2.6.16.29/xenoprof-generic.patch | 268 + tools/check/check_python | 2 tools/console/daemon/io.c | 10 tools/debugger/gdb/gdbbuild | 2 tools/examples/locking.sh | 2 tools/firmware/vmxassist/machine.h | 1 tools/firmware/vmxassist/vm86.c | 87 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/target-i386-dm/helper2.c | 4 tools/ioemu/usb-linux.c | 1 tools/ioemu/vl.c | 6 tools/ioemu/vl.h | 1 tools/ioemu/vnc.c | 256 - tools/libxc/powerpc64/Makefile | 3 tools/libxc/powerpc64/flatdevtree.c | 636 ++ tools/libxc/powerpc64/flatdevtree.h | 106 tools/libxc/powerpc64/flatdevtree_env.h | 94 tools/libxc/powerpc64/xc_linux_build.c | 200 tools/libxc/powerpc64/xc_memory.c | 42 tools/libxc/xc_ptrace.c | 11 tools/pygrub/Makefile | 2 tools/pygrub/src/fsys/ext2/__init__.py | 2 tools/pygrub/src/fsys/reiser/__init__.py | 1 tools/python/xen/util/blkif.py | 4 tools/python/xen/xend/XendBootloader.py | 3 tools/python/xen/xend/XendDomain.py | 28 tools/python/xen/xend/XendDomainInfo.py | 50 tools/python/xen/xend/image.py | 4 tools/python/xen/xend/server/DevController.py | 2 tools/python/xen/xend/server/blkif.py | 6 tools/python/xen/xend/server/tpmif.py | 2 tools/python/xen/xm/addlabel.py | 37 tools/python/xen/xm/cfgbootpolicy.py | 25 tools/python/xen/xm/console.py | 2 tools/python/xen/xm/create.py | 81 tools/python/xen/xm/dry-run.py | 19 tools/python/xen/xm/dumppolicy.py | 11 tools/python/xen/xm/getlabel.py | 36 tools/python/xen/xm/labels.py | 77 tools/python/xen/xm/loadpolicy.py | 19 tools/python/xen/xm/main.py | 707 +- tools/python/xen/xm/makepolicy.py | 10 tools/python/xen/xm/migrate.py | 16 tools/python/xen/xm/opts.py | 92 tools/python/xen/xm/resources.py | 25 tools/python/xen/xm/rmlabel.py | 32 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/xenmon/xenmon.py | 5 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py | 2 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py | 2 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py | 2 unmodified_drivers/linux-2.6/mkbuildtree | 6 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 11 xen/Makefile | 27 xen/arch/ia64/xen/mm.c | 95 xen/arch/ia64/xen/xensetup.c | 1 xen/arch/powerpc/0opt.c | 4 xen/arch/powerpc/Makefile | 4 xen/arch/powerpc/backtrace.c | 17 xen/arch/powerpc/boot_of.c | 192 xen/arch/powerpc/dart.c | 23 xen/arch/powerpc/domain.c | 87 xen/arch/powerpc/domctl.c | 118 xen/arch/powerpc/elf32.c | 2 xen/arch/powerpc/exceptions.c | 45 xen/arch/powerpc/exceptions.h | 1 xen/arch/powerpc/external.c | 9 xen/arch/powerpc/hcalls.c | 3 xen/arch/powerpc/iommu.c | 2 xen/arch/powerpc/mm.c | 263 - xen/arch/powerpc/mpic_init.c | 61 xen/arch/powerpc/of-devtree.h | 17 xen/arch/powerpc/of_handler/xencomm.c | 10 xen/arch/powerpc/ofd_fixup.c | 31 xen/arch/powerpc/oftree.h | 2 xen/arch/powerpc/papr/xlate.c | 79 xen/arch/powerpc/powerpc64/Makefile | 3 xen/arch/powerpc/powerpc64/domain.c | 55 xen/arch/powerpc/powerpc64/exceptions.S | 67 xen/arch/powerpc/powerpc64/io.S | 26 xen/arch/powerpc/powerpc64/ppc970.c | 212 xen/arch/powerpc/powerpc64/ppc970_machinecheck.c | 120 xen/arch/powerpc/powerpc64/ppc970_scom.c | 117 xen/arch/powerpc/setup.c | 50 xen/arch/powerpc/shadow.c | 5 xen/arch/powerpc/smp-tbsync.c | 186 xen/arch/powerpc/sysctl.c | 65 xen/arch/powerpc/time.c | 36 xen/arch/powerpc/usercopy.c | 53 xen/arch/x86/Rules.mk | 3 xen/arch/x86/acpi/boot.c | 81 xen/arch/x86/apic.c | 95 xen/arch/x86/boot/x86_64.S | 49 xen/arch/x86/domain_build.c | 17 xen/arch/x86/domctl.c | 58 xen/arch/x86/flushtlb.c | 101 xen/arch/x86/hvm/hvm.c | 1 xen/arch/x86/hvm/i8259.c | 46 xen/arch/x86/hvm/platform.c | 10 xen/arch/x86/hvm/svm/svm.c | 189 xen/arch/x86/hvm/vioapic.c | 32 xen/arch/x86/hvm/vlapic.c | 39 xen/arch/x86/hvm/vmx/io.c | 8 xen/arch/x86/hvm/vmx/vmx.c | 139 xen/arch/x86/io_apic.c | 8 xen/arch/x86/mm.c | 361 - xen/arch/x86/mm/shadow/common.c | 30 xen/arch/x86/mm/shadow/multi.c | 16 xen/arch/x86/mpparse.c | 61 xen/arch/x86/oprofile/nmi_int.c | 25 xen/arch/x86/oprofile/xenoprof.c | 103 xen/arch/x86/setup.c | 3 xen/arch/x86/smpboot.c | 2 xen/arch/x86/traps.c | 44 xen/arch/x86/x86_32/entry.S | 2 xen/arch/x86/x86_64/entry.S | 2 xen/arch/x86/x86_64/mm.c | 20 xen/arch/x86/x86_64/traps.c | 6 xen/common/domctl.c | 43 xen/common/gdbstub.c | 52 xen/common/sched_credit.c | 99 xen/common/sched_sedf.c | 15 xen/common/schedule.c | 50 xen/drivers/acpi/tables.c | 473 - xen/drivers/char/console.c | 36 xen/drivers/video/vga.c | 11 xen/include/asm-ia64/mm.h | 8 xen/include/asm-powerpc/cache.h | 11 xen/include/asm-powerpc/config.h | 3 xen/include/asm-powerpc/current.h | 2 xen/include/asm-powerpc/debugger.h | 19 xen/include/asm-powerpc/domain.h | 5 xen/include/asm-powerpc/flushtlb.h | 3 xen/include/asm-powerpc/guest_access.h | 2 xen/include/asm-powerpc/io.h | 2 xen/include/asm-powerpc/mm.h | 29 xen/include/asm-powerpc/page.h | 19 xen/include/asm-powerpc/percpu.h | 16 xen/include/asm-powerpc/powerpc64/ppc970-hid.h | 105 xen/include/asm-powerpc/powerpc64/procarea.h | 1 xen/include/asm-powerpc/powerpc64/processor.h | 35 xen/include/asm-powerpc/processor.h | 19 xen/include/asm-powerpc/reg_defs.h | 5 xen/include/asm-powerpc/shadow.h | 13 xen/include/asm-powerpc/smp.h | 8 xen/include/asm-powerpc/system.h | 4 xen/include/asm-powerpc/time.h | 45 xen/include/asm-x86/apicdef.h | 1 xen/include/asm-x86/flushtlb.h | 7 xen/include/asm-x86/hvm/hvm.h | 7 xen/include/asm-x86/hvm/svm/emulate.h | 32 xen/include/asm-x86/hvm/vlapic.h | 30 xen/include/asm-x86/hvm/vmx/vmcs.h | 3 xen/include/asm-x86/hvm/vmx/vmx.h | 44 xen/include/asm-x86/io_apic.h | 1 xen/include/asm-x86/mm.h | 72 xen/include/asm-x86/shadow.h | 14 xen/include/asm-x86/x86_32/page-3level.h | 2 xen/include/asm-x86/x86_64/page.h | 15 xen/include/public/xen.h | 50 xen/include/public/xenoprof.h | 15 xen/include/xen/compiler.h | 5 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 | 17 xen/tools/figlet/figlet.c | 5 283 files changed, 10510 insertions(+), 9668 deletions(-) diff -r da942e577e5e -r 432f978d1cd1 .hgignore --- a/.hgignore Thu Sep 21 15:35:45 2006 -0600 +++ b/.hgignore Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen0_ia64 --- a/buildconfigs/linux-defconfig_xen0_ia64 Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xenU_ia64 --- a/buildconfigs/linux-defconfig_xenU_ia64 Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/linux-defconfig_xenU_ia64 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_ia64 --- a/buildconfigs/linux-defconfig_xen_ia64 Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_ia64 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_x86_32 --- a/buildconfigs/linux-defconfig_xen_x86_32 Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_x86_64 --- a/buildconfigs/linux-defconfig_xen_x86_64 Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/mk.linux-2.6-xen --- a/buildconfigs/mk.linux-2.6-xen Thu Sep 21 15:35:45 2006 -0600 +++ b/buildconfigs/mk.linux-2.6-xen Sun Sep 24 13:10:13 2006 -0600 @@ -1,5 +1,5 @@ LINUX_SERIES = 2.6 LINUX_SERIES = 2.6 -LINUX_VER = 2.6.16.13 +LINUX_VER = 2.6.16.29 EXTRAVERSION ?= xen diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/events.c --- a/extras/mini-os/events.c Thu Sep 21 15:35:45 2006 -0600 +++ b/extras/mini-os/events.c Sun Sep 24 13:10:13 2006 -0600 @@ -88,19 +88,18 @@ void unbind_evtchn(evtchn_port_t port ) int bind_virq(uint32_t virq, evtchn_handler_t handler, void *data) { - evtchn_op_t op; + evtchn_bind_virq_t op; /* Try to bind the virq to a port */ - op.cmd = EVTCHNOP_bind_virq; - op.u.bind_virq.virq = virq; - op.u.bind_virq.vcpu = smp_processor_id(); + op.virq = virq; + op.vcpu = smp_processor_id(); - if ( HYPERVISOR_event_channel_op(&op) != 0 ) + if ( HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op) != 0 ) { printk("Failed to bind virtual IRQ %d\n", virq); return 1; } - bind_evtchn(op.u.bind_virq.port, handler, data); + bind_evtchn(op.port, handler, data); return 0; } @@ -151,14 +150,13 @@ int evtchn_alloc_unbound(domid_t pal, ev int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler, void *data, evtchn_port_t *port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.dom = DOMID_SELF; - op.u.alloc_unbound.remote_dom = pal; - int err = HYPERVISOR_event_channel_op(&op); + evtchn_alloc_unbound_t op; + op.dom = DOMID_SELF; + op.remote_dom = pal; + int err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); if (err) return err; - *port = bind_evtchn(op.u.alloc_unbound.port, handler, data); + *port = bind_evtchn(op.port, handler, data); return err; } @@ -169,14 +167,13 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_handler_t handler, void *data, evtchn_port_t *local_port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_bind_interdomain; - op.u.bind_interdomain.remote_dom = pal; - op.u.bind_interdomain.remote_port = remote_port; - int err = HYPERVISOR_event_channel_op(&op); + evtchn_bind_interdomain_t op; + op.remote_dom = pal; + op.remote_port = remote_port; + int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op); if (err) return err; - evtchn_port_t port = op.u.bind_interdomain.local_port; + evtchn_port_t port = op.local_port; clear_evtchn(port); /* Without, handler gets invoked now! */ *local_port = bind_evtchn(port, handler, data); return err; diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/include/events.h --- a/extras/mini-os/include/events.h Thu Sep 21 15:35:45 2006 -0600 +++ b/extras/mini-os/include/events.h Sun Sep 24 13:10:13 2006 -0600 @@ -39,10 +39,9 @@ int evtchn_bind_interdomain(domid_t pal, static inline int notify_remote_via_evtchn(evtchn_port_t port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_send; - op.u.send.port = port; - return HYPERVISOR_event_channel_op(&op); + evtchn_send_t op; + op.port = port; + return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op); } diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Thu Sep 21 15:35:45 2006 -0600 +++ b/extras/mini-os/include/x86/os.h Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 extras/mini-os/include/x86/x86_32/hypercall-x86_32.h --- a/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h Thu Sep 21 15:35:45 2006 -0600 +++ b/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h Sun Sep 24 13:10:13 2006 -0600 @@ -238,9 +238,9 @@ HYPERVISOR_update_va_mapping( static inline int HYPERVISOR_event_channel_op( - void *op) -{ - return _hypercall1(int, event_channel_op, op); + int cmd, void *op) +{ + return _hypercall2(int, event_channel_op, cmd, op); } static inline int diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Thu Sep 21 15:35:45 2006 -0600 +++ b/extras/mini-os/kernel.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/i386/Kconfig --- a/linux-2.6-xen-sparse/arch/i386/Kconfig Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Sun Sep 24 13:10:13 2006 -0600 @@ -789,6 +789,9 @@ config DOUBLEFAULT endmenu +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on HIGHMEM menu "Power management options (ACPI, APM)" depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sun Sep 24 13:10:13 2006 -0600 @@ -65,6 +65,7 @@ #include <xen/interface/physdev.h> #include <xen/interface/memory.h> #include <xen/features.h> +#include <xen/xencons.h> #include "setup_arch_pre.h" #include <bios_ebda.h> @@ -155,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 *); @@ -1450,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; @@ -1460,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) @@ -1485,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 @@ -1665,33 +1667,15 @@ void __init setup_arch(char **cmdline_p) screen_info.orig_video_cols = 80; screen_info.orig_video_ega_bx = 3; screen_info.orig_video_points = 16; + screen_info.orig_y = screen_info.orig_video_lines - 1; if (xen_start_info->console.dom0.info_size >= sizeof(struct dom0_vga_console_info)) { const struct dom0_vga_console_info *info = (struct dom0_vga_console_info *)( (char *)xen_start_info + xen_start_info->console.dom0.info_off); - screen_info.orig_video_mode = info->txt_mode; - screen_info.orig_video_isVGA = info->video_type; - screen_info.orig_video_lines = info->video_height; - screen_info.orig_video_cols = info->video_width; - screen_info.orig_video_points = info->txt_points; - screen_info.lfb_width = info->video_width; - screen_info.lfb_height = info->video_height; - screen_info.lfb_depth = info->lfb_depth; - screen_info.lfb_base = info->lfb_base; - screen_info.lfb_size = info->lfb_size; - screen_info.lfb_linelength = info->lfb_linelen; - screen_info.red_size = info->red_size; - screen_info.red_pos = info->red_pos; - screen_info.green_size = info->green_size; - screen_info.green_pos = info->green_pos; - screen_info.blue_size = info->blue_size; - screen_info.blue_pos = info->blue_pos; - screen_info.rsvd_size = info->rsvd_size; - screen_info.rsvd_pos = info->rsvd_pos; - } - screen_info.orig_y = screen_info.orig_video_lines - 1; + dom0_init_screen_info(info); + } xen_start_info->console.domU.mfn = 0; xen_start_info->console.domU.evtchn = 0; } else diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Sun Sep 24 13:10:13 2006 -0600 @@ -32,6 +32,8 @@ #include <../../../drivers/oprofile/cpu_buffer.h> #include <../../../drivers/oprofile/event_buffer.h> +#define MAX_XENOPROF_SAMPLES 16 + static int xenoprof_start(void); static void xenoprof_stop(void); @@ -43,7 +45,7 @@ static int active_defined; /* sample buffers shared with Xen */ xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS]; /* Shared buffer area */ -char * shared_buffer; +char * shared_buffer = NULL; /* Number of buffers in shared area (one per VCPU) */ int nbuf; /* Mappings of VIRQ_XENOPROF to irq number (per cpu) */ @@ -233,13 +235,57 @@ static int bind_virq(void) } +static int map_xenoprof_buffer(int max_samples) +{ + struct xenoprof_get_buffer get_buffer; + struct xenoprof_buf *buf; + int npages, ret, i; + struct vm_struct *area; + + if ( shared_buffer ) + return 0; + + get_buffer.max_samples = max_samples; + + if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) ) + return ret; + + nbuf = get_buffer.nbuf; + npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1; + + area = alloc_vm_area(npages * PAGE_SIZE); + if (area == NULL) + return -ENOMEM; + + if ( (ret = direct_kernel_remap_pfn_range( + (unsigned long)area->addr, + get_buffer.buf_maddr >> PAGE_SHIFT, + npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) ) { + vunmap(area->addr); + return ret; + } + + shared_buffer = area->addr; + for (i=0; i< nbuf; i++) { + buf = (struct xenoprof_buf*) + &shared_buffer[i * get_buffer.bufsize]; + BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); + xenoprof_buf[buf->vcpu_id] = buf; + } + + return 0; +} + + static int xenoprof_setup(void) { int ret; int i; - ret = bind_virq(); - if (ret) + if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) ) + return ret; + + if ( (ret = bind_virq()) ) return ret; if (is_primary) { @@ -482,50 +528,18 @@ int __init oprofile_arch_init(struct opr int __init oprofile_arch_init(struct oprofile_operations * ops) { struct xenoprof_init init; - struct xenoprof_buf *buf; - int npages, ret, i; - struct vm_struct *area; - - init.max_samples = 16; + int ret, i; + ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init); if (!ret) { - pgprot_t prot = __pgprot(_KERNPG_TABLE); - num_events = init.num_events; is_primary = init.is_primary; - nbuf = init.nbuf; /* just in case - make sure we do not overflow event list - (i.e. counter_config list) */ + (i.e. counter_config list) */ if (num_events > OP_MAX_COUNTER) num_events = OP_MAX_COUNTER; - - npages = (init.bufsize * nbuf - 1) / PAGE_SIZE + 1; - - area = alloc_vm_area(npages * PAGE_SIZE); - if (area == NULL) { - ret = -ENOMEM; - goto out; - } - - ret = direct_kernel_remap_pfn_range( - (unsigned long)area->addr, - init.buf_maddr >> PAGE_SHIFT, - npages * PAGE_SIZE, prot, DOMID_SELF); - if (ret) { - vunmap(area->addr); - goto out; - } - - shared_buffer = area->addr; - - for (i=0; i< nbuf; i++) { - buf = (struct xenoprof_buf*) - &shared_buffer[i * init.bufsize]; - BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); - xenoprof_buf[buf->vcpu_id] = buf; - } /* cpu_type is detected by Xen */ cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0; @@ -541,7 +555,6 @@ int __init oprofile_arch_init(struct opr active_defined = 0; } - out: printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, " "is_primary %d\n", ret, num_events, is_primary); return ret; diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/ia64/Kconfig --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Sun Sep 24 13:10:13 2006 -0600 @@ -276,6 +276,9 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config SCHED_SMT bool "SMT scheduler support" depends on SMP diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/ia64/dig/setup.c --- a/linux-2.6-xen-sparse/arch/ia64/dig/setup.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/dig/setup.c Sun Sep 24 13:10:13 2006 -0600 @@ -24,6 +24,8 @@ #include <asm/io.h> #include <asm/machvec.h> #include <asm/system.h> + +#include <xen/xencons.h> void __init dig_setup (char **cmdline_p) @@ -78,27 +80,8 @@ dig_setup (char **cmdline_p) (struct dom0_vga_console_info *)( (char *)xen_start_info + xen_start_info->console.dom0.info_off); - screen_info.orig_video_mode = info->txt_mode; - screen_info.orig_video_isVGA = info->video_type; - screen_info.orig_video_lines = info->video_height; - screen_info.orig_video_cols = info->video_width; - screen_info.orig_video_points = info->txt_points; - screen_info.lfb_width = info->video_width; - screen_info.lfb_height = info->video_height; - screen_info.lfb_depth = info->lfb_depth; - screen_info.lfb_base = info->lfb_base; - screen_info.lfb_size = info->lfb_size; - screen_info.lfb_linelength = info->lfb_linelen; - screen_info.red_size = info->red_size; - screen_info.red_pos = info->red_pos; - screen_info.green_size = info->green_size; - screen_info.green_pos = info->green_pos; - screen_info.blue_size = info->blue_size; - screen_info.blue_pos = info->blue_pos; - screen_info.rsvd_size = info->rsvd_size; - screen_info.rsvd_pos = info->rsvd_pos; + dom0_init_screen_info(info); } - screen_info.orig_y = screen_info.orig_video_lines - 1; xen_start_info->console.domU.mfn = 0; xen_start_info->console.domU.evtchn = 0; #endif diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/x86_64/Kconfig --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig Sun Sep 24 13:10:13 2006 -0600 @@ -368,6 +368,8 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y config HPET_TIMER bool diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Sun Sep 24 13:10:13 2006 -0600 @@ -316,12 +316,7 @@ tracesys: ja 1f movq %r10,%rcx /* fixup for C */ call *sys_call_table(,%rax,8) - movq %rax,RAX-ARGOFFSET(%rsp) -1: SAVE_REST - movq %rsp,%rdi - call syscall_trace_leave - RESTORE_TOP_OF_STACK %rbx - RESTORE_REST +1: movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ jmp int_ret_from_sys_call CFI_ENDPROC diff -r da942e577e5e -r 432f978d1cd1 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 Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Sun Sep 24 13:10:13 2006 -0600 @@ -74,6 +74,7 @@ #include <asm/hypervisor.h> #include <xen/interface/nmi.h> #include <xen/features.h> +#include <xen/xencons.h> #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_PHYS(x) ((x) << PAGE_SHIFT) #include <asm/mach-xen/setup_arch_post.h> @@ -143,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; @@ -625,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 @@ -645,33 +648,15 @@ void __init setup_arch(char **cmdline_p) screen_info.orig_video_cols = 80; screen_info.orig_video_ega_bx = 3; screen_info.orig_video_points = 16; + screen_info.orig_y = screen_info.orig_video_lines - 1; if (xen_start_info->console.dom0.info_size >= sizeof(struct dom0_vga_console_info)) { const struct dom0_vga_console_info *info = (struct dom0_vga_console_info *)( (char *)xen_start_info + xen_start_info->console.dom0.info_off); - screen_info.orig_video_mode = info->txt_mode; - screen_info.orig_video_isVGA = info->video_type; - screen_info.orig_video_lines = info->video_height; - screen_info.orig_video_cols = info->video_width; - screen_info.orig_video_points = info->txt_points; - screen_info.lfb_width = info->video_width; - screen_info.lfb_height = info->video_height; - screen_info.lfb_depth = info->lfb_depth; - screen_info.lfb_base = info->lfb_base; - screen_info.lfb_size = info->lfb_size; - screen_info.lfb_linelength = info->lfb_linelen; - screen_info.red_size = info->red_size; - screen_info.red_pos = info->red_pos; - screen_info.green_size = info->green_size; - screen_info.green_pos = info->green_pos; - screen_info.blue_size = info->blue_size; - screen_info.blue_pos = info->blue_pos; - screen_info.rsvd_size = info->rsvd_size; - screen_info.rsvd_pos = info->rsvd_pos; - } - screen_info.orig_y = screen_info.orig_video_lines - 1; + dom0_init_screen_info(info); + } xen_start_info->console.domU.mfn = 0; xen_start_info->console.domU.evtchn = 0; } else @@ -936,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); @@ -959,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 da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c Sun Sep 24 13:10:13 2006 -0600 @@ -30,6 +30,7 @@ #include <linux/moduleparam.h> #include <linux/nmi.h> #include <linux/kprobes.h> +#include <linux/kexec.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -438,6 +439,8 @@ void __kprobes __die(const char * str, s printk(KERN_ALERT "RIP "); printk_address(regs->rip); printk(" RSP <%016lx>\n", regs->rsp); + if (kexec_should_crash(current)) + crash_kexec(regs); } void die(const char * str, struct pt_regs * regs, long err) @@ -461,6 +464,8 @@ void __kprobes die_nmi(char *str, struct */ printk(str, safe_smp_processor_id()); show_registers(regs); + if (kexec_should_crash(current)) + crash_kexec(regs); if (panic_on_timeout || panic_on_oops) panic("nmi watchdog"); printk("console shuts up ...\n"); diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/drivers/char/tty_io.c --- a/linux-2.6-xen-sparse/drivers/char/tty_io.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c Sun Sep 24 13:10:13 2006 -0600 @@ -2761,7 +2761,7 @@ static void flush_to_ldisc(void *private struct tty_struct *tty = (struct tty_struct *) private_; unsigned long flags; struct tty_ldisc *disc; - struct tty_buffer *tbuf; + struct tty_buffer *tbuf, *head; int count; char *char_buf; unsigned char *flag_buf; @@ -2778,7 +2778,9 @@ static void flush_to_ldisc(void *private goto out; } spin_lock_irqsave(&tty->buf.lock, flags); - while((tbuf = tty->buf.head) != NULL) { + head = tty->buf.head; + tty->buf.head = NULL; + while((tbuf = head) != NULL) { while ((count = tbuf->commit - tbuf->read) != 0) { char_buf = tbuf->char_buf_ptr + tbuf->read; flag_buf = tbuf->flag_buf_ptr + tbuf->read; @@ -2787,10 +2789,12 @@ static void flush_to_ldisc(void *private disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - if (tbuf->active) + if (tbuf->active) { + tty->buf.head = head; break; - tty->buf.head = tbuf->next; - if (tty->buf.head == NULL) + } + head = tbuf->next; + if (head == NULL) tty->buf.tail = NULL; tty_buffer_free(tty, tbuf); } diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/drivers/serial/Kconfig --- a/linux-2.6-xen-sparse/drivers/serial/Kconfig Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/serial/Kconfig Sun Sep 24 13:10:13 2006 -0600 @@ -821,6 +821,7 @@ config SERIAL_ICOM tristate "IBM Multiport Serial Adapter" depends on PCI && (PPC_ISERIES || PPC_PSERIES) select SERIAL_CORE + select FW_LOADER help This driver is for a family of multiport serial adapters including 2 port RVX, 2 port internal modem, 4 port internal diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Sun Sep 24 13:10:13 2006 -0600 @@ -49,6 +49,7 @@ #include <linux/console.h> #include <linux/bootmem.h> #include <linux/sysrq.h> +#include <linux/screen_info.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/uaccess.h> @@ -262,6 +263,41 @@ void xencons_force_flush(void) sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent > 0) wc += sent; + } +} + + +void dom0_init_screen_info(const struct dom0_vga_console_info *info) +{ + switch (info->video_type) { + case XEN_VGATYPE_TEXT_MODE_3: + screen_info.orig_video_mode = 3; + screen_info.orig_video_ega_bx = 3; + screen_info.orig_video_isVGA = 1; + screen_info.orig_video_lines = info->u.text_mode_3.rows; + screen_info.orig_video_cols = info->u.text_mode_3.columns; + screen_info.orig_x = info->u.text_mode_3.cursor_x; + screen_info.orig_y = info->u.text_mode_3.cursor_y; + screen_info.orig_video_points = + info->u.text_mode_3.font_height; + break; + case XEN_VGATYPE_VESA_LFB: + screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB; + screen_info.lfb_width = info->u.vesa_lfb.width; + screen_info.lfb_height = info->u.vesa_lfb.height; + screen_info.lfb_depth = info->u.vesa_lfb.bits_per_pixel; + screen_info.lfb_base = info->u.vesa_lfb.lfb_base; + screen_info.lfb_size = info->u.vesa_lfb.lfb_size; + screen_info.lfb_linelength = info->u.vesa_lfb.bytes_per_line; + screen_info.red_size = info->u.vesa_lfb.red_size; + screen_info.red_pos = info->u.vesa_lfb.red_pos; + screen_info.green_size = info->u.vesa_lfb.green_size; + screen_info.green_pos = info->u.vesa_lfb.green_pos; + screen_info.blue_size = info->u.vesa_lfb.blue_size; + screen_info.blue_pos = info->u.vesa_lfb.blue_pos; + screen_info.rsvd_size = info->u.vesa_lfb.rsvd_size; + screen_info.rsvd_pos = info->u.vesa_lfb.rsvd_pos; + break; } } diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/include/xen/xencons.h --- a/linux-2.6-xen-sparse/include/xen/xencons.h Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/include/xen/xencons.h Sun Sep 24 13:10:13 2006 -0600 @@ -1,5 +1,8 @@ #ifndef __ASM_XENCONS_H__ #define __ASM_XENCONS_H__ + +struct dom0_vga_console_info; +void dom0_init_screen_info(const struct dom0_vga_console_info *info); void xencons_force_flush(void); void xencons_resume(void); diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/mm/Kconfig --- a/linux-2.6-xen-sparse/mm/Kconfig Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/mm/Kconfig Sun Sep 24 13:10:13 2006 -0600 @@ -115,7 +115,7 @@ config SPARSEMEM_EXTREME # eventually, we can have this option just 'select SPARSEMEM' config MEMORY_HOTPLUG bool "Allow for memory hot-add" - depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND + depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG comment "Memory hotplug is currently incompatible with Software Suspend" depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/mm/page_alloc.c --- a/linux-2.6-xen-sparse/mm/page_alloc.c Thu Sep 21 15:35:45 2006 -0600 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c Sun Sep 24 13:10:13 2006 -0600 @@ -951,7 +951,8 @@ restart: alloc_flags |= ALLOC_HARDER; if (gfp_mask & __GFP_HIGH) alloc_flags |= ALLOC_HIGH; - alloc_flags |= ALLOC_CPUSET; + if (wait) + alloc_flags |= ALLOC_CPUSET; /* * Go through the zonelist again. Let __GFP_HIGH and allocations diff -r da942e577e5e -r 432f978d1cd1 tools/check/check_python --- a/tools/check/check_python Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/check/check_python Sun Sep 24 13:10:13 2006 -0600 @@ -7,4 +7,4 @@ function error { exit 1 } -python -V 2>&1 | cut -d ' ' -f 2 | grep -q -E '^2.2|^2.3|^2.4' || error +python -V 2>&1 | cut -d ' ' -f 2 | grep -q '^2.[2345]' || error diff -r da942e577e5e -r 432f978d1cd1 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/console/daemon/io.c Sun Sep 24 13:10:13 2006 -0600 @@ -293,12 +293,14 @@ static bool watch_domain(struct domain * bool success; sprintf(domid_str, "dom%u", dom->domid); - if (watch) + if (watch) { success = xs_watch(xs, dom->conspath, domid_str); - else + if (success) + domain_create_ring(dom); + } else { success = xs_unwatch(xs, dom->conspath, domid_str); - if (success) - domain_create_ring(dom); + } + return success; } diff -r da942e577e5e -r 432f978d1cd1 tools/debugger/gdb/gdbbuild --- a/tools/debugger/gdb/gdbbuild Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/debugger/gdb/gdbbuild Sun Sep 24 13:10:13 2006 -0600 @@ -1,4 +1,6 @@ #!/bin/sh + +set -e [ "$GDB_MIRROR" ] || GDB_MIRROR="ftp://ftp.gnu.org/gnu/gdb/" diff -r da942e577e5e -r 432f978d1cd1 tools/examples/locking.sh --- a/tools/examples/locking.sh Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/examples/locking.sh Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/firmware/vmxassist/machine.h --- a/tools/firmware/vmxassist/machine.h Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/firmware/vmxassist/machine.h Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/firmware/vmxassist/vm86.c Sun Sep 24 13:10:13 2006 -0600 @@ -52,29 +52,74 @@ 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 *)gcr3)[(base >> 22) & 0x3ff]; + + if (oldctx.cr4 & CR4_PSE || l1_mfn & PDE_PS) { + /* 1 level page table */ + l0_mfn = l1_mfn; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + + l0_mfn &= 0xffc00000; + return l0_mfn + (base & 0x3fffff); + } + + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + + l1_mfn &= 0xfffff000; + l0_mfn = ((uint32_t *)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 if (oldctx.cr4 & CR4_PAE && !(oldctx.cr4 & CR4_PSE)) { + l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3]; + if (!(l2_mfn & PT_ENTRY_PRESENT)) + panic("l3 entry not present\n"); + l2_mfn &= 0x3fffff000ULL; + + l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + l1_mfn &= 0x3fffff000ULL; + + l0_mfn = ((uint64_t *)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); + } else { /* oldctx.cr4 & CR4_PAE && oldctx.cr4 & CR4_PSE */ + l1_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + l1_mfn &= 0x3fffff000ULL; + + l0_mfn = ((uint64_t *)l1_mfn)[(base >> 21) & 0x1ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0x3ffe00000ULL; + + return l0_mfn + (base & 0x1fffff); + } } static unsigned @@ -95,7 +140,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 +826,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) diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/hw/vga.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/hw/xen_platform.c --- a/tools/ioemu/hw/xen_platform.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/hw/xen_platform.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/domain-timeoffset --- a/tools/ioemu/patches/domain-timeoffset Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/domain-timeoffset Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-bootorder --- a/tools/ioemu/patches/qemu-bootorder Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/qemu-bootorder Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-daemonize --- a/tools/ioemu/patches/qemu-daemonize Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/qemu-daemonize Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-pci --- a/tools/ioemu/patches/qemu-pci Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/qemu-pci Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-target-i386-dm --- a/tools/ioemu/patches/qemu-target-i386-dm Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/qemu-target-i386-dm Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/series --- a/tools/ioemu/patches/series Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/series Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-access-monitor-vt --- a/tools/ioemu/patches/vnc-access-monitor-vt Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-access-monitor-vt Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-cleanup --- a/tools/ioemu/patches/vnc-cleanup Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-cleanup Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-display-find-unused --- a/tools/ioemu/patches/vnc-display-find-unused Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-display-find-unused Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-fixes --- a/tools/ioemu/patches/vnc-fixes Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-fixes Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-start-vncviewer --- a/tools/ioemu/patches/vnc-start-vncviewer Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-start-vncviewer Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-title-domain-name --- a/tools/ioemu/patches/vnc-title-domain-name Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/vnc-title-domain-name Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xen-platform-device --- a/tools/ioemu/patches/xen-platform-device Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/xen-platform-device Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xen-support-buffered-ioreqs --- a/tools/ioemu/patches/xen-support-buffered-ioreqs Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/xen-support-buffered-ioreqs Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xenstore-block-device-config --- a/tools/ioemu/patches/xenstore-block-device-config Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/xenstore-block-device-config Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xenstore-write-vnc-port --- a/tools/ioemu/patches/xenstore-write-vnc-port Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/patches/xenstore-write-vnc-port Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/target-i386-dm/helper2.c Sun Sep 24 13:10:13 2006 -0600 @@ -520,8 +520,8 @@ int main_loop(void) } } - /* 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; diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/usb-linux.c --- a/tools/ioemu/usb-linux.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/usb-linux.c Sun Sep 24 13:10:13 2006 -0600 @@ -26,7 +26,6 @@ #if defined(__linux__) #include <dirent.h> #include <sys/ioctl.h> -#include <linux/compiler.h> #include <linux/usbdevice_fs.h> #include <linux/version.h> diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/vl.c Sun Sep 24 13:10:13 2006 -0600 @@ -723,6 +723,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_mod_timer(ts, expire_time); } /* modify the current timer so that it will be fired when current_time diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/vl.h Sun Sep 24 13:10:13 2006 -0600 @@ -405,6 +405,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; diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/ioemu/vnc.c Sun Sep 24 13:10:13 2006 -0600 @@ -27,7 +27,19 @@ #include "vl.h" #include "qemu_socket.h" -#define VNC_REFRESH_INTERVAL (1000 / 30) +/* 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 +76,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 +110,6 @@ struct VncState int visible_y; int visible_w; int visible_h; - - int slow_client; int ctl_keys; /* Ctrl+Alt starts calibration */ }; @@ -380,7 +391,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 +401,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 +454,145 @@ 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. */ + /* Note that there are bugs in xvncviewer which prevent + this from actually working. Leave the code in place + for correct clients. */ + vnc_write_u8(vs, 0); + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 0); + 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 +607,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 +668,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; @@ -895,13 +937,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 +1059,7 @@ static int protocol_client_msg(VncState { int i; uint16_t limit; + int64_t now; switch (data[0]) { case 0: @@ -1055,12 +1099,18 @@ 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: @@ -1086,6 +1136,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; @@ -1269,7 +1321,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 da942e577e5e -r 432f978d1cd1 tools/libxc/powerpc64/Makefile --- a/tools/libxc/powerpc64/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/libxc/powerpc64/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -1,1 +1,4 @@ GUEST_SRCS-y += powerpc64/xc_linux_build GUEST_SRCS-y += powerpc64/xc_linux_build.c +GUEST_SRCS-y += powerpc64/flatdevtree.c + +CTRL_SRCS-y += powerpc64/xc_memory.c diff -r da942e577e5e -r 432f978d1cd1 tools/libxc/powerpc64/xc_linux_build.c --- a/tools/libxc/powerpc64/xc_linux_build.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/libxc/powerpc64/xc_linux_build.c Sun Sep 24 13:10:13 2006 -0600 @@ -27,14 +27,17 @@ #include <sys/types.h> #include <inttypes.h> +#include <xen/xen.h> #include <xen/memory.h> #include <xc_private.h> #include <xg_private.h> #include <xenctrl.h> -/* XXX 64M hack */ -#define MEMSIZE (64UL << 20) +#include "flatdevtree_env.h" +#include "flatdevtree.h" + #define INITRD_ADDR (24UL << 20) +#define DEVTREE_ADDR (16UL << 20) #define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) @@ -91,8 +94,8 @@ static int init_boot_vcpu( int xc_handle, int domid, struct domain_setup_info *dsi, - unsigned long dtb, - unsigned long kaddr) + unsigned long devtree_addr, + unsigned long kern_addr) { vcpu_guest_context_t ctxt; int rc; @@ -101,15 +104,15 @@ static int init_boot_vcpu( ctxt.user_regs.pc = dsi->v_kernentry; ctxt.user_regs.msr = 0; ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */ - ctxt.user_regs.gprs[3] = dtb; - ctxt.user_regs.gprs[4] = kaddr; + ctxt.user_regs.gprs[3] = devtree_addr; + ctxt.user_regs.gprs[4] = kern_addr; ctxt.user_regs.gprs[5] = 0; /* There is a buggy kernel that does not zero the "local_paca", so * we must make sure this register is 0 */ ctxt.user_regs.gprs[13] = 0; DPRINTF("xc_vcpu_setvcpucontext:\n" - " pc 0x%"PRIx64", msr 0x016%"PRIx64"\n" + " pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n" " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64 " %016"PRIx64"\n", ctxt.user_regs.pc, ctxt.user_regs.msr, @@ -156,31 +159,69 @@ static int install_image( return rc; } -/* XXX be more flexible about placement in memory */ -static int load_dtb( +static int load_devtree( int xc_handle, int domid, - const char *dtb_path, - unsigned long dtb_addr, - struct domain_setup_info *dsi, - xen_pfn_t *page_array) -{ - uint8_t *img; - unsigned long dtb_size; + xen_pfn_t *page_array, + void *devtree, + unsigned long devtree_addr, + uint64_t initrd_base, + unsigned long initrd_len, + start_info_t *si, + unsigned long si_addr) +{ + uint32_t start_info[4] = {0, si_addr, 0, 0x1000}; + struct boot_param_header *header; + void *chosen; + void *xen; + uint64_t initrd_end = initrd_base + initrd_len; + unsigned int devtree_size; int rc = 0; - img = load_file(dtb_path, &dtb_size); - if (img == NULL) { - rc = -1; - goto out; - } - - DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size); - rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size); - -out: - free(img); - return rc; + DPRINTF("adding initrd props\n"); + + chosen = ft_find_node(devtree, "/chosen"); + if (chosen == NULL) { + DPRINTF("couldn't find /chosen\n"); + return -1; + } + + xen = ft_find_node(devtree, "/xen"); + if (xen == NULL) { + DPRINTF("couldn't find /xen\n"); + return -1; + } + + /* initrd-start */ + rc = ft_set_prop(&devtree, chosen, "linux,initrd-start", + &initrd_base, sizeof(initrd_base)); + if (rc < 0) { + DPRINTF("couldn't set /chosen/linux,initrd-start\n"); + return rc; + } + + /* initrd-end */ + rc = ft_set_prop(&devtree, chosen, "linux,initrd-end", + &initrd_end, sizeof(initrd_end)); + if (rc < 0) { + DPRINTF("couldn't set /chosen/linux,initrd-end\n"); + return rc; + } + + /* start-info (XXX being removed soon) */ + rc = ft_set_prop(&devtree, xen, "start-info", + start_info, sizeof(start_info)); + if (rc < 0) { + DPRINTF("couldn't set /xen/start-info\n"); + return rc; + } + + header = devtree; + devtree_size = header->totalsize; + + DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size); + return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR, + devtree_size); } unsigned long spin_list[] = { @@ -294,17 +335,16 @@ out: } static unsigned long create_start_info(start_info_t *si, - unsigned int console_evtchn, unsigned int store_evtchn) -{ - unsigned long eomem; + unsigned int console_evtchn, unsigned int store_evtchn, + unsigned long nr_pages) +{ unsigned long si_addr; memset(si, 0, sizeof(*si)); snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); - eomem = MEMSIZE; - si->nr_pages = eomem >> PAGE_SHIFT; - si->shared_info = eomem - (PAGE_SIZE * 1); + si->nr_pages = nr_pages; + si->shared_info = (nr_pages - 1) << PAGE_SHIFT; si->store_mfn = si->nr_pages - 2; si->store_evtchn = store_evtchn; si->console.domU.mfn = si->nr_pages - 3; @@ -314,29 +354,34 @@ static unsigned long create_start_info(s return si_addr; } -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array) -{ - int nr_pages; +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array, + unsigned long *nr_pages) +{ int rc; DPRINTF("xc_get_tot_pages\n"); - nr_pages = xc_get_tot_pages(xc_handle, domid); - DPRINTF(" 0x%x\n", nr_pages); - - *page_array = malloc(nr_pages * sizeof(xen_pfn_t)); + *nr_pages = xc_get_tot_pages(xc_handle, domid); + DPRINTF(" 0x%lx\n", *nr_pages); + + *page_array = malloc(*nr_pages * sizeof(xen_pfn_t)); if (*page_array == NULL) { perror("malloc"); return -1; } DPRINTF("xc_get_pfn_list\n"); - rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages); - if (rc != nr_pages) { + rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages); + if (rc != *nr_pages) { perror("Could not get the page frame list"); return -1; } return 0; +} + +static void free_page_array(xen_pfn_t *page_array) +{ + free(page_array); } @@ -351,57 +396,70 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn) -{ + unsigned long *console_mfn, + void *devtree) +{ + start_info_t si; struct domain_setup_info dsi; xen_pfn_t *page_array = NULL; + unsigned long nr_pages; + unsigned long devtree_addr = 0; unsigned long kern_addr; - unsigned long dtb_addr; - unsigned long si_addr; unsigned long initrd_base = 0; unsigned long initrd_len = 0; - start_info_t si; + unsigned long si_addr; int rc = 0; - if (get_page_array(xc_handle, domid, &page_array)) { - rc = -1; - goto out; - } - + DPRINTF("%s\n", __func__); + + if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) { + rc = -1; + goto out; + } + + DPRINTF("loading image '%s'\n", image_name); if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) { rc = -1; goto out; } kern_addr = 0; - if (initrd_name && initrd_name[0] != '\0' && - load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base, - &initrd_len)) { - rc = -1; - goto out; - } - /* XXX install initrd addr/len into device tree */ - - dtb_addr = (16 << 20); - if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) { - dtb_addr = 0; - } - - si_addr = create_start_info(&si, console_evtchn, store_evtchn); + if (initrd_name && initrd_name[0] != '\0') { + DPRINTF("loading initrd '%s'\n", initrd_name); + if (load_initrd(xc_handle, domid, page_array, initrd_name, + &initrd_base, &initrd_len)) { + rc = -1; + goto out; + } + } + + /* start_info stuff: about to be removed */ + si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages); *console_mfn = page_array[si.console.domU.mfn]; *store_mfn = page_array[si.store_mfn]; - if (install_image(xc_handle, domid, page_array, &si, si_addr, sizeof(start_info_t))) { rc = -1; goto out; } - if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) { + if (devtree) { + DPRINTF("loading flattened device tree\n"); + devtree_addr = DEVTREE_ADDR; + if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr, + initrd_base, initrd_len, &si, si_addr)) { + DPRINTF("couldn't load flattened device tree.\n"); + rc = -1; + goto out; + } + } + + if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) { rc = -1; goto out; } out: - return rc; -} + free_page_array(page_array); + return rc; +} diff -r da942e577e5e -r 432f978d1cd1 tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/libxc/xc_ptrace.c Sun Sep 24 13:10:13 2006 -0600 @@ -611,17 +611,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 da942e577e5e -r 432f978d1cd1 tools/pygrub/Makefile --- a/tools/pygrub/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/pygrub/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/pygrub/src/fsys/ext2/__init__.py --- a/tools/pygrub/src/fsys/ext2/__init__.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/pygrub/src/fsys/ext2/__init__.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/pygrub/src/fsys/reiser/__init__.py --- a/tools/pygrub/src/fsys/reiser/__init__.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/pygrub/src/fsys/reiser/__init__.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/util/blkif.py --- a/tools/python/xen/util/blkif.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/util/blkif.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 @@ -65,7 +65,7 @@ def blkdev_uname_to_file(uname): fn = None if uname.find(":") != -1: (typ, fn) = uname.split(":") - if typ == "phy" and not fn.startswith("/dev/"): + if typ == "phy" and not fn.startswith("/"): fn = "/dev/%s" %(fn,) return fn diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendBootloader.py --- a/tools/python/xen/xend/XendBootloader.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/XendBootloader.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/XendDomain.py Sun Sep 24 13:10:13 2006 -0600 @@ -390,6 +390,22 @@ class XendDomain: except Exception, ex: raise XendError(str(ex)) + def domain_dump(self, domid, filename, live, crash): + """Dump domain core.""" + + dominfo = self.domain_lookup_by_name_or_id_nr(domid) + if not dominfo: + raise XendInvalidDomain(str(domid)) + + if dominfo.getDomid() == PRIV_DOMAIN: + raise XendError("Cannot dump core for privileged domain %s" % domid) + + try: + log.info("Domain core dump requested for domain %s (%d) live=%d crash=%d.", + dominfo.getName(), dominfo.getDomid(), live, crash) + return dominfo.dumpCore(filename) + except Exception, ex: + raise XendError(str(ex)) def domain_destroy(self, domid): """Terminate domain immediately.""" @@ -544,13 +560,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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/XendDomainInfo.py Sun Sep 24 13:10:13 2006 -0600 @@ -86,6 +86,7 @@ STATE_DOM_SHUTDOWN = 2 STATE_DOM_SHUTDOWN = 2 SHUTDOWN_TIMEOUT = 30.0 +MIGRATE_TIMEOUT = 30.0 ZOMBIE_PREFIX = 'Zombie-' @@ -595,6 +596,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'] @@ -977,18 +980,26 @@ class XendDomainInfo: self.restart(True) - def dumpCore(self): + def dumpCore(self,corefile=None): """Create a core dump for this domain. Nothrow guarantee.""" try: - corefile = "/var/xen/dump/%s.%s.core" % (self.info['name'], - self.domid) + if not corefile: + 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: @@ -996,6 +1007,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) @@ -1088,15 +1102,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) @@ -1531,14 +1546,19 @@ class XendDomainInfo: the device has shutdown correctly, i.e. all blocks are flushed to disk """ + start = time.time() while True: test = 0 + diff = time.time() - start for i in self.getDeviceController('vbd').deviceIDs(): test = 1 log.info("Dev %s still active, looping...", i) time.sleep(0.1) if test == 0: + break + if diff >= MIGRATE_TIMEOUT: + log.info("Dev still active but hit max loop timeout") break def migrateDevices(self, network, dst, step, domName=''): diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/image.py Sun Sep 24 13:10:13 2006 -0600 @@ -340,10 +340,6 @@ class HVMImageHandler(ImageHandler): (nics, mac, model)) ret.append("-net") ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge)) - if name == 'vtpm': - instance = sxp.child_value(info, 'pref_instance') - ret.append("-instance") - ret.append("%s" % instance) return ret def configVNC(self, config): diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/server/DevController.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/server/blkif.py Sun Sep 24 13:10:13 2006 -0600 @@ -64,10 +64,14 @@ class BlkifController(DevController): except ValueError: (typ, params) = ("", "") + mode = sxp.child_value(config, 'mode', 'r') + if mode not in ('r', 'w', 'w!'): + raise VmError('Invalid mode') + back = { 'dev' : dev, 'type' : typ, 'params' : params, - 'mode' : sxp.child_value(config, 'mode', 'r') + 'mode' : mode } if security.on(): diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/server/tpmif.py --- a/tools/python/xen/xend/server/tpmif.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xend/server/tpmif.py Sun Sep 24 13:10:13 2006 -0600 @@ -52,7 +52,7 @@ class TPMifController(DevController): if inst == -1: inst = int(sxp.child_value(config, 'instance' , '0')) - log.info("The domain has a TPM with instance %d and devid %d.", + log.info("The domain has a TPM with pref. instance %d and devid %d.", inst, devid) back = { 'pref_instance' : "%i" % inst, 'resume' : "%s" % (self.vm.getResume()) } diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/addlabel.py Sun Sep 24 13:10:13 2006 -0600 @@ -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): @@ -114,9 +118,8 @@ def main (argv): def main (argv): try: policyref = None - if len(argv) not in [4,5]: - usage() - return + if len(argv) not in (4, 5): + raise OptionError('Needs either 2 or 3 arguments') label = argv[1] @@ -135,20 +138,20 @@ def main (argv): if os.path.isfile(configfile): break if not validate_config_file(configfile): - usage() + 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: - usage() - + raise OptionError('Need to specify either "dom" or "res" as object to add label to.') + except security.ACMError: sys.exit(-1) - if __name__ == '__main__': main(sys.argv) + diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/cfgbootpolicy.py --- a/tools/python/xen/xm/cfgbootpolicy.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/cfgbootpolicy.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 @@ -152,7 +149,7 @@ def main(argv): policy = argv[1] user_kver = argv[2] else: - usage() + raise OptionError('Invalid number of arguments') if not policy_name_re.match(policy): err("Illegal policy name \'" + policy + "\'") diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/console.py --- a/tools/python/xen/xm/console.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/console.py Sun Sep 24 13:10:13 2006 -0600 @@ -18,9 +18,7 @@ XENCONSOLE = "xenconsole" - import xen.util.auxbin - def execConsole(domid): xen.util.auxbin.execute(XENCONSOLE, [str(domid)]) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/create.py Sun Sep 24 13:10:13 2006 -0600 @@ -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, @@ -439,7 +438,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. @@ -490,7 +488,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: @@ -851,7 +848,6 @@ def choose_vnc_display(): if port in ports: continue return d return None - vncpid = None def daemonize(prog, args): @@ -885,7 +881,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()) @@ -904,6 +899,7 @@ def spawn_vnc(display): vncpid = daemonize("vncviewer", vncargs) if vncpid == 0: return 0 + return VNC_BASE_PORT + display def preprocess_vnc(vals): @@ -1019,11 +1015,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: @@ -1091,7 +1086,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. @@ -1145,7 +1139,6 @@ def config_security_check(config, verbos return answer - def create_security_check(config): passed = 0 try: @@ -1158,7 +1151,9 @@ def create_security_check(config): sys.exit(-1) return passed - + +def help(): + return str(gopts) def main(argv): try: @@ -1176,11 +1171,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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/dry-run.py --- a/tools/python/xen/xm/dry-run.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/dry-run.py Sun Sep 24 13:10:13 2006 -0600 @@ -22,20 +22,19 @@ 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() + raise OptionError('Invalid number of arguments') passed = 0 (opts, config) = create.parseCommandLine(argv) @@ -44,7 +43,7 @@ def main (argv): passed = 1 else: print "Checking resources: (skipped)" - + if passed: print "Dry Run: PASSED" else: diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/dumppolicy.py --- a/tools/python/xen/xm/dumppolicy.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/dumppolicy.py Sun Sep 24 13:10:13 2006 -0600 @@ -21,12 +21,10 @@ from xen.util.security import ACMError, from xen.util.security import ACMError, err, dump_policy -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): try: @@ -34,7 +32,6 @@ def main(argv): usage() dump_policy() - except ACMError: sys.exit(-1) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/getlabel.py --- a/tools/python/xen/xm/getlabel.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/getlabel.py Sun Sep 24 13:10:13 2006 -0600 @@ -21,13 +21,13 @@ 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>\n" + This program shows the label for a domain or resource.""" def get_resource_label(resource): """Gets the resource label @@ -90,21 +90,17 @@ def get_domain_label(configfile): def main (argv): - try: - if len(argv) != 3: - usage() + 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) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/labels.py --- a/tools/python/xen/xm/labels.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/labels.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/loadpolicy.py --- a/tools/python/xen/xm/loadpolicy.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/loadpolicy.py Sun Sep 24 13:10:13 2006 -0600 @@ -21,26 +21,23 @@ 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): + if len(argv) != 2: + raise OptionError('No policy defined') + try: - if len(argv) != 2: - usage() load_policy(argv[1]) 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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/main.py Sun Sep 24 13:10:13 2006 -0600 @@ -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,152 @@ 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" -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", + "dump-core", "help", "list", "mem-set", @@ -159,8 +217,8 @@ domain_commands = [ "destroy", "domid", "domname", + "dump-core", "list", - "list_label", "mem-max", "mem-set", "migrate", @@ -218,67 +276,105 @@ 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.""" + + 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) #################################################################### @@ -293,7 +389,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: @@ -340,14 +436,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) @@ -361,9 +462,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) @@ -373,9 +474,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: @@ -392,7 +495,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) @@ -407,7 +510,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), @@ -423,7 +526,7 @@ def parse_sedf_info(info): return t(sxp.child_value(info, n, d)) return { - 'dom' : get_info('domain', int, -1), + 'domid' : get_info('domid', int, -1), 'period' : get_info('period', int, -1), 'slice' : get_info('slice', int, -1), 'latency' : get_info('latency', int, -1), @@ -431,34 +534,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): @@ -469,7 +578,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): @@ -563,10 +676,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) @@ -590,32 +700,68 @@ def xm_unpause(args): server.xend.domain.unpause(dom) +def xm_dump_core(args): + live = False + crash = False + 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]) + else: + filename = None + + if not live: + server.xend.domain.pause(dom) + + try: + 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) + 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: + cpus.append(int(c)) + cpus.sort() + return cpus dom = args[0] vcpu = int(args[1]) @@ -677,11 +823,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: @@ -715,20 +862,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(): @@ -738,7 +890,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)) @@ -747,17 +899,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 @@ -774,20 +923,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) @@ -806,6 +951,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): @@ -862,6 +1009,12 @@ def xm_uptime(args): 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) @@ -883,8 +1036,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() @@ -902,7 +1058,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: @@ -1048,7 +1204,7 @@ def parse_block_configuration(args): cls = 'tap' else: cls = 'vbd' - + vbd = [cls, ['uname', args[1]], ['dev', args[2]], @@ -1057,19 +1213,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 + 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) return (dom, vbd) @@ -1168,11 +1317,13 @@ commands = { "destroy": xm_destroy, "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 @@ -1211,24 +1362,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", @@ -1246,11 +1396,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() @@ -1258,27 +1415,17 @@ 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 and output our own help + if '--help' in argv[1:]: + if '--help' == argv[1]: + longHelp() + else: + usage(argv[1]) + sys.exit(0) cmd = xm_lookup_cmd(argv[1]) @@ -1291,9 +1438,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." @@ -1302,16 +1449,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: @@ -1326,6 +1473,10 @@ def main(argv=sys.argv): except (ValueError, OverflowError): err("Invalid argument.") usage(argv[1]) + except OptionError, e: + err(str(e)) + usage(argv[1]) + print e.usage() except: print "Unexpected error:", sys.exc_info()[0] print diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/makepolicy.py --- a/tools/python/xen/xm/makepolicy.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/makepolicy.py Sun Sep 24 13:10:13 2006 -0600 @@ -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,13 +29,12 @@ def usage(): err("Usage") +def main(argv): + if len(argv) != 2: + raise OptionError('No XML policy file specified') -def main(argv): try: - if len(argv) != 2: - usage() make_policy(argv[1]) - except ACMError: sys.exit(-1) except: @@ -43,7 +42,6 @@ def main(argv): sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/migrate.py --- a/tools/python/xen/xm/migrate.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/migrate.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/opts.py --- a/tools/python/xen/xm/opts.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/opts.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/resources.py --- a/tools/python/xen/xm/resources.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/resources.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 """Usage: xm resource + 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,11 +37,16 @@ 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: - if len(argv) != 1: - usage() + filename = security.res_label_filename + access_control = dictio.dict_read("resources", filename) + except: + print "Resource file not found." + return try: file = security.res_label_filename @@ -52,9 +56,6 @@ def main (argv): print_resource_data(access_control) - except security.ACMError: - sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/rmlabel.py --- a/tools/python/xen/xm/rmlabel.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/rmlabel.py Sun Sep 24 13:10:13 2006 -0600 @@ -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): @@ -93,22 +95,22 @@ def rm_domain_label(configfile): def main (argv): + + 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]) + 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() - except security.ACMError: sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/shutdown.py --- a/tools/python/xen/xm/shutdown.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/python/xen/xm/shutdown.py Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/doc/man/vn.pod.1 --- a/tools/vnet/doc/man/vn.pod.1 Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/doc/man/vn.pod.1 Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/Makefile --- a/tools/vnet/libxutil/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/libxutil/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/hash_table.c --- a/tools/vnet/libxutil/hash_table.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/libxutil/hash_table.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/hash_table.h --- a/tools/vnet/libxutil/hash_table.h Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/libxutil/hash_table.h Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/Makefile.ver --- a/tools/vnet/vnet-module/Makefile.ver Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/Makefile.ver Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/esp.c --- a/tools/vnet/vnet-module/esp.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/esp.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/etherip.c --- a/tools/vnet/vnet-module/etherip.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/etherip.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/tunnel.c --- a/tools/vnet/vnet-module/tunnel.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/tunnel.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/tunnel.h --- a/tools/vnet/vnet-module/tunnel.h Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/tunnel.h Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/varp.c --- a/tools/vnet/vnet-module/varp.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/varp.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/varp_socket.c --- a/tools/vnet/vnet-module/varp_socket.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/varp_socket.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vif.c --- a/tools/vnet/vnet-module/vif.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/vif.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet.c --- a/tools/vnet/vnet-module/vnet.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/vnet.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_dev.c --- a/tools/vnet/vnet-module/vnet_dev.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/vnet_dev.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_eval.c --- a/tools/vnet/vnet-module/vnet_eval.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/vnet_eval.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_forward.c --- a/tools/vnet/vnet-module/vnet_forward.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnet-module/vnet_forward.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnetd/Makefile --- a/tools/vnet/vnetd/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnetd/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnetd/vnetd.c --- a/tools/vnet/vnetd/vnetd.c Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/vnet/vnetd/vnetd.c Sun Sep 24 13:10:13 2006 -0600 @@ -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 da942e577e5e -r 432f978d1cd1 tools/xenmon/xenmon.py --- a/tools/xenmon/xenmon.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/xenmon/xenmon.py Sun Sep 24 13:10:13 2006 -0600 @@ -675,6 +675,11 @@ def main(): if options.mspersample < 0: parser.error("option --ms_per_sample: invalid negative value: '%d'" % options.mspersample) + # If --ms_per_sample= is too large, no data may be logged. + if not options.live and options.duration != 0 and \ + options.mspersample > options.duration * 1000: + parser.error("option --ms_per_sample: too large (> %d ms)" % + (options.duration * 1000)) start_xenbaked() if options.live: diff -r da942e577e5e -r 432f978d1cd1 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py --- a/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Sun Sep 24 13:10:13 2006 -0600 @@ -42,7 +42,7 @@ except ConsoleError, e: FAIL("Error while creating /dev/tpm0") try: - run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0") + run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0") except ConsoleError, e: saveLog(console.getHistory()) vtpm_cleanup(domName) diff -r da942e577e5e -r 432f978d1cd1 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py --- a/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py Sun Sep 24 13:10:13 2006 -0600 @@ -43,7 +43,7 @@ except ConsoleError, e: FAIL("Error while creating /dev/tpm0") try: - run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0") + run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0") except ConsoleError, e: saveLog(console.getHistory()) vtpm_cleanup(domName) diff -r da942e577e5e -r 432f978d1cd1 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py --- a/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py Thu Sep 21 15:35:45 2006 -0600 +++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py Sun Sep 24 13:10:13 2006 -0600 @@ -43,7 +43,7 @@ except ConsoleError, e: FAIL("Error while creating /dev/tpm0") try: - run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0") + run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0") except ConsoleError, e: saveLog(console.getHistory()) vtpm_cleanup(domName) diff -r da942e577e5e -r 432f978d1cd1 unmodified_drivers/linux-2.6/mkbuildtree --- a/unmodified_drivers/linux-2.6/mkbuildtree Thu Sep 21 15:35:45 2006 -0600 +++ b/unmodified_drivers/linux-2.6/mkbuildtree Sun Sep 24 13:10:13 2006 -0600 @@ -42,6 +42,12 @@ i[34567]86) ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm ;; +"ia64") + ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm + ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm + ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm + ln -sf ${XL}/include/asm-ia64/maddr.h include/asm + ;; *) echo unknown architecture $uname exit 1 diff -r da942e577e5e -r 432f978d1cd1 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Thu Sep 21 15:35:45 2006 -0600 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sun Sep 24 13:10:13 2006 -0600 @@ -117,6 +117,7 @@ unsigned long alloc_xen_mmio(unsigned lo return addr; } +#ifndef __ia64__ /* Lifted from hvmloader.c */ static int get_hypercall_stubs(void) { @@ -162,6 +163,9 @@ static int get_hypercall_stubs(void) return 0; } +#else /* __ia64__ */ +#define get_hypercall_stubs() (0) +#endif static int __devinit platform_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -207,7 +211,6 @@ static int __devinit platform_pci_init(s if (ret < 0) goto out; - if ((ret = init_xen_info())) goto out; @@ -228,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 da942e577e5e -r 432f978d1cd1 xen/Makefile --- a/xen/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -90,10 +90,9 @@ include/xen/acm_policy.h: echo "#endif") >$@ # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. -include/xen/compile.h: LANG=C include/xen/compile.h: include/xen/compile.h.in - @sed -e 's/@@date@@/$(shell date)/g' \ - -e 's/@@time@@/$(shell date +%T)/g' \ + @sed -e 's/@@date@@/$(shell LC_ALL=C date)/g' \ + -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g' \ -e 's/@@whoami@@/$(shell whoami)/g' \ -e 's/@@domain@@/$(shell ([ -x /bin/dnsdomainname ] && /bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo [unknown]))/g' \ -e 's/@@hostname@@/$(shell hostname)/g' \ @@ -124,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 da942e577e5e -r 432f978d1cd1 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/ia64/xen/mm.c Sun Sep 24 13:10:13 2006 -0600 @@ -1627,13 +1627,6 @@ void put_page_type(struct page_info *pag nx &= ~PGT_validated; } } - else if ( unlikely(((nx & (PGT_pinned | PGT_count_mask)) == - (PGT_pinned | 1)) && - ((nx & PGT_type_mask) != PGT_writable_page)) ) - { - /* Page is now only pinned. Make the back pointer mutable again. */ - nx |= PGT_va_mutable; - } } while ( unlikely((y = cmpxchg_rel(&page->u.inuse.type_info, x, nx)) != x) ); } @@ -1642,6 +1635,8 @@ int get_page_type(struct page_info *page int get_page_type(struct page_info *page, u32 type) { u32 nx, x, y = page->u.inuse.type_info; + + ASSERT(!(type & ~PGT_type_mask)); again: do { @@ -1654,29 +1649,25 @@ int get_page_type(struct page_info *page } else if ( unlikely((x & PGT_count_mask) == 0) ) { - if ( (x & (PGT_type_mask|PGT_va_mask)) != type ) + if ( (x & PGT_type_mask) != type ) { - if ( (x & PGT_type_mask) != (type & PGT_type_mask) ) + /* + * On type change we check to flush stale TLB entries. This + * may be unnecessary (e.g., page was GDT/LDT) but those + * circumstances should be very rare. + */ + cpumask_t mask = + page_get_owner(page)->domain_dirty_cpumask; + tlbflush_filter(mask, page->tlbflush_timestamp); + + if ( unlikely(!cpus_empty(mask)) ) { - /* - * On type change we check to flush stale TLB - * entries. This may be unnecessary (e.g., page - * was GDT/LDT) but those circumstances should be - * very rare. - */ - cpumask_t mask = - page_get_owner(page)->domain_dirty_cpumask; - tlbflush_filter(mask, page->tlbflush_timestamp); - - if ( unlikely(!cpus_empty(mask)) ) - { - perfc_incrc(need_flush_tlb_flush); - flush_tlb_mask(mask); - } + perfc_incrc(need_flush_tlb_flush); + flush_tlb_mask(mask); } /* We lose existing type, back pointer, and validity. */ - nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated); + nx &= ~(PGT_type_mask | PGT_validated); nx |= type; /* No special validation needed for writable pages. */ @@ -1685,46 +1676,22 @@ int get_page_type(struct page_info *page nx |= PGT_validated; } } - else + else if ( unlikely((x & PGT_type_mask) != type) ) { - if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) ) - { - if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) - { - if ( ((x & PGT_type_mask) != PGT_l2_page_table) || - ((type & PGT_type_mask) != PGT_l1_page_table) ) - MEM_LOG("Bad type (saw %08x != exp %08x) " - "for mfn %016lx (pfn %016lx)", - x, type, page_to_mfn(page), - get_gpfn_from_mfn(page_to_mfn(page))); - return 0; - } - else if ( (x & PGT_va_mask) == PGT_va_mutable ) - { - /* The va backpointer is mutable, hence we update it. */ - nx &= ~PGT_va_mask; - nx |= type; /* we know the actual type is correct */ - } - else if ( ((type & PGT_va_mask) != PGT_va_mutable) && - ((type & PGT_va_mask) != (x & PGT_va_mask)) ) - { -#ifdef CONFIG_X86_PAE - /* We use backptr as extra typing. Cannot be unknown. */ - if ( (type & PGT_type_mask) == PGT_l2_page_table ) - return 0; -#endif - /* This table is possibly mapped at multiple locations. */ - nx &= ~PGT_va_mask; - nx |= PGT_va_unknown; - } - } - if ( unlikely(!(x & PGT_validated)) ) - { - /* Someone else is updating validation of this page. Wait... */ - while ( (y = page->u.inuse.type_info) == x ) - cpu_relax(); - goto again; - } + if ( ((x & PGT_type_mask) != PGT_l2_page_table) || + (type != PGT_l1_page_table) ) + MEM_LOG("Bad type (saw %08x != exp %08x) " + "for mfn %016lx (pfn %016lx)", + x, type, page_to_mfn(page), + get_gpfn_from_mfn(page_to_mfn(page))); + return 0; + } + else if ( unlikely(!(x & PGT_validated)) ) + { + /* Someone else is updating validation of this page. Wait... */ + while ( (y = page->u.inuse.type_info) == x ) + cpu_relax(); + goto again; } } while ( unlikely((y = cmpxchg_acq(&page->u.inuse.type_info, x, nx)) != x) ); diff -r da942e577e5e -r 432f978d1cd1 xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/ia64/xen/xensetup.c Sun Sep 24 13:10:13 2006 -0600 @@ -38,7 +38,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 **); diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/0opt.c --- a/xen/arch/powerpc/0opt.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/0opt.c Sun Sep 24 13:10:13 2006 -0600 @@ -19,10 +19,10 @@ */ #include <xen/config.h> -#include <asm/misc.h> +#include <xen/lib.h> extern void __cmpxchg_called_with_bad_pointer(void); void __cmpxchg_called_with_bad_pointer(void) { - trap(); + BUG(); } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/Makefile --- a/xen/arch/powerpc/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -13,7 +13,7 @@ obj-y += dart_u3.o obj-y += dart_u3.o obj-y += dart_u4.o obj-y += delay.o -obj-y += dom0_ops.o +obj-y += domctl.o obj-y += domain_build.o obj-y += domain.o obj-y += exceptions.o @@ -36,6 +36,8 @@ obj-y += setup.o obj-y += setup.o obj-y += shadow.o obj-y += smp.o +obj-y += smp-tbsync.o +obj-y += sysctl.o obj-y += time.o obj-y += usercopy.o diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/backtrace.c --- a/xen/arch/powerpc/backtrace.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/backtrace.c Sun Sep 24 13:10:13 2006 -0600 @@ -191,3 +191,20 @@ void show_backtrace(ulong sp, ulong lr, backtrace(sp, lr, pc); console_end_sync(); } + +void __warn(char *file, int line) +{ + ulong sp; + ulong lr; + + console_start_sync(); + printk("WARN at %s:%d\n", file, line); + + sp = (ulong)__builtin_frame_address(0); + lr = (ulong)__builtin_return_address(0); + + backtrace(sp, lr, lr); + console_end_sync(); +} + + diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/boot_of.c --- a/xen/arch/powerpc/boot_of.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/boot_of.c Sun Sep 24 13:10:13 2006 -0600 @@ -31,6 +31,7 @@ #include <asm/io.h> #include "exceptions.h" #include "of-devtree.h" +#include "oftree.h" /* Secondary processors use this for handshaking with main processor. */ volatile unsigned int __spin_ack; @@ -38,7 +39,6 @@ static ulong of_vec; static ulong of_vec; static ulong of_msr; static int of_out; -static ofdn_t boot_cpu; static char bootargs[256]; #define COMMAND_LINE_SIZE 512 @@ -669,7 +669,7 @@ static int boot_of_fixup_chosen(void *me dn = ofd_node_find(mem, ofpath); if (dn <= 0) of_panic("no node for: %s\n", ofpath); - boot_cpu = dn; + ofd_boot_cpu = dn; val = dn; dn = ofd_node_find(mem, "/chosen"); @@ -681,7 +681,7 @@ static int boot_of_fixup_chosen(void *me } else { of_printf("*** can't find path to booting cpu, " "SMP is disabled\n"); - boot_cpu = -1; + ofd_boot_cpu = -1; } } return rc; @@ -773,7 +773,7 @@ static void __init boot_of_fix_maple(voi } } -static int __init boot_of_serial(void *oftree) +static int __init boot_of_serial(void *oft) { int n; int p; @@ -805,7 +805,7 @@ static int __init boot_of_serial(void *o continue; of_printf("pruning `%s' from devtree\n", buf); - rc = ofd_prune_path(oftree, buf); + rc = ofd_prune_path(oft, buf); if (rc < 0) of_panic("prune of `%s' failed\n", buf); } @@ -858,8 +858,8 @@ static void boot_of_module(ulong r3, ulo static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) { static module_t mods[3]; - void *oftree; - ulong oftree_sz = 48 * PAGE_SIZE; + void *oft; + ulong oft_sz = 48 * PAGE_SIZE; ulong mod0_start; ulong mod0_size; static const char sepr[] = " -- "; @@ -922,28 +922,28 @@ static void boot_of_module(ulong r3, ulo } /* snapshot the tree */ - oftree = (void*)find_space(oftree_sz, PAGE_SIZE, mbi); - if (oftree == 0) + oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi); + if (oft == 0) of_panic("Could not allocate OFD tree\n"); - of_printf("creating oftree\n"); + of_printf("creating oft\n"); of_test("package-to-path"); - oftree = ofd_create(oftree, oftree_sz); - pkg_save(oftree); - - if (ofd_size(oftree) > oftree_sz) + oft = ofd_create(oft, oft_sz); + pkg_save(oft); + + if (ofd_size(oft) > oft_sz) of_panic("Could not fit all of native devtree\n"); - boot_of_fixup_refs(oftree); - boot_of_fixup_chosen(oftree); - - if (ofd_size(oftree) > oftree_sz) + boot_of_fixup_refs(oft); + boot_of_fixup_chosen(oft); + + if (ofd_size(oft) > oft_sz) of_panic("Could not fit all devtree fixups\n"); - ofd_walk(oftree, OFD_ROOT, /* add_hype_props */ NULL, 2); - - mods[1].mod_start = (ulong)oftree; - mods[1].mod_end = mods[1].mod_start + oftree_sz; + ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2); + + mods[1].mod_start = (ulong)oft; + mods[1].mod_end = mods[1].mod_start + oft_sz; of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__, mods[1].mod_start, mods[1].mod_end); @@ -952,26 +952,36 @@ static void boot_of_module(ulong r3, ulo mbi->mods_count = 2; mbi->mods_addr = (u32)mods; - boot_of_serial(oftree); + boot_of_serial(oft); } static int __init boot_of_cpus(void) { - int cpus; - int cpu, bootcpu, logical; + int cpus_node; + int cpu_node, bootcpu_node, logical; int result; + s32 cpuid; u32 cpu_clock[2]; - - cpus = of_finddevice("/cpus"); - cpu = of_getchild(cpus); - result = of_getprop(cpu, "timebase-frequency", &timebase_freq, + extern uint cpu_hard_id[NR_CPUS]; + + /* Look up which CPU we are running on right now and get all info + * from there */ + result = of_getprop(bof_chosen, "cpu", + &bootcpu_node, sizeof (bootcpu_node)); + if (result == OF_FAILURE) + of_panic("Failed to look up boot cpu\n"); + + cpu_node = bootcpu_node; + + result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq, sizeof(timebase_freq)); if (result == OF_FAILURE) { of_panic("Couldn't get timebase frequency!\n"); } of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq); - result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock)); + result = of_getprop(cpu_node, "clock-frequency", + &cpu_clock, sizeof(cpu_clock)); if (result == OF_FAILURE || (result !=4 && result != 8)) { of_panic("Couldn't get clock frequency!\n"); } @@ -983,69 +993,79 @@ static int __init boot_of_cpus(void) cpu_khz /= 1000; of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz); - /* Look up which CPU we are running on right now. */ - result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu)); - if (result == OF_FAILURE) - of_panic("Failed to look up boot cpu\n"); - - cpu = of_getpeer(cpu); - - /* We want a continuous logical cpu number space. */ + /* We want a continuous logical cpu number space and we'll make + * the booting CPU logical 0. */ cpu_set(0, cpu_present_map); cpu_set(0, cpu_online_map); cpu_set(0, cpu_possible_map); - /* Spin up all CPUS, even if there are more than NR_CPUS, because - * Open Firmware has them spinning on cache lines which will - * eventually be scrubbed, which could lead to random CPU activation. + result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); + cpu_hard_id[0] = cpuid; + + /* Spin up all CPUS, even if there are more than NR_CPUS or we are + * runnign nosmp, because Open Firmware has them spinning on cache + * lines which will eventually be scrubbed, which could lead to + * random CPU activation. */ - for (logical = 1; cpu > 0; logical++) { - unsigned int cpuid, ping, pong; + + /* Find the base of the multi-CPU package node */ + cpus_node = of_finddevice("/cpus"); + if (cpus_node <= 0) { + of_printf("Single Processor System\n"); + return 1; + } + /* Start with the first child */ + cpu_node = of_getchild(cpus_node); + + for (logical = 1; cpu_node > 0; logical++) { + unsigned int ping, pong; unsigned long now, then, timeout; - - if (cpu == bootcpu) { - of_printf("skipping boot cpu!\n"); - continue; - } - - result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); - if (result == OF_FAILURE) - of_panic("cpuid lookup failed\n"); - - of_printf("spinning up secondary processor #%d: ", logical); - - __spin_ack = ~0x0; - ping = __spin_ack; - pong = __spin_ack; - of_printf("ping = 0x%x: ", ping); - - mb(); - result = of_start_cpu(cpu, (ulong)spin_start, logical); - if (result == OF_FAILURE) - of_panic("start cpu failed\n"); - - /* We will give the secondary processor five seconds to reply. */ - then = mftb(); - timeout = then + (5 * timebase_freq); - - do { - now = mftb(); - if (now >= timeout) { - of_printf("BROKEN: "); - break; + + if (cpu_node == bootcpu_node) { + /* same CPU as boot CPU shich we have already made 0 so + * reduce the logical count */ + --logical; + } else { + result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); + if (result == OF_FAILURE) + of_panic("cpuid lookup failed\n"); + + cpu_hard_id[logical] = cpuid; + + of_printf("spinning up secondary processor #%d: ", logical); + + __spin_ack = ~0x0; + ping = __spin_ack; + pong = __spin_ack; + of_printf("ping = 0x%x: ", ping); + + mb(); + result = of_start_cpu(cpu_node, (ulong)spin_start, logical); + if (result == OF_FAILURE) + of_panic("start cpu failed\n"); + + /* We will give the secondary processor five seconds to reply. */ + then = mftb(); + timeout = then + (5 * timebase_freq); + + do { + now = mftb(); + if (now >= timeout) { + of_printf("BROKEN: "); + break; + } + + mb(); + pong = __spin_ack; + } while (pong == ping); + of_printf("pong = 0x%x\n", pong); + + if (pong != ping) { + cpu_set(logical, cpu_present_map); + cpu_set(logical, cpu_possible_map); } - - mb(); - pong = __spin_ack; - } while (pong == ping); - of_printf("pong = 0x%x\n", pong); - - if (pong != ping) { - cpu_set(logical, cpu_present_map); - cpu_set(logical, cpu_possible_map); - } - - cpu = of_getpeer(cpu); + } + cpu_node = of_getpeer(cpu_node); } return 1; } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/dart.c --- a/xen/arch/powerpc/dart.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/dart.c Sun Sep 24 13:10:13 2006 -0600 @@ -114,7 +114,7 @@ static void dart_fill(ulong index, int p ++rpg; if (i == num_pg) break; - if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) { + if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) { last_flush = (ulong)&entry[i - 1]; dcbst(last_flush); } @@ -134,7 +134,7 @@ static void dart_clear(ulong index, ulon ++i; if (i == num_pg) break; - if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) { + if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) { last_flush = (ulong)&entry[i - 1]; dcbst(last_flush); } @@ -207,16 +207,17 @@ static int find_dart(struct dart_info *d if (rc <= 0) return -1; + if (ofd_strstr(compat, rc, "u4")) + di->di_model = DART_U4; + else if (ofd_strstr(compat, rc, "u3")) + di->di_model = DART_U3; + else { + DBG("%s: not a U3 or U4\n", __func__); + return -1; + } + di->di_base = DART_DEF_BASE; - if (strstr(compat, "u3")) { - di->di_model = DART_U3; - } else if (strstr(compat, "u4")) { - di->di_model = DART_U4; - } else { - DBG("%s: not a U3 or U4\n", __func__); - return -1; - } /* FIXME: this should actually be the HT reg value */ di->di_window.dw_liobn = 0; di->di_window.dw_base_hi = 0; @@ -263,7 +264,7 @@ static int init_dart(void) /* Linux uses a dummy page, filling "empty" DART entries with a reference to this page to capture stray DMA's */ dummy_page = (ulong)alloc_xenheap_pages(1); - memset((void *)dummy_page, 0, PAGE_SIZE); + clear_page((void *)dummy_page); dummy_page >>= PAGE_SHIFT; printk("Initializing DART 0x%lx: tbl: %p[0x%lx] entries: 0x%lx\n", diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/domain.c Sun Sep 24 13:10:13 2006 -0600 @@ -29,11 +29,10 @@ #include <xen/shutdown.h> #include <xen/shadow.h> #include <xen/mm.h> +#include <xen/softirq.h> #include <asm/htab.h> #include <asm/current.h> #include <asm/hcalls.h> - -extern void idle_loop(void); #define next_arg(fmt, args) ({ \ unsigned long __arg; \ @@ -47,6 +46,7 @@ extern void idle_loop(void); } \ __arg; \ }) +extern void idle_loop(void); unsigned long hypercall_create_continuation(unsigned int op, const char *format, ...) @@ -75,31 +75,12 @@ unsigned long hypercall_create_continuat int arch_domain_create(struct domain *d) { - unsigned long rma_base; - unsigned long rma_sz; - uint rma_order_pages; - int rc; - if (d->domain_id == IDLE_DOMAIN_ID) { d->shared_info = (void *)alloc_xenheap_page(); clear_page(d->shared_info); return 0; } - - /* allocate the real mode area */ - rma_order_pages = cpu_default_rma_order_pages(); - d->max_pages = 1UL << rma_order_pages; - d->tot_pages = 0; - - rc = allocate_rma(d, rma_order_pages); - if (rc) - return rc; - rma_base = page_to_maddr(d->arch.rma_page); - rma_sz = rma_size(rma_order_pages); - - d->shared_info = (shared_info_t *) - (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); d->arch.large_page_sizes = cpu_large_page_orders( d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order)); @@ -198,7 +179,6 @@ void dump_pageframe_info(struct domain * } } - void context_switch(struct vcpu *prev, struct vcpu *next) { struct cpu_user_regs *stack_regs = guest_cpu_user_regs(); @@ -262,12 +242,73 @@ void sync_vcpu_execstate(struct vcpu *v) return; } +static void relinquish_memory(struct domain *d, struct list_head *list) +{ + struct list_head *ent; + struct page_info *page; + + /* Use a recursive lock, as we may enter 'free_domheap_page'. */ + spin_lock_recursive(&d->page_alloc_lock); + + ent = list->next; + while ( ent != list ) + { + page = list_entry(ent, struct page_info, list); + + /* Grab a reference to the page so it won't disappear from under us. */ + if ( unlikely(!get_page(page, d)) ) + { + /* Couldn't get a reference -- someone is freeing this page. */ + ent = ent->next; + continue; + } + if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) + put_page_and_type(page); + + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) + put_page(page); + + /* Follow the list chain and /then/ potentially free the page. */ + ent = ent->next; + put_page(page); + } + spin_unlock_recursive(&d->page_alloc_lock); +} + void domain_relinquish_resources(struct domain *d) { - free_domheap_pages(d->arch.rma_page, d->arch.rma_order); + relinquish_memory(d, &d->page_list); free_extents(d); + return; } void arch_dump_domain_info(struct domain *d) { } + +extern void sleep(void); +static void safe_halt(void) +{ + int cpu = smp_processor_id(); + + while (!softirq_pending(cpu)) + sleep(); +} + +static void default_idle(void) +{ + local_irq_disable(); + if ( !softirq_pending(smp_processor_id()) ) + safe_halt(); + else + local_irq_enable(); +} + +void idle_loop(void) +{ + for ( ; ; ) { + page_scrub_schedule_work(); + default_idle(); + do_softirq(); + } +} diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/elf32.c --- a/xen/arch/powerpc/elf32.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/elf32.c Sun Sep 24 13:10:13 2006 -0600 @@ -1,5 +1,7 @@ #define parseelfimage parseelfimage_32 #define loadelfimage loadelfimage_32 +#define xen_elfnote_string xen_elfnote_string32 +#define xen_elfnote_numeric xen_elfnote_numeric32 #define ELFSIZE 32 #include "../../common/elf.c" diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/exceptions.c --- a/xen/arch/powerpc/exceptions.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/exceptions.c Sun Sep 24 13:10:13 2006 -0600 @@ -16,6 +16,7 @@ * Copyright (C) IBM Corp. 2005, 2006 * * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> + * Jimi Xenidis <jimix@xxxxxxxxxxxxxx> */ #include <xen/config.h> @@ -23,11 +24,11 @@ #include <xen/sched.h> #include <xen/serial.h> #include <xen/gdbstub.h> -#include <public/xen.h> +#include <xen/console.h> #include <asm/time.h> +#include <asm/processor.h> #undef DEBUG -#define HDEC_PREEMPT extern ulong ppc_do_softirq(ulong orig_msr); extern void do_timer(struct cpu_user_regs *regs); @@ -38,31 +39,10 @@ int hdec_sample = 0; void do_timer(struct cpu_user_regs *regs) { - /* XXX this is just here to keep HDEC from firing until - * reprogram_ac_timer() sets the proper next-tick time */ - mthdec(timebase_freq); - -#ifdef HDEC_PREEMPT + /* Set HDEC high so it stops firing and can be reprogrammed by + * set_preempt() */ + mthdec(INT_MAX); raise_softirq(TIMER_SOFTIRQ); -#endif -#ifdef DEBUG - { - int d; - if (regs->msr & MSR_HV) { - d = -1; - } else { - d = get_current()->domain->domain_id; - } - extern char serial_getc_nb(int handle); - if (0 && serial_getc_nb(0) > 0) { - printk("H: pc: 0x%lx lr: 0x%lx \n", regs->pc, regs->lr); - } - if (hdec_sample) { - printk("H: pc: 0x%lx lr: 0x%lx \n", regs->pc, regs->lr); - hdec_sample = 0; - } - } -#endif } void do_dec(struct cpu_user_regs *regs) @@ -79,11 +59,22 @@ void program_exception(struct cpu_user_r #ifdef CRASH_DEBUG __trap_to_gdb(regs, cookie); #else /* CRASH_DEBUG */ + int recover = 0; + + console_start_sync(); + show_registers(regs); printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr()); printk("hid4 0x%016lx\n", regs->hid4); printk("---[ backtrace ]---\n"); show_backtrace(regs->gprs[1], regs->lr, regs->pc); - panic("%s: 0x%lx\n", __func__, cookie); + + if (cookie == 0x200) + recover = cpu_machinecheck(regs); + + if (!recover) + panic("%s: 0x%lx\n", __func__, cookie); + + console_end_sync(); #endif /* CRASH_DEBUG */ } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/exceptions.h --- a/xen/arch/powerpc/exceptions.h Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/exceptions.h Sun Sep 24 13:10:13 2006 -0600 @@ -51,4 +51,5 @@ extern char exception_vectors[]; extern char exception_vectors[]; extern char exception_vectors_end[]; extern int spin_start[]; +extern int secondary_cpu_init(int cpuid, unsigned long r4); #endif diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/external.c --- a/xen/arch/powerpc/external.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/external.c Sun Sep 24 13:10:13 2006 -0600 @@ -75,6 +75,7 @@ void do_external(struct cpu_user_regs *r void do_external(struct cpu_user_regs *regs) { int vec; + static unsigned spur_count; BUG_ON(!(regs->msr & MSR_EE)); BUG_ON(mfmsr() & MSR_EE); @@ -87,6 +88,14 @@ void do_external(struct cpu_user_regs *r do_IRQ(regs); BUG_ON(mfmsr() & MSR_EE); + spur_count = 0; + } else { + ++spur_count; + if (spur_count > 100) + panic("Too many (%d) spurrious interrupts in a row\n" + " Known problem, please halt and let machine idle/cool " + " then reboot\n", + 100); } } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/hcalls.c --- a/xen/arch/powerpc/hcalls.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/hcalls.c Sun Sep 24 13:10:13 2006 -0600 @@ -112,9 +112,8 @@ static void do_ni_papr_hypercall(struct { struct vcpu *v = get_current(); - printk("unsupported hcall 0x%lx was called by dom0x%x\n", + printk("unsupported PAPR hcall 0x%lx was called by dom0x%x\n", regs->gprs[3], v->domain->domain_id); - debugger_trap_immediate(); regs->gprs[3] = H_Parameter; } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/iommu.c --- a/xen/arch/powerpc/iommu.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/iommu.c Sun Sep 24 13:10:13 2006 -0600 @@ -52,7 +52,7 @@ int iommu_put(u32 buid, ulong ioba, unio pfn = tce.tce_bits.tce_rpn; mfn = pfn2mfn(d, pfn, &mtype); - if (mfn > 0) { + if (mfn != INVALID_MFN) { #ifdef DEBUG printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__, ioba, pfn, mfn); diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/mm.c --- a/xen/arch/powerpc/mm.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/mm.c Sun Sep 24 13:10:13 2006 -0600 @@ -39,7 +39,6 @@ /* Frame table and its size in pages. */ struct page_info *frame_table; -unsigned long frame_table_size; unsigned long max_page; unsigned long total_pages; @@ -87,12 +86,6 @@ void put_page_type(struct page_info *pag /* Record TLB information for flush later. */ page->tlbflush_timestamp = tlbflush_current_time(); } - else if ( unlikely((nx & (PGT_pinned|PGT_type_mask|PGT_count_mask)) == - (PGT_pinned | 1)) ) - { - /* Page is now only pinned. Make the back pointer mutable again. */ - nx |= PGT_va_mutable; - } } while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) ); } @@ -101,6 +94,8 @@ int get_page_type(struct page_info *page int get_page_type(struct page_info *page, unsigned long type) { unsigned long nx, x, y = page->u.inuse.type_info; + + ASSERT(!(type & ~PGT_type_mask)); again: do { @@ -113,29 +108,25 @@ int get_page_type(struct page_info *page } else if ( unlikely((x & PGT_count_mask) == 0) ) { - if ( (x & (PGT_type_mask|PGT_va_mask)) != type ) + if ( (x & PGT_type_mask) != type ) { - if ( (x & PGT_type_mask) != (type & PGT_type_mask) ) + /* + * On type change we check to flush stale TLB entries. This + * may be unnecessary (e.g., page was GDT/LDT) but those + * circumstances should be very rare. + */ + cpumask_t mask = + page_get_owner(page)->domain_dirty_cpumask; + tlbflush_filter(mask, page->tlbflush_timestamp); + + if ( unlikely(!cpus_empty(mask)) ) { - /* - * On type change we check to flush stale TLB - * entries. This may be unnecessary (e.g., page - * was GDT/LDT) but those circumstances should be - * very rare. - */ - cpumask_t mask = - page_get_owner(page)->domain_dirty_cpumask; - tlbflush_filter(mask, page->tlbflush_timestamp); - - if ( unlikely(!cpus_empty(mask)) ) - { - perfc_incrc(need_flush_tlb_flush); - flush_tlb_mask(mask); - } + perfc_incrc(need_flush_tlb_flush); + flush_tlb_mask(mask); } /* We lose existing type, back pointer, and validity. */ - nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated); + nx &= ~(PGT_type_mask | PGT_validated); nx |= type; /* No special validation needed for writable pages. */ @@ -144,36 +135,16 @@ int get_page_type(struct page_info *page nx |= PGT_validated; } } - else - { - if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) ) - { - if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) - { - return 0; - } - else if ( (x & PGT_va_mask) == PGT_va_mutable ) - { - /* The va backpointer is mutable, hence we update it. */ - nx &= ~PGT_va_mask; - nx |= type; /* we know the actual type is correct */ - } - else if ( (type & PGT_va_mask) != PGT_va_mutable ) - { - ASSERT((type & PGT_va_mask) != (x & PGT_va_mask)); - - /* This table is possibly mapped at multiple locations. */ - nx &= ~PGT_va_mask; - nx |= PGT_va_unknown; - } - } - if ( unlikely(!(x & PGT_validated)) ) - { - /* Someone else is updating validation of this page. Wait... */ - while ( (y = page->u.inuse.type_info) == x ) - cpu_relax(); - goto again; - } + else if ( unlikely((x & PGT_type_mask) != type) ) + { + return 0; + } + if ( unlikely(!(x & PGT_validated)) ) + { + /* Someone else is updating validation of this page. Wait... */ + while ( (y = page->u.inuse.type_info) == x ) + cpu_relax(); + goto again; } } while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) ); @@ -190,33 +161,26 @@ void __init init_frametable(void) void __init init_frametable(void) { unsigned long p; - - frame_table_size = PFN_UP(max_page * sizeof(struct page_info)); - - p = alloc_boot_pages(min(frame_table_size, 4UL << 20), 1); + unsigned long nr_pages; + int i; + + nr_pages = PFN_UP(max_page * sizeof(struct page_info)); + nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT))); + + + p = alloc_boot_pages(nr_pages, 1); if (p == 0) panic("Not enough memory for frame table\n"); frame_table = (struct page_info *)(p << PAGE_SHIFT); - frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK; - - memset(frame_table, 0, frame_table_size); + for (i = 0; i < nr_pages; i += 1) + clear_page((void *)((p + i) << PAGE_SHIFT)); } long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) { printk("%s: no PPC specific memory ops\n", __func__); return -ENOSYS; -} - -void clear_page(void *page) -{ - if (on_mambo()) { - extern void *mambo_memset(void *,int ,__kernel_size_t); - mambo_memset(page, 0, PAGE_SIZE); - } else { - memset(page, 0, PAGE_SIZE); - } } extern void copy_page(void *dp, void *sp) @@ -227,16 +191,6 @@ extern void copy_page(void *dp, void *sp } else { memcpy(dp, sp, PAGE_SIZE); } -} - -static int mfn_in_hole(ulong mfn) -{ - /* totally cheating */ - if (mfn >= (0xf0000000UL >> PAGE_SHIFT) && - mfn < (((1UL << 32) - 1) >> PAGE_SHIFT)) - return 1; - - return 0; } static uint add_extent(struct domain *d, struct page_info *pg, uint order) @@ -301,70 +255,119 @@ uint allocate_extents(struct domain *d, return total_nrpages; } - -int allocate_rma(struct domain *d, unsigned int order_pages) -{ + +int allocate_rma(struct domain *d, unsigned int order) +{ + struct vcpu *v; ulong rma_base; - ulong rma_sz = rma_size(order_pages); - - d->arch.rma_page = alloc_domheap_pages(d, order_pages, 0); + ulong rma_sz; + int i; + + if (d->arch.rma_page) + return -EINVAL; + + d->arch.rma_page = alloc_domheap_pages(d, order, 0); if (d->arch.rma_page == NULL) { - DPRINTK("Could not allocate order_pages=%d RMA for domain %u\n", - order_pages, d->domain_id); + DPRINTK("Could not allocate order=%d RMA for domain %u\n", + order, d->domain_id); return -ENOMEM; } - d->arch.rma_order = order_pages; + d->arch.rma_order = order; rma_base = page_to_maddr(d->arch.rma_page); + rma_sz = rma_size(d->arch.rma_order); + BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */ - /* XXX */ - printk("clearing RMA: 0x%lx[0x%lx]\n", rma_base, rma_sz); - memset((void *)rma_base, 0, rma_sz); + printk("allocated RMA for Dom[%d]: 0x%lx[0x%lx]\n", + d->domain_id, rma_base, rma_sz); + + for (i = 0; i < (1 << d->arch.rma_order); i++ ) { + /* Add in any extra CPUs that need flushing because of this page. */ + d->arch.rma_page[i].count_info |= PGC_page_RMA; + clear_page((void *)page_to_maddr(&d->arch.rma_page[i])); + } + + d->shared_info = (shared_info_t *) + (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); + + /* if there are already running vcpus, adjust v->vcpu_info */ + /* XXX untested */ + for_each_vcpu(d, v) { + v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; + } return 0; } - -ulong pfn2mfn(struct domain *d, long pfn, int *type) +void free_rma_check(struct page_info *page) +{ + if (test_bit(_PGC_page_RMA, &page->count_info) && + !test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) + panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page)); +} + + +ulong pfn2mfn(struct domain *d, ulong pfn, int *type) { ulong rma_base_mfn = page_to_mfn(d->arch.rma_page); ulong rma_size_mfn = 1UL << d->arch.rma_order; struct page_extents *pe; - - if (pfn < rma_size_mfn) { - if (type) - *type = PFN_TYPE_RMA; - return pfn + rma_base_mfn; - } - + ulong mfn = INVALID_MFN; + int t = PFN_TYPE_NONE; + + /* quick tests first */ if (test_bit(_DOMF_privileged, &d->domain_flags) && - mfn_in_hole(pfn)) { - if (type) - *type = PFN_TYPE_IO; - return pfn; - } - - /* quick tests first */ - list_for_each_entry (pe, &d->arch.extent_list, pe_list) { - uint end_pfn = pe->pfn + (1 << pe->order); - - if (pfn >= pe->pfn && pfn < end_pfn) { - if (type) - *type = PFN_TYPE_LOGICAL; - return page_to_mfn(pe->pg) + (pfn - pe->pfn); - } - } - - /* This hack allows dom0 to map all memory, necessary to - * initialize domU state. */ - if (test_bit(_DOMF_privileged, &d->domain_flags)) { - if (type) - *type = PFN_TYPE_REMOTE; - return pfn; - } - - BUG(); - return 0; + cpu_io_mfn(pfn)) { + t = PFN_TYPE_IO; + mfn = pfn; + } else { + if (pfn < rma_size_mfn) { + t = PFN_TYPE_RMA; + mfn = pfn + rma_base_mfn; + } else { + list_for_each_entry (pe, &d->arch.extent_list, pe_list) { + uint end_pfn = pe->pfn + (1 << pe->order); + + if (pfn >= pe->pfn && pfn < end_pfn) { + t = PFN_TYPE_LOGICAL; + mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn); + break; + } + } + } + BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d); + } + + if (t == PFN_TYPE_NONE) { + /* This hack allows dom0 to map all memory, necessary to + * initialize domU state. */ + if (test_bit(_DOMF_privileged, &d->domain_flags) && + mfn_valid(pfn)) { + struct page_info *pg; + + /* page better be allocated to some domain but not the caller */ + pg = mfn_to_page(pfn); + if (!(pg->count_info & PGC_allocated)) + panic("Foreign page: 0x%lx is not owned by any domain\n", + mfn); + if (page_get_owner(pg) == d) + panic("Foreign page: 0x%lx is owned by this domain\n", + mfn); + + t = PFN_TYPE_FOREIGN; + mfn = pfn; + } + } + + if (mfn == INVALID_MFN) { + printk("%s: Dom[%d] pfn 0x%lx is not a valid page\n", + __func__, d->domain_id, pfn); + } + + if (type) + *type = t; + + return mfn; } void guest_physmap_add_page( diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/mpic_init.c --- a/xen/arch/powerpc/mpic_init.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/mpic_init.c Sun Sep 24 13:10:13 2006 -0600 @@ -27,6 +27,8 @@ #include "of-devtree.h" #undef DEBUG +#define CONFIG_SHARE_MPIC + #ifdef DEBUG #define DBG(fmt...) printk(fmt) #else @@ -319,7 +321,42 @@ static int find_mpic(void) return rc; } +#ifdef CONFIG_SHARE_MPIC static struct hw_interrupt_type hc_irq; + +static struct hw_interrupt_type *share_mpic( + struct hw_interrupt_type *mpic_irq, + struct hw_interrupt_type *xen_irq) +{ + hc_irq.startup = mpic_irq->startup; + mpic_irq->startup = xen_irq->startup; + + hc_irq.enable = mpic_irq->enable; + mpic_irq->enable = xen_irq->enable; + + hc_irq.disable = mpic_irq->disable; + mpic_irq->disable = xen_irq->disable; + + hc_irq.shutdown = mpic_irq->shutdown; + mpic_irq->shutdown = xen_irq->shutdown; + + hc_irq.ack = mpic_irq->ack; + mpic_irq->ack = xen_irq->ack; + + hc_irq.end = mpic_irq->end; + mpic_irq->end = xen_irq->end; + + hc_irq.set_affinity = mpic_irq->set_affinity; + mpic_irq->set_affinity = xen_irq->set_affinity; + + return &hc_irq; +} + +#else /* CONFIG_SHARE_MPIC */ + +#define share_mpic(M,X) (M) + +#endif struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq) { @@ -329,6 +366,7 @@ struct hw_interrupt_type *xen_mpic_init( unsigned int ipi_offset; unsigned char *senses; unsigned int senses_count; + struct hw_interrupt_type *hit; printk("%s: start\n", __func__); @@ -356,29 +394,10 @@ struct hw_interrupt_type *xen_mpic_init( BUG_ON(mpic == NULL); mpic_init(mpic); - hc_irq.startup = mpic->hc_irq.startup; - mpic->hc_irq.startup = xen_irq->startup; - - hc_irq.enable = mpic->hc_irq.enable; - mpic->hc_irq.enable = xen_irq->enable; - - hc_irq.disable = mpic->hc_irq.disable; - mpic->hc_irq.disable = xen_irq->disable; - - hc_irq.shutdown = mpic->hc_irq.shutdown; - mpic->hc_irq.shutdown = xen_irq->shutdown; - - hc_irq.ack = mpic->hc_irq.ack; - mpic->hc_irq.ack = xen_irq->ack; - - hc_irq.end = mpic->hc_irq.end; - mpic->hc_irq.end = xen_irq->end; - - hc_irq.set_affinity = mpic->hc_irq.set_affinity; - mpic->hc_irq.set_affinity = xen_irq->set_affinity; + hit = share_mpic(&mpic->hc_irq, xen_irq); printk("%s: success\n", __func__); - return &hc_irq; + return hit; } int xen_mpic_get_irq(struct cpu_user_regs *regs) diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/of-devtree.h --- a/xen/arch/powerpc/of-devtree.h Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/of-devtree.h Sun Sep 24 13:10:13 2006 -0600 @@ -22,6 +22,7 @@ #define _OF_DEVTREE_H #include <xen/types.h> +#include <xen/string.h> #include <public/xen.h> enum { @@ -136,4 +137,20 @@ extern ofdn_t ofd_node_find_prev(void *m extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n); extern void ofd_init(int (*write)(const char *, size_t len)); +static inline int ofd_strstr(const char *s, int len, const char *str) +{ + int l = strlen(str); + do { + int n; + + if (len >= l && strstr(s, str)) + return 1; + + n = strnlen(s, len) + 1; + len -= strnlen(s, len) + 1; + s += n; + } while (len > 0); + return 0; +} + #endif /* _OF_DEVTREE_H */ diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/of_handler/xencomm.c --- a/xen/arch/powerpc/of_handler/xencomm.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/of_handler/xencomm.c Sun Sep 24 13:10:13 2006 -0600 @@ -50,18 +50,18 @@ static void *__xencomm_alloc_mini(void * static void *__xencomm_alloc_mini(void *area, int arealen) { unsigned long base = (unsigned long)area; - unsigned int pageoffset; + unsigned int left_in_page; - pageoffset = base % PAGE_SIZE; + left_in_page = PAGE_SIZE - base % PAGE_SIZE; /* we probably fit right at the front of area */ - if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini)) { + if (left_in_page >= sizeof(struct xencomm_mini)) { return area; } /* if not, see if area is big enough to advance to the next page */ - if ((arealen - pageoffset) >= sizeof(struct xencomm_mini)) - return (void *)(base + pageoffset); + if ((arealen - left_in_page) >= sizeof(struct xencomm_mini)) + return (void *)(base + left_in_page); /* area was too small */ return NULL; diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/ofd_fixup.c --- a/xen/arch/powerpc/ofd_fixup.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/ofd_fixup.c Sun Sep 24 13:10:13 2006 -0600 @@ -28,6 +28,8 @@ #undef RTAS +ofdn_t ofd_boot_cpu; + #ifdef PAPR_VTERM static ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d) { @@ -172,24 +174,21 @@ static ofdn_t ofd_cpus_props(void *m, st #endif c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu)); + if (ofd_boot_cpu == -1) + ofd_boot_cpu = c; while (c > 0) { - ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE; - ofd_prop_add(m, c, "ibm,pft-size", - ibm_pft_size, sizeof (ibm_pft_size)); - - /* FIXME: Check the the "l2-cache" property who's - * contents is an orphaned phandle? */ + /* Since we are not MP yet we prune all but the booting cpu */ + if (c == ofd_boot_cpu) { + ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE; + ofd_prop_add(m, c, "ibm,pft-size", + ibm_pft_size, sizeof (ibm_pft_size)); + + /* FIXME: Check the the "l2-cache" property who's + * contents is an orphaned phandle? */ + } else + ofd_node_prune(m, c); + c = ofd_node_find_next(m, c); - - /* Since we are not MP yet we can prune the rest of the CPUs */ - while (c > 0) { - ofdn_t nc; - - nc = ofd_node_find_next(m, c); - ofd_node_prune(m, c); - - c = nc; - } } return n; diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/oftree.h --- a/xen/arch/powerpc/oftree.h Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/oftree.h Sun Sep 24 13:10:13 2006 -0600 @@ -21,10 +21,12 @@ #ifndef _OFTREE_H #define _OFTREE_H #include <xen/multiboot.h> +#include "of-devtree.h" extern ulong oftree; extern ulong oftree_len; extern ulong oftree_end; +extern ofdn_t ofd_boot_cpu; extern int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si); extern void ofd_memory_props(void *m, struct domain *d); diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/papr/xlate.c --- a/xen/arch/powerpc/papr/xlate.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/papr/xlate.c Sun Sep 24 13:10:13 2006 -0600 @@ -118,11 +118,14 @@ static void h_enter(struct cpu_user_regs int pgshift = PAGE_SHIFT; ulong idx; int limit = 0; /* how many PTEs to examine in the PTEG */ - ulong lpn; - ulong rpn; + ulong pfn; + ulong mfn; struct vcpu *v = get_current(); struct domain *d = v->domain; int mtype; + struct page_info *pg = NULL; + struct domain *f = NULL; + htab = &d->arch.htab; if (ptex > (1UL << htab->log_num_ptes)) { @@ -160,17 +163,21 @@ static void h_enter(struct cpu_user_regs /* get the correct logical RPN in terms of 4K pages need to mask * off lp bits and unused arpn bits if this is a large page */ - lpn = ~0ULL << (pgshift - PAGE_SHIFT); - lpn = pte.bits.rpn & lpn; - - rpn = pfn2mfn(d, lpn, &mtype); + pfn = ~0ULL << (pgshift - PAGE_SHIFT); + pfn = pte.bits.rpn & pfn; + + mfn = pfn2mfn(d, pfn, &mtype); + if (mfn == INVALID_MFN) { + regs->gprs[3] = H_Parameter; + return; + } if (mtype == PFN_TYPE_IO) { /* only a privilaged dom can access outside IO space */ if ( !test_bit(_DOMF_privileged, &d->domain_flags) ) { regs->gprs[3] = H_Privilege; - printk("%s: unprivileged access to logical page: 0x%lx\n", - __func__, lpn); + printk("%s: unprivileged access to physical page: 0x%lx\n", + __func__, pfn); return; } @@ -188,7 +195,7 @@ static void h_enter(struct cpu_user_regs } } /* fixup the RPN field of our local PTE copy */ - pte.bits.rpn = rpn | lp_bits; + pte.bits.rpn = mfn | lp_bits; /* clear reserved bits in high word */ pte.bits.lock = 0x0; @@ -199,20 +206,44 @@ static void h_enter(struct cpu_user_regs pte.bits.ts = 0x0; pte.bits.res2 = 0x0; + if (mtype == PFN_TYPE_FOREIGN) { + pg = mfn_to_page(mfn); + f = page_get_owner(pg); + + BUG_ON(f == d); + + if (unlikely(!get_domain(f))) { + regs->gprs[3] = H_Rescinded; + return; + } + if (unlikely(!get_page(pg, f))) { + put_domain(f); + regs->gprs[3] = H_Rescinded; + return; + } + } + if ( !(flags & H_EXACT) ) { /* PTEG (not specific PTE); clear 3 lowest bits */ ptex &= ~0x7UL; limit = 7; } - /* data manipulations should be done prior to the pte insertion. */ + /* data manipulations should be done prior to the pte insertion. */ if ( flags & H_ZERO_PAGE ) { - memset((void *)(rpn << PAGE_SHIFT), 0, 1UL << pgshift); + ulong pg = mfn << PAGE_SHIFT; + ulong pgs = 1UL << pgshift; + + while (pgs > 0) { + clear_page((void *)pg); + pg += PAGE_SIZE; + --pgs; + } } if ( flags & H_ICACHE_INVALIDATE ) { ulong k; - ulong addr = rpn << PAGE_SHIFT; + ulong addr = mfn << PAGE_SHIFT; for (k = 0; k < (1UL << pgshift); k += L1_CACHE_BYTES) { dcbst(addr + k); @@ -225,7 +256,7 @@ static void h_enter(struct cpu_user_regs if ( flags & H_ICACHE_SYNCHRONIZE ) { ulong k; - ulong addr = rpn << PAGE_SHIFT; + ulong addr = mfn << PAGE_SHIFT; for (k = 0; k < (1UL << pgshift); k += L1_CACHE_BYTES) { icbi(addr + k); sync(); @@ -256,6 +287,12 @@ static void h_enter(struct cpu_user_regs /* If the PTEG is full then no additional values are returned. */ printk("%s: PTEG FULL\n", __func__); #endif + + if (pg != NULL) + put_page(pg); + + if (f != NULL) + put_domain(f); regs->gprs[3] = H_PTEG_Full; } @@ -476,9 +513,23 @@ static void h_remove(struct cpu_user_reg /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */ /* XXX - I think the spec should be questioned in this case (MFM) */ - if (pte->bits.v == 0) { + if (lpte.bits.v == 0) { printk("%s: removing invalid entry\n", __func__); } + + if (lpte.bits.v) { + ulong mfn = lpte.bits.rpn; + if (!cpu_io_mfn(mfn)) { + struct page_info *pg = mfn_to_page(mfn); + struct domain *f = page_get_owner(pg); + + if (f != d) { + put_domain(f); + put_page(pg); + } + } + } + asm volatile("eieio; std %1, 0(%0); ptesync" : : "b" (pte), "r" (0) diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/Makefile --- a/xen/arch/powerpc/powerpc64/Makefile Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/Makefile Sun Sep 24 13:10:13 2006 -0600 @@ -6,6 +6,9 @@ obj-y += io.o obj-y += io.o obj-y += memcpy.o obj-y += ppc970.o +obj-y += ppc970_machinecheck.o +obj-y += ppc970_scom.o obj-y += prom_call.o obj-y += string.o obj-y += traps.o + diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/domain.c --- a/xen/arch/powerpc/powerpc64/domain.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/domain.c Sun Sep 24 13:10:13 2006 -0600 @@ -55,29 +55,39 @@ void load_sprs(struct vcpu *v) /* adjust the DEC value to account for cycles while not * running this OS */ timebase_delta = mftb() - v->arch.timebase; - v->arch.dec -= timebase_delta; + if (timebase_delta > v->arch.dec) + v->arch.dec = 0; + else + v->arch.dec -= timebase_delta; } /* XXX evaluate all isyncs in segment code */ -static void flush_slb(struct vcpu *v) +void flush_segments(void) { - struct slb_entry *slb0 = &v->arch.slb_entries[0]; + struct slb_entry slb0; + ulong zero = 0; - slbia(); + __asm__ __volatile__( + "slbmfev %0,%2\n" + "slbmfee %1,%2\n" + :"=&r"(slb0.slb_vsid), "=&r"(slb0.slb_esid) + :"r"(zero) + :"memory"); /* we manually have to invalidate SLB[0] since slbia doesn't. */ /* XXX name magic constants! */ - if (slb0->slb_esid & (1 << (63 - 36))) { + if (slb0.slb_esid & SLB_ESID_VALID) { ulong rb; ulong class; - class = (slb0->slb_vsid >> (63 - 56)) & 1ULL; - rb = slb0->slb_esid & (~0ULL << (63 - 35)); - rb |= class << (63 - 36); + class = !!(slb0.slb_vsid & SLB_ESID_CLASS); + rb = slb0.slb_esid & SLB_ESID_MASK; + rb |= class << SLBIE_CLASS_LOG; slbie(rb); } + slbia(); } void save_segments(struct vcpu *v) @@ -108,7 +118,7 @@ void save_segments(struct vcpu *v) #endif } - flush_slb(v); + flush_segments(); } void load_segments(struct vcpu *v) @@ -123,7 +133,8 @@ void load_segments(struct vcpu *v) /* FIXME: should we bother to restore invalid entries */ /* stuff in the index here */ - esid |= i & ((0x1UL << (63 - 52 + 1)) - 1); + esid &= ~SLBMTE_ENTRY_MASK; + esid |= i; __asm__ __volatile__( "isync\n" @@ -141,3 +152,27 @@ void load_segments(struct vcpu *v) #endif } } + +void dump_segments(int valid) +{ + int i; + + printk("Dump %s SLB entries:\n", valid ? "VALID" : "ALL"); + + /* save all extra SLBs */ + for (i = 0; i < NUM_SLB_ENTRIES; i++) { + ulong vsid; + ulong esid; + + __asm__ __volatile__( + "slbmfev %0,%2\n" + "slbmfee %1,%2\n" + :"=&r"(vsid), "=&r"(esid) + :"r"(i) + :"memory"); + + if (valid && !(esid & SLB_ESID_VALID)) + continue; + printf("S%02d: 0x%016lx 0x%016lx\n", i, vsid, esid); + } +} diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/exceptions.S --- a/xen/arch/powerpc/powerpc64/exceptions.S Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/exceptions.S Sun Sep 24 13:10:13 2006 -0600 @@ -1,27 +1,30 @@ /* - * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * Copyright (C) IBM Corp. 2005, 2006 + * + * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> + * Hollis Blanchard <hollisb@xxxxxxxxxx> */ - + #include <asm/config.h> #include <asm/asm-offsets.h> #include <asm/reg_defs.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/percpu.h> .macro SAVE_GPR regno uregs std \regno, (UREGS_gprs + GPR_WIDTH * \regno)(\uregs) @@ -115,10 +118,13 @@ 1: mfspr r0, SPRN_HSPRG1 std r0, UREGS_r13(r1) /* save R13 from HSPRG1 */ - /* done with processor_area; re-enable MSR:RI */ - mfmsr r0 - ori r0, r0, MSR_RI@l - mtmsrd r0 + /* Only _one_ larx is allowed at a time. Any future use will be + * rejected until the earlier one (if any) completes. Since we + * may have interrupted a larx in the Domain, or Xen we need to + * clear any larx that may currently exist. We could probably + * skip which for hcalls */ + ldx r0, 0, r1 + stdcx. r0, 0, r1 /* save CTR and use it to jump */ mfctr r0 @@ -144,6 +150,13 @@ 1: li r0, -1 /* we clobbered the OS's SRR0/SRR1 to get here. */ std r0, UREGS_srr0(\uregs) std r0, UREGS_srr1(\uregs) + + /* done with processor_area; re-enable MSR:RI */ + mfmsr r0 + ori r0, r0, MSR_RI@l + mtmsrd r0 + + .endm /* For exceptions that use HSRR0/1 (preserving the OS's SRR0/1). */ @@ -164,6 +177,12 @@ 1: std r0, UREGS_srr0(\uregs) mfspr r0, SPRN_SRR1 std r0, UREGS_srr1(\uregs) + + /* done with processor_area; re-enable MSR:RI */ + mfmsr r0 + ori r0, r0, MSR_RI@l + mtmsrd r0 + .endm /* Hypervisor exception handling code; copied to physical address zero. */ @@ -178,6 +197,14 @@ zero: li r0, 0x0 /* exception vector for GDB stub */ bctr + /* The following byte array is where any per-CPU state flags + * that can be be used across interrupts. Currently it is only used + * to track Cache Inhibited Mode when a Machine Check occurs. */ + /* NOTE: This array is indexed by PIR NOT CPUID */ + . = MCK_CPU_STAT_BASE + .space NR_CPUS + . = MCK_GOOD_HID4 + .quad 0 . = 0x100 # System Reset ex_reset: /* XXX thread initialization */ @@ -188,8 +215,19 @@ ex_reset: . = 0x200 # Machine Check ex_machcheck: - GET_STACK r13 SPRN_SRR1 - EXCEPTION_HEAD r13 ex_program_continued + /* Restore HID4 to a known state early, we do not recover from + * machine check yet, but when we do we shoul dbe able to restore + * HID4 to it proper value */ + mtspr SPRN_HSPRG1, r13 + ld r13, MCK_GOOD_HID4(0) + sync + mtspr SPRN_HID4, r13 + isync + /* Hopefully we don't have to worry about the ERAT */ + mfspr r13, SPRN_HSPRG1 + /* and now back to our regularly schedualed program */ + GET_STACK r13 SPRN_SRR1 + EXCEPTION_HEAD r13 ex_machcheck_continued li r0, 0x200 /* exception vector for GDB stub */ bctr @@ -324,6 +362,10 @@ exception_vectors_end: HRFID b . /* prevent speculative icache fetch */ .endm + +/* Not a whole lot just yet */ +ex_machcheck_continued: + /* We enter with the exception number in r0. The EXCEPTION_SAVE_STATE macro * clobbers r0 though, so we have to move it around a little bit. Not ideal, @@ -371,6 +413,7 @@ ex_hcall_continued: mfmsr r14 ori r14, r14, MSR_EE xori r15, r14, MSR_EE + hcall_test_all_events: mtmsrd r15, 1 /* disable interrupts */ ld r3, PAREA_vcpu(r13) diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/io.S --- a/xen/arch/powerpc/powerpc64/io.S Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/io.S Sun Sep 24 13:10:13 2006 -0600 @@ -1,23 +1,27 @@ /* - * Copyright (C) 2005 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) IBM Corp. 2005, 2006 + * + * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> + * Hollis Blanchard <hollisb@xxxxxxxxxx> */ #include <asm/config.h> #include <asm/processor.h> +#include <asm/percpu.h> /* Xen runs in real mode (i.e. untranslated, MMU disabled). This avoids TLB * flushes and also makes it easy to access all domains' memory. However, on @@ -54,6 +58,12 @@ sync mtspr SPRN_HID4, r5 isync + + /* Mark the processor as "in CI mode" */ + mfspr r5, SPRN_PIR + li r6, MCK_CPU_STAT_CI + stb r6, MCK_CPU_STAT_BASE(r5) + sync .endm .macro ENABLE_DCACHE addr @@ -63,6 +73,12 @@ mtspr SPRN_HID4, r9 isync + /* Mark the processor as "out of CI mode" */ + mfspr r5, SPRN_PIR + li r6, 0 + stb r6, MCK_CPU_STAT_BASE(r5) + sync + /* re-enable interrupts */ mtmsr r8 .endm diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/ppc970.c --- a/xen/arch/powerpc/powerpc64/ppc970.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/powerpc64/ppc970.c Sun Sep 24 13:10:13 2006 -0600 @@ -17,6 +17,7 @@ * * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> * Jimi Xenidis <jimix@xxxxxxxxxxxxxx> + * Amos Waterland <apw@xxxxxxxxxx> */ #include <xen/config.h> @@ -30,23 +31,31 @@ #include <asm/powerpc64/processor.h> #include <asm/powerpc64/ppc970-hid.h> +#undef DEBUG #undef SERIALIZE -extern volatile struct processor_area * volatile global_cpu_table[]; +struct cpu_caches cpu_caches = { + .dline_size = 0x80, + .log_dline_size = 7, + .dlines_per_page = PAGE_SIZE >> 7, + .iline_size = 0x80, + .log_iline_size = 7, + .ilines_per_page = PAGE_SIZE >> 7, +}; struct rma_settings { int order; - int rmlr0; - int rmlr12; + int rmlr_0; + int rmlr_1_2; }; static struct rma_settings rma_orders[] = { - { .order = 26, .rmlr0 = 0, .rmlr12 = 3, }, /* 64 MB */ - { .order = 27, .rmlr0 = 1, .rmlr12 = 3, }, /* 128 MB */ - { .order = 28, .rmlr0 = 1, .rmlr12 = 0, }, /* 256 MB */ - { .order = 30, .rmlr0 = 0, .rmlr12 = 2, }, /* 1 GB */ - { .order = 34, .rmlr0 = 0, .rmlr12 = 1, }, /* 16 GB */ - { .order = 38, .rmlr0 = 0, .rmlr12 = 0, }, /* 256 GB */ + { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /* 64 MB */ + { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */ + { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */ + { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /* 1 GB */ + { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /* 16 GB */ + { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */ }; static uint log_large_page_sizes[] = { @@ -68,6 +77,11 @@ unsigned int cpu_default_rma_order_pages return rma_orders[0].order - PAGE_SHIFT; } +int cpu_rma_valid(unsigned int log) +{ + return cpu_find_rma(log) != NULL; +} + unsigned int cpu_large_page_orders(uint *sizes, uint max) { uint i = 0; @@ -85,17 +99,63 @@ unsigned int cpu_extent_order(void) return log_large_page_sizes[0] - PAGE_SHIFT; } + +/* This is more a platform thing than a CPU thing, but we only have + * one platform now */ +int cpu_io_mfn(ulong mfn) +{ + /* totally cheating */ + if (mfn >= (2UL << (30 - PAGE_SHIFT)) && /* 2GiB */ + mfn < (4UL << (30 - PAGE_SHIFT))) /* 4GiB */ + return 1; + + return 0; +} + +static u64 cpu0_hids[6]; +static u64 cpu0_hior; + void cpu_initialize(int cpuid) { - ulong r1, r2; - __asm__ __volatile__ ("mr %0, 1" : "=r" (r1)); - __asm__ __volatile__ ("mr %0, 2" : "=r" (r2)); + union hid0 hid0; + union hid1 hid1; + union hid4 hid4; + union hid5 hid5; + + if (cpuid == 0) { + /* we can assume that these are sane to start with. We + * _do_not_ store the results in case we want to mess with them + * on a per-cpu basis later. */ + cpu0_hids[0] = mfhid0(); + cpu0_hids[1] = mfhid1(); + cpu0_hids[4] = mfhid4(); + cpu0_hids[5] = mfhid5(); + cpu0_hior = 0; + } + + hid0.word = cpu0_hids[0]; + hid1.word = cpu0_hids[1]; + hid4.word = cpu0_hids[4]; + hid5.word = cpu0_hids[5]; /* This is SMP safe because the compiler must use r13 for it. */ parea = global_cpu_table[cpuid]; ASSERT(parea != NULL); mthsprg0((ulong)parea); /* now ready for exceptions */ + + printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n", + mfpir(), hard_smp_processor_id(), smp_processor_id()); + +#ifdef DEBUG + { + ulong r1, r2; + + asm volatile ("mr %0, 1" : "=r" (r1)); + asm volatile ("mr %0, 2" : "=r" (r2)); + printk(" SP = %lx TOC = %lx\n", r1, r2); + } +#endif /* Set decrementers for 1 second to keep them out of the way during * intialization. */ @@ -103,59 +163,81 @@ void cpu_initialize(int cpuid) mtdec(timebase_freq); mthdec(timebase_freq); - union hid0 hid0; - - hid0.word = mfhid0(); - hid0.bits.nap = 1; - hid0.bits.dpm = 1; - hid0.bits.nhr = 1; - hid0.bits.hdice = 1; /* enable HDEC */ - hid0.bits.eb_therm = 1; - hid0.bits.en_attn = 1; + hid0.bits.nap = 1; /* NAP */ + hid0.bits.dpm = 1; /* Dynamic Power Management */ + hid0.bits.nhr = 1; /* Not Hard Reset */ + hid0.bits.hdice_en = 1; /* enable HDEC */ + hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */ + /* only debug Xen should activate ATTN */ + hid0.bits.en_attn = 1; /* Enable attn instruction */ + hid0.bits.en_mck = 1; /* Enable external machine check interrupts */ + #ifdef SERIALIZE - ulong s = 0; - - s |= 1UL << (63-0); /* one_ppc */ - s |= 1UL << (63-2); /* isync_sc */ - s |= 1UL << (63-16); /* inorder */ + hid0.bits.one_ppc = 1; + hid0.bits.isync_sc = 1; + hid0.bits.inorder = 1; /* may not want these */ - s |= 1UL << (63-1); /* do_single */ - s |= 1UL << (63-3); /* ser-gp */ - hid0.word |= s; -#endif - - printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n", - smp_processor_id(), r1, r2, hid0.word); + hid0.bits.do_single = 1; + hid0.bits.ser-gp = 1; +#endif mthid0(hid0.word); - union hid1 hid1; - - hid1.word = mfhid1(); - hid1.bits.bht_pm = 7; - hid1.bits.en_ls = 1; - - hid1.bits.en_cc = 1; - hid1.bits.en_ic = 1; - - hid1.bits.pf_mode = 2; - - hid1.bits.en_if_cach = 1; - hid1.bits.en_ic_rec = 1; - hid1.bits.en_id_rec = 1; - hid1.bits.en_er_rec = 1; - - hid1.bits.en_sp_itw = 1; + hid1.bits.bht_pm = 7; /* branch history table prediction mode */ + hid1.bits.en_ls = 1; /* enable link stack */ + + hid1.bits.en_cc = 1; /* enable count cache */ + hid1.bits.en_ic = 1; /* enable inst cache */ + + hid1.bits.pf_mode = 2; /* prefetch mode */ + + hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */ + hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */ + hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */ + hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */ + + hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */ mthid1(hid1.word); - union hid5 hid5; - - hid5.word = mfhid5(); - hid5.bits.DCBZ_size = 0; - hid5.bits.DCBZ32_ill = 0; + /* no changes to hid4 but we want to make sure that secondaries + * are sane */ + hid4.bits.lg_pg_dis = 0; /* make sure we enable large pages */ + mthid4(hid4.word); + + hid5.bits.DC_mck = 1; /* Machine check enabled for dcache errors */ + hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */ + hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */ mthid5(hid5.word); - __asm__ __volatile__("isync; slbia; isync" : : : "memory"); +#ifdef DEBUG + printk("hid0 0x%016lx\n" + "hid1 0x%016lx\n" + "hid4 0x%016lx\n" + "hid5 0x%016lx\n", + mfhid0(), mfhid1(), mfhid4(), mfhid5()); +#endif + + /* Make sure firmware has not left this dirty */ + mthior(cpu0_hior); + + /* some machine check goodness */ + /* save this for checkstop processing */ + if (cpuid == 0) + *mck_good_hid4 = hid4.word; + + if (mfpir() > NR_CPUS) + panic("we do not expect a processor to have a PIR (%u) " + "to be larger that NR_CPUS(%u)\n", + mfpir(), NR_CPUS); + + cpu_scom_init(); + + /* initialize the SLB */ +#ifdef DEBUG + dump_segments(1); +#endif + flush_segments(); + local_flush_tlb(); } void cpu_init_vcpu(struct vcpu *v) @@ -166,18 +248,18 @@ void cpu_init_vcpu(struct vcpu *v) hid4.word = mfhid4(); - hid4.bits.lpes0 = 0; /* exceptions set MSR_HV=1 */ - hid4.bits.lpes1 = 1; /* RMA applies */ - - hid4.bits.rmor = page_to_maddr(d->arch.rma_page) >> 26; - - hid4.bits.lpid01 = d->domain_id & 3; - hid4.bits.lpid25 = (d->domain_id >> 2) & 0xf; + hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */ + hid4.bits.lpes_1 = 1; /* RMA applies */ + + hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26; + + hid4.bits.lpid_0_1 = d->domain_id & 3; + hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf; rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT); ASSERT(rma_settings != NULL); - hid4.bits.rmlr0 = rma_settings->rmlr0; - hid4.bits.rmlr12 = rma_settings->rmlr12; + hid4.bits.rmlr_0 = rma_settings->rmlr_0; + hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2; v->arch.cpu.hid4.word = hid4.word; } diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/setup.c Sun Sep 24 13:10:13 2006 -0600 @@ -16,6 +16,8 @@ * Copyright (C) IBM Corp. 2005, 2006 * * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> + * Amos Waterland <apw@xxxxxxxxxx> + * Hollis Blanchard <hollisb@xxxxxxxxxx> */ #include <xen/config.h> @@ -41,6 +43,7 @@ #include <asm/debugger.h> #include <asm/delay.h> #include <asm/percpu.h> +#include <asm/io.h> #include "exceptions.h" #include "of-devtree.h" #include "oftree.h" @@ -71,20 +74,18 @@ ulong oftree_len; ulong oftree_len; ulong oftree_end; +uint cpu_hard_id[NR_CPUS] __initdata; cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; cpumask_t cpu_online_map; /* missing ifdef in schedule.c */ cpumask_t cpu_present_map; cpumask_t cpu_possible_map; /* XXX get this from ISA node in device tree */ +char *vgabase; ulong isa_io_base; struct ns16550_defaults ns16550; extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[]; -extern void idle_loop(void); - -/* move us to a header file */ -extern void initialize_keytable(void); volatile struct processor_area * volatile global_cpu_table[NR_CPUS]; @@ -99,21 +100,6 @@ unsigned long kernel_text_end(void) unsigned long kernel_text_end(void) { return (unsigned long) &_etext; -} - -void idle_loop(void) -{ - int cpu = smp_processor_id(); - - for ( ; ; ) - { - while (!softirq_pending(cpu)) { - void sleep(void); - page_scrub_schedule_work(); - sleep(); - } - do_softirq(); - } } static void __init do_initcalls(void) @@ -209,6 +195,8 @@ static void __init start_of_day(void) schedulers_start(); } +extern void idle_loop(void); + void startup_cpu_idle_loop(void) { struct vcpu *v = current; @@ -237,6 +225,7 @@ static void init_parea(int cpuid) __func__, STACK_ORDER, cpuid); pa->whoami = cpuid; + pa->hard_id = cpu_hard_id[cpuid]; pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE); /* This store has the effect of invoking secondary_cpu_init. */ @@ -254,18 +243,22 @@ static int kick_secondary_cpus(int maxcp if (cpuid >= maxcpus) break; init_parea(cpuid); - cpu_set(cpuid, cpu_online_map); - cpu_set(cpuid, cpu_possible_map); + smp_generic_give_timebase(); + + /* wait for it */ + while (!cpu_online(cpuid)) + cpu_relax(); } return 0; } /* This is the first C code that secondary processors invoke. */ -int secondary_cpu_init(int cpuid, unsigned long r4); int secondary_cpu_init(int cpuid, unsigned long r4) { cpu_initialize(cpuid); + smp_generic_take_timebase(); + cpu_set(cpuid, cpu_online_map); while(1); } @@ -339,7 +332,7 @@ static void __init __start_xen(multiboot #endif /* Deal with secondary processors. */ - if (opt_nosmp) { + if (opt_nosmp || ofd_boot_cpu == -1) { printk("nosmp: leaving secondary processors spinning forever\n"); } else { printk("spinning up at most %d total processors ...\n", max_cpus); @@ -350,8 +343,17 @@ static void __init __start_xen(multiboot /* Create initial domain 0. */ dom0 = domain_create(0); - if ((dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL)) + if (dom0 == NULL) panic("Error creating domain 0\n"); + dom0->max_pages = ~0U; + if (0 > allocate_rma(dom0, cpu_default_rma_order_pages())) + panic("Error allocating domain 0 RMA\n"); + if (NULL == alloc_vcpu(dom0, 0, 0)) + panic("Error creating domain 0 vcpu 0\n"); + + /* The Interrupt Controller will route everything to CPU 0 so we + * need to make sure Dom0's vVCPU 0 is pinned to the CPU */ + dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0); set_bit(_DOMF_privileged, &dom0->domain_flags); /* post-create hooks sets security label */ diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/shadow.c --- a/xen/arch/powerpc/shadow.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/shadow.c Sun Sep 24 13:10:13 2006 -0600 @@ -78,7 +78,6 @@ unsigned int shadow_set_allocation(struc unsigned int megabytes, int *preempted) { - unsigned int rc; uint pages; uint p; uint order; @@ -91,7 +90,7 @@ unsigned int shadow_set_allocation(struc if (megabytes == 0) { /* old management tools */ megabytes = 1; /* 1/64th of 64M */ - printk("%s: Fix management tools to set and get shadow/htab values\n" + printk("%s: WARNING!!: Update your managment tools\n" " using %d MiB htab\n", __func__, megabytes); } @@ -112,7 +111,7 @@ unsigned int shadow_set_allocation(struc for (p = 0; p < (1 << order); p++) clear_page((void *)(addr + (p << PAGE_SHIFT))); - return rc; + return 0; } int shadow_domctl(struct domain *d, diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/time.c --- a/xen/arch/powerpc/time.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/time.c Sun Sep 24 13:10:13 2006 -0600 @@ -34,40 +34,6 @@ unsigned long cpu_khz; unsigned long cpu_khz; unsigned int timebase_freq; -u64 get_timebase(void) -{ - u64 s; - -#ifdef __PPC64__ - s = mftb(); -#else - do { - unsigned up; - unsigned lo; - unsigned up2; - - up = mftbu(); - lo = mftbl(); - up2 = mftbu(); - } while (up1 != up2); - s = ((ulong)up << 32) | lo; -#endif - return s; -} - -static ulong ns_to_tb(ulong ns) -{ - return (ns * timebase_freq) / 1000000000ULL; -} - -static ulong tb_to_ns(ulong tb) -{ - return tb * (1000000000ULL / timebase_freq); -} - -/* - * Return nanoseconds from time of boot - */ s_time_t get_s_time(void) { return tb_to_ns(get_timebase()); @@ -94,7 +60,7 @@ int reprogram_timer(s_time_t timeout) s_time_t expire; if (timeout == 0) { - expire = 0; + expire = INT_MAX; } else { s_time_t now; diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/usercopy.c --- a/xen/arch/powerpc/usercopy.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/powerpc/usercopy.c Sun Sep 24 13:10:13 2006 -0600 @@ -47,14 +47,30 @@ static unsigned long paddr_to_maddr(unsi pfn = pa >> PAGE_SHIFT; pa = pfn2mfn(d, pfn, &mtype); + if (pa == INVALID_MFN) { + printk("%s: Dom:%d bad paddr: 0x%lx\n", + __func__, d->domain_id, paddr); + return 0; + } switch (mtype) { - case PFN_TYPE_RMA: - case PFN_TYPE_LOGICAL: - break; - default: - panic("%s: called with bad memory address type: 0x%lx\n", - __func__, paddr); - break; + case PFN_TYPE_RMA: + case PFN_TYPE_LOGICAL: + break; + + case PFN_TYPE_FOREIGN: + /* I don't think this should ever happen, but I suppose it + * could be possible */ + printk("%s: Dom:%d paddr: 0x%lx type: FOREIGN\n", + __func__, d->domain_id, paddr); + WARN(); + break; + + case PFN_TYPE_IO: + default: + printk("%s: Dom:%d paddr: 0x%lx bad type: 0x%x\n", + __func__, d->domain_id, paddr, mtype); + WARN(); + return 0; } pa <<= PAGE_SHIFT; pa |= offset; @@ -85,6 +101,9 @@ xencomm_copy_from_guest(void *to, const /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from); + if (desc == NULL) + return n; + if (desc->magic != XENCOMM_MAGIC) { printk("%s: error: %p magic was 0x%x\n", __func__, desc, desc->magic); @@ -117,6 +136,9 @@ xencomm_copy_from_guest(void *to, const unsigned int bytes = min(chunksz, n - to_pos); src_maddr = paddr_to_maddr(src_paddr + chunk_skip); + if (src_maddr == 0) + return n - to_pos; + if (xencomm_debug) printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest); memcpy((void *)dest, (void *)src_maddr, bytes); @@ -153,6 +175,9 @@ xencomm_copy_to_guest(void *to, const vo /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to); + if (desc == NULL) + return n; + if (desc->magic != XENCOMM_MAGIC) { printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic); return n; @@ -184,6 +209,9 @@ xencomm_copy_to_guest(void *to, const vo unsigned int bytes = min(chunksz, n - from_pos); dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip); + if (dest_maddr == 0) + return -1; + if (xencomm_debug) printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr); memcpy((void *)dest_maddr, (void *)source, bytes); @@ -199,16 +227,19 @@ xencomm_copy_to_guest(void *to, const vo /* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely * exhausted pages to XENCOMM_INVALID. */ -void xencomm_add_offset(void *handle, unsigned int bytes) +int xencomm_add_offset(void *handle, unsigned int bytes) { struct xencomm_desc *desc; int i = 0; /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle); + if (desc == NULL) + return -1; + if (desc->magic != XENCOMM_MAGIC) { printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic); - return; + return -1; } /* iterate through the descriptor incrementing addresses */ @@ -230,6 +261,7 @@ void xencomm_add_offset(void *handle, un } bytes -= chunk_skip; } + return 0; } int xencomm_handle_is_null(void *ptr) @@ -237,6 +269,9 @@ int xencomm_handle_is_null(void *ptr) struct xencomm_desc *desc; desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr); + if (desc == NULL) + return 1; return (desc->nr_addrs == 0); } + diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/Rules.mk --- a/xen/arch/x86/Rules.mk Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/Rules.mk Sun Sep 24 13:10:13 2006 -0600 @@ -42,6 +42,9 @@ ifeq ($(TARGET_SUBARCH),x86_64) ifeq ($(TARGET_SUBARCH),x86_64) CFLAGS += -mno-red-zone -fpic -fno-reorder-blocks CFLAGS += -fno-asynchronous-unwind-tables +# -fvisibility=hidden reduces -fpic cost, if it's available +CFLAGS += $(shell $(CC) -v --help 2>&1 | grep " -fvisibility=" | \ + grep -q hidden && echo "-fvisibility=hidden") LDFLAGS += -m elf_x86_64 x86_32 := n x86_64 := y diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/acpi/boot.c Sun Sep 24 13:10:13 2006 -0600 @@ -106,7 +106,7 @@ char *__acpi_map_table(unsigned long phy unsigned long base, offset, mapped_size; int idx; - if (phys + size < 8 * 1024 * 1024) + if (phys + size < 8 * 1024 * 1024) return __va(phys); offset = phys & (PAGE_SIZE - 1); @@ -132,7 +132,7 @@ char *__acpi_map_table(unsigned long phy #ifdef CONFIG_X86_LOCAL_APIC static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { - struct acpi_table_madt *madt = NULL; + struct acpi_table_madt *madt = NULL; if (!phys_addr || !size) return -EINVAL; @@ -147,18 +147,18 @@ static int __init acpi_parse_madt(unsign acpi_lapic_addr = (u64) madt->lapic_address; printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); + madt->lapic_address); } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); - + return 0; } static int __init acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_table_lapic *processor = NULL; + struct acpi_table_lapic *processor = NULL; processor = (struct acpi_table_lapic *)header; @@ -167,10 +167,17 @@ acpi_parse_lapic(acpi_table_entry_header acpi_table_print_madt_entry(header); - /* Register even disabled CPUs for cpu hotplug */ - - x86_acpiid_to_apicid[processor->acpi_id] = processor->id; - + /* Record local apic id only when enabled */ + if (processor->flags.enabled) + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; + + /* + * We need to register disabled CPU as well to permit + * counting disabled CPUs. This allows us to size + * cpus_possible_map more accurately, to permit + * to not preallocating memory for all NR_CPUS + * when we use CPU hotplug. + */ mp_register_lapic(processor->id, /* APIC ID */ processor->flags.enabled); /* Enabled? */ @@ -224,7 +231,7 @@ acpi_parse_ioapic(acpi_table_entry_heade if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; - + acpi_table_print_madt_entry(header); mp_register_ioapic(ioapic->id, @@ -281,8 +288,8 @@ static unsigned long __init static unsigned long __init acpi_scan_rsdp(unsigned long start, unsigned long length) { - unsigned long offset = 0; - unsigned long sig_len = sizeof("RSD PTR ") - 1; + unsigned long offset = 0; + unsigned long sig_len = sizeof("RSD PTR ") - 1; /* * Scan all 16-byte boundaries of the physical memory region for the @@ -302,7 +309,7 @@ static int __init acpi_parse_sbf(unsigne struct acpi_table_sbf *sb; if (!phys_addr || !size) - return -EINVAL; + return -EINVAL; sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); if (!sb) { @@ -310,11 +317,10 @@ static int __init acpi_parse_sbf(unsigne return -ENODEV; } - sbf_port = sb->sbf_cmos; /* Save CMOS port */ - - return 0; -} - + sbf_port = sb->sbf_cmos; /* Save CMOS port */ + + return 0; +} #ifdef CONFIG_HPET_TIMER @@ -349,7 +355,7 @@ static int __init acpi_parse_hpet(unsign hpet_address = hpet_tbl->addr.addrl; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, hpet_address); + hpet_tbl->id, hpet_address); } #endif /* X86 */ @@ -410,17 +416,16 @@ static int __init acpi_parse_fadt(unsign return 0; } - unsigned long __init acpi_find_rsdp(void) { - unsigned long rsdp_phys = 0; + unsigned long rsdp_phys = 0; #if 0 if (efi_enabled) { - if (efi.acpi20) - return __pa(efi.acpi20); - else if (efi.acpi) - return __pa(efi.acpi); + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + return efi.acpi20; + else if (efi.acpi != EFI_INVALID_TABLE_ADDR) + return efi.acpi; } #endif /* @@ -442,6 +447,9 @@ static int __init acpi_parse_madt_lapic_ static int __init acpi_parse_madt_lapic_entries(void) { int count; + + if (!cpu_has_apic) + return -ENODEV; /* * Note that the LAPIC address is obtained from the MADT (32-bit value) @@ -460,8 +468,8 @@ static int __init acpi_parse_madt_lapic_ mp_register_lapic_address(acpi_lapic_addr); count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, - MAX_APICS); - if (!count) { + MAX_APICS); + if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; @@ -499,14 +507,17 @@ static int __init acpi_parse_madt_ioapic */ if (acpi_disabled || acpi_noirq) { return -ENODEV; - } - - /* - * if "noapic" boot option, don't look for IO-APICs + } + + if (!cpu_has_apic) + return -ENODEV; + + /* + * if "noapic" boot option, don't look for IO-APICs */ if (skip_ioapic_setup) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " - "due to 'noapic' option.\n"); + "due to 'noapic' option.\n"); return -ENODEV; } @@ -852,7 +863,7 @@ int __init acpi_boot_table_init(void) * One exception: acpi=ht continues far enough to enumerate LAPICs */ if (acpi_disabled && !acpi_ht) - return 1; + return 1; /* * Initialize the ACPI boot-time table parser. @@ -884,7 +895,6 @@ int __init acpi_boot_table_init(void) return 0; } - int __init acpi_boot_init(void) { /* @@ -892,7 +902,7 @@ int __init acpi_boot_init(void) * One exception: acpi=ht continues far enough to enumerate LAPICs */ if (acpi_disabled && !acpi_ht) - return 1; + return 1; acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); @@ -910,4 +920,3 @@ int __init acpi_boot_init(void) return 0; } - diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/apic.c Sun Sep 24 13:10:13 2006 -0600 @@ -1,5 +1,5 @@ /* - * based on linux-2.6.11/arch/i386/kernel/apic.c + * based on linux-2.6.17.13/arch/i386/kernel/apic.c * * Local APIC handling, local APIC timers * @@ -50,6 +50,18 @@ int apic_verbosity; static void apic_pm_activate(void); +int modern_apic(void) +{ + unsigned int lvr, version; + /* AMD systems use old APIC versions, so check the CPU */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 0xf) + return 1; + lvr = apic_read(APIC_LVR); + version = GET_APIC_VERSION(lvr); + return version >= 0x14; +} + /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -64,8 +76,10 @@ void ack_bad_irq(unsigned int irq) * holds up an irq slot - in excessive cases (when multiple * unexpected vectors occur) that might lock up the APIC * completely. - */ - ack_APIC_irq(); + * But only ack when the APIC is enabled -AK + */ + if (cpu_has_apic) + ack_APIC_irq(); } void __init apic_intr_init(void) @@ -91,12 +105,21 @@ int using_apic_timer = 0; static int enabled_via_apicbase; +void enable_NMI_through_LVT0 (void * dummy) +{ + unsigned int v, ver; + + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); + v = APIC_DM_NMI; /* unmask and set to NMI */ + if (!APIC_INTEGRATED(ver)) /* 82489DX */ + v |= APIC_LVT_LEVEL_TRIGGER; + apic_write_around(APIC_LVT0, v); +} + int get_physical_broadcast(void) { - unsigned int lvr, version; - lvr = apic_read(APIC_LVR); - version = GET_APIC_VERSION(lvr); - if (!APIC_INTEGRATED(version) || version >= 0x14) + if (modern_apic()) return 0xff; else return 0xf; @@ -323,9 +346,9 @@ int __init verify_local_APIC(void) void __init sync_Arb_IDs(void) { - /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ - unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); - if (ver >= 0x14) /* P4 or higher */ + /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 + And not needed on AMD */ + if (modern_apic()) return; /* * Wait for idle. @@ -389,6 +412,7 @@ void __devinit setup_local_APIC(void) void __devinit setup_local_APIC(void) { unsigned long oldvalue, value, ver, maxlvt; + int i, j; /* Pound the ESR really hard over the head with a big hammer - mbligh */ if (esr_disable) { @@ -424,6 +448,25 @@ void __devinit setup_local_APIC(void) value = apic_read(APIC_TASKPRI); value &= ~APIC_TPRI_MASK; apic_write_around(APIC_TASKPRI, value); + + /* + * After a crash, we no longer service the interrupts and a pending + * interrupt from previous kernel might still have ISR bit set. + * + * Most probably by now CPU has serviced that pending interrupt and + * it might not have done the ack_APIC_irq() because it thought, + * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it + * does not clear the ISR bit and cpu thinks it has already serivced + * the interrupt. Hence a vector might get locked. It was noticed + * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. + */ + for (i = APIC_ISR_NR - 1; i >= 0; i--) { + value = apic_read(APIC_ISR + i*0x10); + for (j = 31; j >= 0; j--) { + if (value & (1<<j)) + ack_APIC_irq(); + } + } /* * Now that we are all set up, enable the APIC @@ -534,6 +577,29 @@ void __devinit setup_local_APIC(void) if (nmi_watchdog == NMI_LOCAL_APIC) setup_apic_nmi_watchdog(); apic_pm_activate(); +} + +/* + * If Linux enabled the LAPIC against the BIOS default + * disable it down before re-entering the BIOS on shutdown. + * Otherwise the BIOS may get confused and not power-off. + * Additionally clear all LVT entries before disable_local_APIC + * for the case where Linux didn't enable the LAPIC. + */ +void lapic_shutdown(void) +{ + unsigned long flags; + + if (!cpu_has_apic) + return; + + local_irq_save(flags); + clear_local_APIC(); + + if (enabled_via_apicbase) + disable_local_APIC(); + + local_irq_restore(flags); } static void apic_pm_activate(void) { } @@ -1086,6 +1152,7 @@ int __init APIC_init_uniprocessor (void) if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); return -1; } @@ -1093,6 +1160,14 @@ int __init APIC_init_uniprocessor (void) connect_bsp_APIC(); + /* + * Hack: In case of kdump, after a crash, kernel might be booting + * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid + * might be zero if read from MP tables. Get it from LAPIC. + */ +#ifdef CONFIG_CRASH_DUMP + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); +#endif phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); setup_local_APIC(); diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/boot/x86_64.S --- a/xen/arch/x86/boot/x86_64.S Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/boot/x86_64.S Sun Sep 24 13:10:13 2006 -0600 @@ -9,6 +9,8 @@ .text .code32 + +#define SYM_PHYS(sym) (sym - __PAGE_OFFSET) ENTRY(start) ENTRY(stext) @@ -24,15 +26,14 @@ ENTRY(_stext) /* Checksum: must be the negated sum of the first two fields. */ .long -0x1BADB005 - .org 0x010 - .asciz "ERR: Not a 64-bit CPU!" - .org 0x028 - .asciz "ERR: Not a Multiboot bootloader!" +.Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!" +.Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!" + bad_cpu: - mov $0x100010,%esi # Error message + mov $(SYM_PHYS(.Lbad_cpu_msg)),%esi # Error message jmp print_err not_multiboot: - mov $0x100028,%esi # Error message + mov $(SYM_PHYS(.Lbad_ldr_msg)),%esi # Error message print_err: mov $0xB8000,%edi # VGA framebuffer 1: mov (%esi),%bl @@ -55,7 +56,7 @@ __start: cli /* Set up a few descriptors: on entry only CS is guaranteed good. */ - lgdt %cs:0x100306 # nopaging_gdt_descr + lgdt %cs:SYM_PHYS(nopaging_gdt_descr) mov $(__HYPERVISOR_DS32),%ecx mov %ecx,%ds mov %ecx,%es @@ -68,7 +69,7 @@ __start: jne not_multiboot /* Save the Multiboot info structure for later use. */ - mov %ebx,0x100300 # multiboot_ptr + mov %ebx,SYM_PHYS(multiboot_ptr) /* We begin by interrogating the CPU for the presence of long mode. */ mov $0x80000000,%eax @@ -79,7 +80,7 @@ __start: cpuid bt $29,%edx # Long mode feature? jnc bad_cpu - mov %edx,0x100310 # cpuid_ext_features + mov %edx,SYM_PHYS(cpuid_ext_features) skip_boot_checks: /* Set up FPU. */ @@ -90,7 +91,7 @@ skip_boot_checks: mov %ecx,%cr4 /* Load pagetable base register. */ - mov $0x102000,%eax /* idle_pg_table */ + mov $SYM_PHYS(idle_pg_table),%eax mov %eax,%cr3 /* Set up EFER (Extended Feature Enable Register). */ @@ -98,7 +99,7 @@ skip_boot_checks: rdmsr btsl $_EFER_LME,%eax /* Long Mode */ btsl $_EFER_SCE,%eax /* SYSCALL/SYSRET */ - mov 0x100310,%edi + mov SYM_PHYS(cpuid_ext_features),%edi btl $20,%edi /* CPUID 0x80000001, EDX[20] */ jnc 1f btsl $_EFER_NX,%eax /* No-Execute */ @@ -109,11 +110,10 @@ 1: wrmsr jmp 1f 1: /* Now in compatibility mode. Long-jump into 64-bit mode. */ - ljmp $(__HYPERVISOR_CS64),$0x100200 + ljmp $(__HYPERVISOR_CS64),$SYM_PHYS(start64) .code64 - .org 0x0200 - +start64: /* Install relocated selectors (FS/GS unused). */ lgdt gdt_descr(%rip) @@ -195,18 +195,16 @@ 1: jmp 1b .globl idt .globl gdt - .org 0x300 - .code32 - -multiboot_ptr: /* 0x300 */ + .align 8, 0xCC +multiboot_ptr: .long 0 .word 0 -nopaging_gdt_descr: /* 0x306 */ +nopaging_gdt_descr: .word LAST_RESERVED_GDT_BYTE .quad gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET -cpuid_ext_features: /* 0x310 */ +cpuid_ext_features: .long 0 .word 0 @@ -227,7 +225,7 @@ high_start: high_start: .quad __high_start - .org 0x1000 + .align PAGE_SIZE, 0 ENTRY(gdt_table) .quad 0x0000000000000000 /* unused */ .quad 0x00cf9a000000ffff /* 0xe008 ring 0 code, compatibility */ @@ -240,7 +238,7 @@ ENTRY(gdt_table) .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ /* Initial PML4 -- level-4 page table. */ - .org 0x2000 + .align PAGE_SIZE, 0 ENTRY(idle_pg_table) ENTRY(idle_pg_table_4) .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0] @@ -248,12 +246,12 @@ ENTRY(idle_pg_table_4) .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262] /* Initial PDP -- level-3 page table. */ - .org 0x3000 + .align PAGE_SIZE, 0 ENTRY(idle_pg_table_l3) .quad idle_pg_table_l2 - __PAGE_OFFSET + 7 /* Initial PDE -- level-2 page table. Maps first 1GB physical memory. */ - .org 0x4000 + .align PAGE_SIZE, 0 ENTRY(idle_pg_table_l2) .macro identmap from=0, count=512 .if \count-1 @@ -265,8 +263,7 @@ ENTRY(idle_pg_table_l2) .endm identmap - .org 0x4000 + PAGE_SIZE - .code64 + .align PAGE_SIZE, 0 .section ".bss.stack_aligned","w" ENTRY(cpu0_stack) diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/domain_build.c Sun Sep 24 13:10:13 2006 -0600 @@ -74,10 +74,11 @@ string_param("dom0_ioports_disable", opt #define L3_PROT (_PAGE_PRESENT) #elif defined(__x86_64__) /* Allow ring-3 access in long mode as guest cannot use ring 1. */ -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) +#define BASE_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) +#define L1_PROT (BASE_PROT|_PAGE_GUEST_KERNEL) +#define L2_PROT (BASE_PROT|_PAGE_DIRTY) +#define L3_PROT (BASE_PROT|_PAGE_DIRTY) +#define L4_PROT (BASE_PROT|_PAGE_DIRTY) #endif #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) @@ -510,15 +511,13 @@ int construct_dom0(struct domain *d, case 1 ... 4: page->u.inuse.type_info &= ~PGT_type_mask; page->u.inuse.type_info |= PGT_l2_page_table; - page->u.inuse.type_info |= - (count-1) << PGT_va_shift; + if ( count == 4 ) + page->u.inuse.type_info |= PGT_pae_xen_l2; get_page(page, d); /* an extra ref because of readable mapping */ break; default: page->u.inuse.type_info &= ~PGT_type_mask; page->u.inuse.type_info |= PGT_l1_page_table; - page->u.inuse.type_info |= - ((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-5))<<PGT_va_shift; get_page(page, d); /* an extra ref because of readable mapping */ break; } @@ -544,8 +543,6 @@ int construct_dom0(struct domain *d, { page->u.inuse.type_info &= ~PGT_type_mask; page->u.inuse.type_info |= PGT_l1_page_table; - page->u.inuse.type_info |= - ((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift; /* * No longer writable: decrement the type_count. diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/domctl.c Sun Sep 24 13:10:13 2006 -0600 @@ -22,6 +22,7 @@ #include <asm/hvm/hvm.h> #include <asm/hvm/support.h> #include <asm/processor.h> +#include <public/hvm/e820.h> long arch_do_domctl( struct xen_domctl *domctl, @@ -213,7 +214,7 @@ long arch_do_domctl( int i; struct domain *d = find_domain_by_id(domctl->domain); unsigned long max_pfns = domctl->u.getmemlist.max_pfns; - unsigned long mfn; + unsigned long mfn, gmfn; struct list_head *list_ent; ret = -EINVAL; @@ -222,19 +223,48 @@ long arch_do_domctl( ret = 0; spin_lock(&d->page_alloc_lock); - list_ent = d->page_list.next; - for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ ) - { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, - i, &mfn, 1) ) - { - ret = -EFAULT; - break; - } - list_ent = mfn_to_page(mfn)->list.next; - } + + if ( hvm_guest(d->vcpu[0]) && shadow_mode_translate(d) ) + { + /* HVM domain: scan P2M to get guaranteed physmap order. */ + for ( i = 0, gmfn = 0; + (i < max_pfns) && (i < d->tot_pages); + i++, gmfn++ ) + { + if ( unlikely(i == (HVM_BELOW_4G_MMIO_START>>PAGE_SHIFT)) ) + { + /* skip MMIO range */ + gmfn += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; + } + mfn = gmfn_to_mfn(d, gmfn); + if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, + i, &mfn, 1) ) + { + ret = -EFAULT; + break; + } + } + } + else + { + /* Other guests: return in order of ownership list. */ + list_ent = d->page_list.next; + for ( i = 0; + (i < max_pfns) && (list_ent != &d->page_list); + i++ ) + { + mfn = page_to_mfn(list_entry( + list_ent, struct page_info, list)); + if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, + i, &mfn, 1) ) + { + ret = -EFAULT; + break; + } + list_ent = mfn_to_page(mfn)->list.next; + } + } + spin_unlock(&d->page_alloc_lock); domctl->u.getmemlist.num_pfns = i; diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/flushtlb.c --- a/xen/arch/x86/flushtlb.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/flushtlb.c Sun Sep 24 13:10:13 2006 -0600 @@ -4,13 +4,14 @@ * TLB flushes are timestamped using a global virtual 'clock' which ticks * on any TLB flush on any processor. * - * Copyright (c) 2003-2004, K A Fraser + * Copyright (c) 2003-2006, K A Fraser */ #include <xen/config.h> #include <xen/sched.h> #include <xen/softirq.h> #include <asm/flushtlb.h> +#include <asm/page.h> /* Debug builds: Wrap frequently to stress-test the wrap logic. */ #ifdef NDEBUG @@ -22,21 +23,17 @@ u32 tlbflush_clock = 1U; u32 tlbflush_clock = 1U; DEFINE_PER_CPU(u32, tlbflush_time); -void write_cr3(unsigned long cr3) +/* + * pre_flush(): Increment the virtual TLB-flush clock. Returns new clock value. + * + * This must happen *before* we flush the TLB. If we do it after, we race other + * CPUs invalidating PTEs. For example, a page invalidated after the flush + * might get the old timestamp, but this CPU can speculatively fetch the + * mapping into its TLB after the flush but before inc'ing the clock. + */ +static u32 pre_flush(void) { u32 t, t1, t2; - unsigned long flags; - - /* This non-reentrant function is sometimes called in interrupt context. */ - local_irq_save(flags); - - /* - * STEP 1. Increment the virtual clock *before* flushing the TLB. - * If we do it after, we race other CPUs invalidating PTEs. - * (e.g., a page invalidated after the flush might get the old - * timestamp, but this CPU can speculatively fetch the mapping - * into its TLB after the flush but before inc'ing the clock). - */ t = tlbflush_clock; do { @@ -52,26 +49,68 @@ void write_cr3(unsigned long cr3) if ( unlikely(t2 == 0) ) raise_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ); - /* - * STEP 2. Update %CR3, thereby flushing the TLB. - */ + skip_clocktick: + return t2; +} - skip_clocktick: +/* + * post_flush(): Update this CPU's timestamp with specified clock value. + * + * Note that this happens *after* flushing the TLB, as otherwise we can race a + * NEED_FLUSH() test on another CPU. (e.g., other CPU sees the updated CPU + * stamp and so does not force a synchronous TLB flush, but the flush in this + * function hasn't yet occurred and so the TLB might be stale). The ordering + * would only actually matter if this function were interruptible, and + * something that abuses the stale mapping could exist in an interrupt + * handler. In fact neither of these is the case, so really we are being ultra + * paranoid. + */ +static void post_flush(u32 t) +{ + this_cpu(tlbflush_time) = t; +} + +void write_cr3(unsigned long cr3) +{ + unsigned long flags; + u32 t; + + /* This non-reentrant function is sometimes called in interrupt context. */ + local_irq_save(flags); + + t = pre_flush(); + +#ifdef USER_MAPPINGS_ARE_GLOBAL + __pge_off(); __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" ); + __pge_on(); +#else + __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" ); +#endif - /* - * STEP 3. Update this CPU's timestamp. Note that this happens *after* - * flushing the TLB, as otherwise we can race a NEED_FLUSH() test - * on another CPU. (e.g., other CPU sees the updated CPU stamp and - * so does not force a synchronous TLB flush, but the flush in this - * function hasn't yet occurred and so the TLB might be stale). - * The ordering would only actually matter if this function were - * interruptible, and something that abuses the stale mapping could - * exist in an interrupt handler. In fact neither of these is the - * case, so really we are being ultra paranoid. - */ - - this_cpu(tlbflush_time) = t2; + post_flush(t); local_irq_restore(flags); } + +void local_flush_tlb(void) +{ + unsigned long flags; + u32 t; + + /* This non-reentrant function is sometimes called in interrupt context. */ + local_irq_save(flags); + + t = pre_flush(); + +#ifdef USER_MAPPINGS_ARE_GLOBAL + __pge_off(); + __pge_on(); +#else + __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (read_cr3()) : "memory" ); +#endif + + post_flush(t); + + local_irq_restore(flags); +} diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/hvm/hvm.c Sun Sep 24 13:10:13 2006 -0600 @@ -337,7 +337,6 @@ int cpu_get_interrupt(struct vcpu *v, in return -1; } -#include <asm/hvm/vmx/vmx.h> void hvm_hlt(unsigned long rflags) { struct vcpu *v = current; diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/hvm/i8259.c --- a/xen/arch/x86/hvm/i8259.c Thu Sep 21 15:35:45 2006 -0600 +++ b/xen/arch/x86/hvm/i8259.c Sun Sep 24 13:10:13 2006 -0600 @@ -35,12 +35,11 @@ #include <asm/current.h> /* set irq level. If an edge is detected, then the IRR is set to 1 */ -/* Caller must hold vpic lock */ static inline void pic_set_irq1(PicState *s, int irq, int level) { int mask; - BUG_ON(!spin_is_locked(&s->pics_state->lock)); + ASSERT(spin_is_locked(&s->pics_state->lock)); mask = 1 << irq; if (s->elcr & mask) { @@ -55,9 +54,8 @@ static inline void pic_set_irq1(PicState } else { /* edge triggered */ if (level) { - if ((s->last_irr & mask) == 0) { + if ((s->last_irr & mask) == 0) s->irr |= mask; - } s->last_irr |= mask; } else { s->last_irr &= ~mask; @@ -67,12 +65,11 @@ static inline void pic_set_irq1(PicState /* return the highest priority found in mask (highest = smallest number). Return 8 if no irq */ -/* Caller must hold vpic lock */ static inline int get_priority(PicState *s, int mask) { int priority; - BUG_ON(!spin_is_locked(&s->pics_state->lock)); + ASSERT(spin_is_locked(&s->pics_state->lock)); if (mask == 0) return 8; @@ -83,12 +80,11 @@ static inline int get_priority(PicState } /* return the pic wanted interrupt. return -1 if none */ -/* Caller must hold vpic lock */ static int pic_get_irq(PicState *s) { int mask, cur_priority, priority; - BUG_ON(!spin_is_locked(&s->pics_state->lock)); + ASSERT(spin_is_locked(&s->pics_state->lock)); mask = s->irr & ~s->imr; priority = get_priority(s, mask); @@ -112,12 +108,11 @@ static int pic_get_irq(PicState *s) /* raise irq to CPU if necessary. must be called every time the active irq may change */ /* XXX: should not export it, but it is needed for an APIC kludge */ -/* Caller must hold vpic lock */ void pic_update_irq(struct hvm_virpic *s) { int irq2, irq; - BUG_ON(!spin_is_locked(&s->lock)); + ASSERT(spin_is_locked(&s->lock)); /* first look at slave pic */ irq2 = pic_get_irq(&s->pics[1]); @@ -179,10 +174,9 @@ void pic_set_irq(struct hvm_virpic *isa_ } /* acknowledge interrupt 'irq' */ -/* Caller must hold vpic lock */ static inline void pic_intack(PicState *s, int irq) { - BUG_ON(!spin_is_locked(&s->pics_state->lock)); + ASSERT(spin_is_locked(&s->pics_state->lock)); if (s->auto_eoi) { if (s->rotate_on_auto_eoi) @@ -219,7 +213,6 @@ int pic_read_irq(struct hvm_virpic *s) } } else { /* spurious IRQ on host controller */ - printk("spurious IRQ irq got=%d\n",irq); irq = 7; intno = s->pics[0].irq_base + irq; } @@ -229,12 +222,11 @@ int pic_read_irq(struct hvm_virpic *s) return intno; } -/* Caller must hold vpic lock */ static void update_shared_irr(struct hvm_virpic *s, PicState *c) { uint8_t *pl, *pe; - BUG_ON(!spin_is_locked(&s->lock)); + ASSERT(spin_is_locked(&s->lock)); get_sp(current->domain)->sp_global.pic_elcr = s->pics[0].elcr | ((u16)s->pics[1].elcr << 8); @@ -250,12 +242,11 @@ static void update_shared_irr(struct hvm } } -/* Caller must hold vpic lock */ static void pic_reset(void *opaque) { PicState *s = opaque; - BUG_ON(!spin_is_locked(&s->pics_state->lock)); + ASSERT(spin_is_locked(&s->pics_state->lock)); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |