[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 Hollis Blanchard <hollisb@xxxxxxxxxx> # Date 1174518511 18000 # Node ID 49ec3725d0c08130d339ad4d3ccb27b1557f8c27 # Parent 2c087916aaba101c3fbdc1c67c95f28065cf4709 # Parent 3fd9b0c71b8c687b108a8bf671c9c4fc47046a0a Merge with xen-unstable.hg. Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/include/asm-x86/hvm/svm/vmmcall.h | 44 Config.mk | 6 buildconfigs/conf.linux-native/00_xen_to_native | 2 buildconfigs/linux-defconfig_xen0_ia64 | 4 buildconfigs/linux-defconfig_xen0_x86_32 | 4 buildconfigs/linux-defconfig_xen0_x86_64 | 4 buildconfigs/linux-defconfig_xenU_ia64 | 4 buildconfigs/linux-defconfig_xenU_x86_32 | 4 buildconfigs/linux-defconfig_xenU_x86_64 | 4 buildconfigs/linux-defconfig_xen_ia64 | 4 buildconfigs/linux-defconfig_xen_x86_32 | 4 buildconfigs/linux-defconfig_xen_x86_64 | 4 docs/man/xm.pod.1 | 2 docs/misc/dump-core-format.txt | 8 docs/src/user.tex | 5 docs/xen-api/coversheet.tex | 2 docs/xen-api/presentation.tex | 16 docs/xen-api/todo.tex | 11 docs/xen-api/vm-lifecycle.tex | 16 docs/xen-api/wire-protocol.tex | 50 docs/xen-api/xenapi-datamodel.tex | 1212 ++++------ docs/xen-api/xenapi.tex | 3 extras/mini-os/arch/x86/mm.c | 4 extras/mini-os/gnttab.c | 2 extras/mini-os/hypervisor.c | 4 extras/mini-os/include/wait.h | 7 extras/mini-os/include/xenbus.h | 1 extras/mini-os/xenbus/xenbus.c | 3 linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c | 24 linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c | 4 linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c | 2 linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c | 6 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c | 6 linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c | 6 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 39 linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S | 2 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c | 4 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c | 16 linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c | 2 linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c | 2 linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c | 24 linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 8 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 6 linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c | 98 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c | 2 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h | 13 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 28 linux-2.6-xen-sparse/drivers/xen/Kconfig | 9 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 4 linux-2.6-xen-sparse/drivers/xen/char/mem.c | 6 linux-2.6-xen-sparse/drivers/xen/console/console.c | 7 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c | 17 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 4 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c | 13 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c | 6 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h | 2 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c | 12 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 1 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c | 13 linux-2.6-xen-sparse/include/asm-i386/kexec.h | 3 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h | 10 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h | 2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h | 7 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h | 6 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 2 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h | 10 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h | 7 linux-2.6-xen-sparse/kernel/kexec.c | 23 linux-2.6-xen-sparse/mm/Kconfig | 157 + patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch | 28 patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps.patch | 51 patches/linux-2.6.18/series | 2 patches/linux-2.6.18/softlockup-no-idle-hz.patch | 1 tools/Rules.mk | 5 tools/blktap/drivers/block-qcow.c | 1 tools/firmware/Makefile | 6 tools/firmware/hvmloader/32bitbios_support.c | 179 - tools/firmware/hvmloader/acpi/acpi2_0.h | 60 tools/firmware/hvmloader/acpi/build.c | 51 tools/firmware/hvmloader/hvmloader.c | 144 - tools/firmware/hvmloader/smbios.c | 48 tools/firmware/hvmloader/util.c | 21 tools/firmware/hvmloader/util.h | 12 tools/firmware/rombios/32bit/tcgbios/tcgbios.c | 64 tools/firmware/rombios/32bitgateway.c | 29 tools/firmware/rombios/rombios.c | 247 -- tools/firmware/rombios/tcgbios.c | 6 tools/ioemu/hw/ide.c | 61 tools/ioemu/hw/usb-hid.c | 47 tools/ioemu/hw/usb-ohci.c | 2 tools/ioemu/hw/usb-uhci.c | 50 tools/ioemu/hw/usb.c | 40 tools/ioemu/hw/usb.h | 6 tools/ioemu/target-i386-dm/exec-dm.c | 16 tools/ioemu/target-i386-dm/helper2.c | 36 tools/ioemu/vl.c | 19 tools/ioemu/vl.h | 1 tools/ioemu/xenstore.c | 179 + tools/libxc/Makefile | 2 tools/libxc/xc_core.c | 6 tools/libxc/xc_core_ia64.c | 24 tools/libxc/xc_core_x86.c | 24 tools/libxc/xc_dom_x86.c | 38 tools/libxc/xc_hvm_build.c | 15 tools/libxc/xc_hvm_restore.c | 102 tools/libxc/xc_hvm_save.c | 194 + tools/libxc/xc_linux_restore.c | 5 tools/libxc/xc_misc.c | 19 tools/libxc/xc_private.c | 16 tools/libxc/xc_ptrace_core.c | 1 tools/libxc/xenctrl.h | 8 tools/libxc/xenguest.h | 9 tools/libxc/xg_private.c | 9 tools/libxen/include/xen_crashdump.h | 23 tools/libxen/include/xen_vbd.h | 17 tools/libxen/include/xen_vdi.h | 51 tools/libxen/include/xen_vif.h | 16 tools/libxen/include/xen_vm.h | 148 - tools/libxen/src/xen_common.c | 21 tools/libxen/src/xen_crashdump.c | 47 tools/libxen/src/xen_vbd.c | 31 tools/libxen/src/xen_vdi.c | 114 tools/libxen/src/xen_vif.c | 28 tools/libxen/src/xen_vm.c | 281 -- tools/libxen/test/test_bindings.c | 6 tools/python/scripts/test_hvm_create.py | 3 tools/python/scripts/test_vm_create.py | 6 tools/python/scripts/xapi.py | 11 tools/python/scripts/xapi.vdicfg.py | 3 tools/python/xen/lowlevel/xc/xc.c | 98 tools/python/xen/util/blkif.py | 17 tools/python/xen/util/xmlrpclib2.py | 52 tools/python/xen/xend/XendAPI.py | 440 ++- tools/python/xen/xend/XendCheckpoint.py | 26 tools/python/xen/xend/XendConfig.py | 384 +-- tools/python/xen/xend/XendDomain.py | 4 tools/python/xen/xend/XendDomainInfo.py | 201 - tools/python/xen/xend/XendError.py | 7 tools/python/xen/xend/XendLogging.py | 12 tools/python/xen/xend/XendNode.py | 65 tools/python/xen/xend/XendVDI.py | 27 tools/python/xen/xend/XendVMMetrics.py | 70 tools/python/xen/xend/image.py | 59 tools/python/xen/xend/server/SrvDaemon.py | 9 tools/python/xen/xend/server/XMLRPCServer.py | 2 tools/python/xen/xend/server/vfbif.py | 2 tools/python/xen/xm/XenAPI.py | 2 tools/python/xen/xm/addlabel.py | 2 tools/python/xen/xm/create.dtd | 118 tools/python/xen/xm/create.py | 83 tools/python/xen/xm/main.py | 555 +++- tools/python/xen/xm/messages/en/xen-xm.po | 5 tools/python/xen/xm/new.py | 13 tools/python/xen/xm/shutdown.py | 37 tools/python/xen/xm/xenapi_create.py | 636 +++++ tools/xcutils/Makefile | 6 tools/xcutils/xc_save.c | 129 + tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py | 4 tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py | 4 tools/xm-test/tests/destroy/01_destroy_basic_pos.py | 2 tools/xm-test/tests/network-attach/network_utils.py | 19 tools/xm-test/tests/vtpm/09_vtpm-xapi.py | 11 tools/xm-test/tests/vtpm/vtpm_utils.py | 3 unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 3 xen/arch/ia64/xen/domain.c | 8 xen/arch/ia64/xen/xensetup.c | 2 xen/arch/powerpc/domain.c | 7 xen/arch/powerpc/domain_build.c | 1 xen/arch/powerpc/setup.c | 3 xen/arch/x86/Rules.mk | 18 xen/arch/x86/apic.c | 14 xen/arch/x86/domain.c | 44 xen/arch/x86/domain_build.c | 1 xen/arch/x86/domctl.c | 12 xen/arch/x86/gdbstub.c | 28 xen/arch/x86/hvm/hpet.c | 24 xen/arch/x86/hvm/hvm.c | 61 xen/arch/x86/hvm/platform.c | 11 xen/arch/x86/hvm/rtc.c | 17 xen/arch/x86/hvm/svm/svm.c | 193 - xen/arch/x86/hvm/svm/vmcb.c | 19 xen/arch/x86/hvm/svm/x86_32/exits.S | 40 xen/arch/x86/hvm/svm/x86_64/exits.S | 34 xen/arch/x86/hvm/vlapic.c | 5 xen/arch/x86/hvm/vpic.c | 4 xen/arch/x86/mm.c | 115 xen/arch/x86/mm/shadow/common.c | 29 xen/arch/x86/mm/shadow/multi.c | 2 xen/arch/x86/setup.c | 8 xen/arch/x86/traps.c | 7 xen/arch/x86/x86_64/asm-offsets.c | 1 xen/arch/x86/x86_64/compat/entry.S | 4 xen/arch/x86/x86_64/compat/traps.c | 4 xen/arch/x86/x86_64/compat_kexec.S | 13 xen/arch/x86/x86_64/entry.S | 30 xen/arch/x86/x86_64/traps.c | 18 xen/arch/x86/x86_emulate.c | 74 xen/common/compat/domain.c | 4 xen/common/compat/memory.c | 2 xen/common/domain.c | 76 xen/common/domctl.c | 20 xen/common/grant_table.c | 6 xen/common/keyhandler.c | 34 xen/common/memory.c | 15 xen/common/page_alloc.c | 15 xen/common/perfc.c | 17 xen/common/sched_credit.c | 40 xen/common/schedule.c | 139 - xen/common/sysctl.c | 15 xen/drivers/char/console.c | 11 xen/include/asm-ia64/grant_table.h | 3 xen/include/asm-ia64/mm.h | 2 xen/include/asm-powerpc/grant_table.h | 13 xen/include/asm-powerpc/mm.h | 2 xen/include/asm-x86/domain.h | 6 xen/include/asm-x86/grant_table.h | 10 xen/include/asm-x86/hvm/svm/svm.h | 2 xen/include/asm-x86/hvm/svm/vmcb.h | 3 xen/include/asm-x86/hvm/vpt.h | 1 xen/include/asm-x86/mm.h | 1 xen/include/asm-x86/paging.h | 2 xen/include/asm-x86/processor.h | 6 xen/include/public/arch-x86/xen-x86_32.h | 2 xen/include/public/arch-x86/xen.h | 2 xen/include/public/foreign/Makefile | 2 xen/include/public/foreign/structs.py | 2 xen/include/public/hvm/hvm_op.h | 8 xen/include/public/memory.h | 5 xen/include/public/sysctl.h | 13 xen/include/public/vcpu.h | 42 xen/include/xen/mm.h | 5 xen/include/xen/sched-if.h | 2 xen/include/xen/sched.h | 8 xen/include/xen/timer.h | 4 xen/include/xen/trace.h | 10 236 files changed, 5875 insertions(+), 3372 deletions(-) diff -r 2c087916aaba -r 49ec3725d0c0 Config.mk --- a/Config.mk Wed Mar 21 17:03:00 2007 -0500 +++ b/Config.mk Wed Mar 21 18:08:31 2007 -0500 @@ -35,6 +35,12 @@ endif # Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586) cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \ /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;) + +# cc-ver +# Usage: ifeq ($(call cc-ver,$(CC),0x030400),y) +cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \ + '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \ + then echo y; else echo n; fi ;) ifneq ($(debug),y) CFLAGS += -DNDEBUG diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/conf.linux-native/00_xen_to_native --- a/buildconfigs/conf.linux-native/00_xen_to_native Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/conf.linux-native/00_xen_to_native Wed Mar 21 18:08:31 2007 -0500 @@ -74,8 +74,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_XEN_DISABLE_SERIAL is not set # CONFIG_XEN_SYSFS is not set # CONFIG_XEN_COMPAT_030002_AND_LATER is not set +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set # CONFIG_XEN_COMPAT_030002 is not set +# CONFIG_XEN_COMPAT_030004 is not set # CONFIG_HAVE_ARCH_ALLOC_SKB is not set # CONFIG_HAVE_ARCH_DEV_ALLOC_SKB is not set # CONFIG_NO_IDLE_HZ is not set diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen0_ia64 --- a/buildconfigs/linux-defconfig_xen0_ia64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Wed Mar 21 18:08:31 2007 -0500 @@ -1619,7 +1619,7 @@ CONFIG_XEN_BALLOON=y CONFIG_XEN_BALLOON=y CONFIG_XEN_REBOOT=y # CONFIG_XEN_SMPBOOT is not set -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1647,8 +1647,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_DEVMEM=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen0_x86_32 --- a/buildconfigs/linux-defconfig_xen0_x86_32 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 Wed Mar 21 18:08:31 2007 -0500 @@ -1384,7 +1384,7 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1411,8 +1411,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen0_x86_64 --- a/buildconfigs/linux-defconfig_xen0_x86_64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 Wed Mar 21 18:08:31 2007 -0500 @@ -1334,7 +1334,7 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1361,8 +1361,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xenU_ia64 --- a/buildconfigs/linux-defconfig_xenU_ia64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xenU_ia64 Wed Mar 21 18:08:31 2007 -0500 @@ -1471,7 +1471,7 @@ CONFIG_XEN_BALLOON=y CONFIG_XEN_BALLOON=y CONFIG_XEN_REBOOT=y # CONFIG_XEN_SMPBOOT is not set -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1489,8 +1489,10 @@ CONFIG_XEN_KEYBOARD=y # CONFIG_XEN_DISABLE_SERIAL is not set CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_DEVMEM=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xenU_x86_32 --- a/buildconfigs/linux-defconfig_xenU_x86_32 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xenU_x86_32 Wed Mar 21 18:08:31 2007 -0500 @@ -904,7 +904,7 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -920,8 +920,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xenU_x86_64 --- a/buildconfigs/linux-defconfig_xenU_x86_64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xenU_x86_64 Wed Mar 21 18:08:31 2007 -0500 @@ -1200,7 +1200,7 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1216,8 +1216,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen_ia64 --- a/buildconfigs/linux-defconfig_xen_ia64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen_ia64 Wed Mar 21 18:08:31 2007 -0500 @@ -1619,7 +1619,7 @@ CONFIG_XEN_BALLOON=y CONFIG_XEN_BALLOON=y CONFIG_XEN_REBOOT=y # CONFIG_XEN_SMPBOOT is not set -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -1648,8 +1648,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_DEVMEM=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen_x86_32 --- a/buildconfigs/linux-defconfig_xen_x86_32 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Wed Mar 21 18:08:31 2007 -0500 @@ -3242,7 +3242,7 @@ CONFIG_CRYPTO_TEST=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -3271,8 +3271,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 buildconfigs/linux-defconfig_xen_x86_64 --- a/buildconfigs/linux-defconfig_xen_x86_64 Wed Mar 21 17:03:00 2007 -0500 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Wed Mar 21 18:08:31 2007 -0500 @@ -3072,7 +3072,7 @@ CONFIG_CRYPTO_TEST=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030203 +CONFIG_XEN_INTERFACE_VERSION=0x00030205 # # XEN @@ -3101,8 +3101,10 @@ CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set # CONFIG_XEN_COMPAT_LATEST_ONLY is not set CONFIG_XEN_COMPAT_030002=y +CONFIG_XEN_COMPAT_030004=y CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y CONFIG_XEN_UTIL=y diff -r 2c087916aaba -r 49ec3725d0c0 docs/man/xm.pod.1 --- a/docs/man/xm.pod.1 Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/man/xm.pod.1 Wed Mar 21 18:08:31 2007 -0500 @@ -619,7 +619,7 @@ devices, or by device id, such as 0x1400 =item I<mode> The access mode for the device from the guest domain. Supported modes -are I<rw> (read/write) or I<ro> (read-only). +are I<w> (read/write) or I<r> (read-only). =item I<bedomain-id> diff -r 2c087916aaba -r 49ec3725d0c0 docs/misc/dump-core-format.txt --- a/docs/misc/dump-core-format.txt Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/misc/dump-core-format.txt Wed Mar 21 18:08:31 2007 -0500 @@ -80,8 +80,7 @@ Currently the following sections are def gmfn: machine physical frame number The size of arrays is stored in xch_nr_pages member of header note descriptor in .note.Xen note section. - There is no rule about the order. Analysis tools must no rely - on its order. + The entryies are stored in pfn-ascending order. This section must exist when the domain is non auto translated physmap mode. Currently x86 paravirtualized domain. @@ -94,8 +93,7 @@ Currently the following sections are def in .xen_pages section. The size of arrays is stored in xch_nr_pages member of header note descriptor in .note.Xen note section. - There is no rule about the order. Analysis tools must no rely - on its order. + The entries are stored in ascending order. This section must exist when the domain is auto translated physmap mode. Currently x86 full virtualized domain and ia64 domain. @@ -226,6 +224,8 @@ Currently only (major, minor) = (0, 1) i [When the format is changed, it would be described here.] (0, 1) update +- .xen_p2m, .xen_pfn section + Arrays must be in pfn ascending order for efficient looking up. - EI_CLASS member of elf header was changed to ELFCLASS64 independent of architecture. This is mainly for x86_32pae. The format version isn't bumped because analysis tools can distinguish it. diff -r 2c087916aaba -r 49ec3725d0c0 docs/src/user.tex --- a/docs/src/user.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/src/user.tex Wed Mar 21 18:08:31 2007 -0500 @@ -3179,6 +3179,11 @@ editing \path{grub.conf}. one of 80x25, 80x28, 80x30, 80x34, 80x43, 80x50, 80x60. \item[ keep ] Keep the VGA console even after domain 0 boots. \end{description} +\item [ console\_to\_ring ] Place guest console output into the + hypervisor console ring buffer. This is disabled by default. + When enabled, both hypervisor output and guest console output + is available from the ring buffer. This can be useful for logging + and/or remote presentation of console data. \item [ sync\_console ] Force synchronous console output. This is useful if you system fails unexpectedly before it has sent all available output to the console. In most cases Xen will diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/coversheet.tex --- a/docs/xen-api/coversheet.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/coversheet.tex Wed Mar 21 18:08:31 2007 -0500 @@ -47,4 +47,4 @@ Date: \datestring{} \legalnotice{} \newpage -\pagestyle{plain} \ No newline at end of file +\pagestyle{fancy} \ No newline at end of file diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/presentation.tex --- a/docs/xen-api/presentation.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/presentation.tex Wed Mar 21 18:08:31 2007 -0500 @@ -57,14 +57,14 @@ type $t_1$ to values of type $t_2$. \end{itemize} Note that there are a number of cases where {\em Ref}s are {\em doubly -linked\/}---e.g.\ a VM has a field called {\tt groups} of type -$(\mathit{VMGroup}~\mathit{Ref})~\mathit{Set}$; this field lists -the VMGroups that a particular VM is part of. Similarly, the VMGroups -class has a field called {\tt VMs} of type $(\mathit{VM}~{\mathit -Ref})~\mathit{Set}$ that contains the VMs that are part of a particular -VMGroup. These two fields are {\em bound together\/}, in the sense that -adding a new VMGroup to a VM causes the VMs field of the corresponding -VMGroup object to be updated automatically. +linked\/}---e.g.\ a VM has a field called {\tt VIFs} of type +$(\mathit{VIF}~\mathit{Ref})~\mathit{Set}$; this field lists +the network interfaces attached to a particular VM. Similarly, the VIF +class has a field called {\tt VM} of type $(\mathit{VM}~{\mathit +Ref})$ which references the VM to which the interface is connected. +These two fields are {\em bound together\/}, in the sense that +creating a new VIF causes the {\tt VIFs} field of the corresponding +VM object to be updated automatically. The API reference explicitly lists the fields that are bound together in this way. It also contains a diagram that shows diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/todo.tex --- a/docs/xen-api/todo.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/todo.tex Wed Mar 21 18:08:31 2007 -0500 @@ -91,17 +91,10 @@ same subnet. \end{itemize} -\item TPM +\item ACM \begin{itemize} -\item Would it not be better to have a class TPM and a member TPMs ((TPM ref) -Set) containing an array of zero or one references to TPMs? I assume that -an empty array would make it clear that no TPM is associated with the VM -instead of encoding its existence into TPM/instance or TPM/backend -somehow. The current members instance and backend could then be moved into -the TPM class. - -\item Also a Xen system can be running an access control policy where each +\item A Xen system can be running an access control policy where each VM's run-time access to resources is restricted by the label it has been given compared to those of the resources. Currently a VM's configuration file may contain a line like access\_control[policy='$<$name of the system's diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/vm-lifecycle.tex --- a/docs/xen-api/vm-lifecycle.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/vm-lifecycle.tex Wed Mar 21 18:08:31 2007 -0500 @@ -22,3 +22,19 @@ Figure~\ref{fig-vm-lifecycle} shows the states that a VM can be in and the API calls that can be used to move the VM between these states. + +\section{VM boot parameters} + +The VM class contains a number of fields that control the way in which the VM is booted. +With reference to the fields defined in the VM class (see later in this document), +this section outlines the boot options available and the mechanisms provided for controlling them. + +VM booting is controlled by setting one of the two mutually exclusive groups: ``PV'', and ``HVM''. If HVM.boot\_policy is the empty string, then paravirtual domain building and booting will be used; otherwise the VM will be loaded as an HVM domain, and booted using an emulated BIOS. + +When paravirtual booting is in use, the PV/bootloader field indicates the bootloader to use. It may be ``pygrub'', in which case the platform's default installation of pygrub will be used, or a full path within the control domain to some other bootloader. The other fields, PV/kernel, PV/ramdisk, PV/args and PV/bootloader\_args will be passed to the bootloader unmodified, and interpretation of those fields is then specific to the bootloader itself, including the possibility that the bootloader will ignore some or all of those given values. Finally the paths of all bootable disks are added to the bootloader commandline (a disk is bootable if its VBD has the bootable flag set). There may be zero, one or many bootable disks; the bootloader decides which disk (if any) to boot from. + +If the bootloader is pygrub, then the menu.lst is parsed if present in the guest's filesystem, otherwise the specified kernel and ramdisk are used, or an autodetected kernel is used if nothing is specified and autodetection is possible. PV/args is appended to the kernel command line, no matter which mechanism is used for finding the kernel. + +If PV/bootloader is empty but PV/kernel is specified, then the kernel and ramdisk values will be treated as paths within the control domain. If both PV/bootloader and PV/kernel are empty, then the behaviour is as if PV/bootloader was specified as ``pygrub''. + +When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the boot handling. Only one policy is currently defined: ``BIOS order''. In this case, HVM/boot\_params should contain one key-value pair ``order'' = ``N'' where N is the string that will be passed to QEMU. \ No newline at end of file diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/wire-protocol.tex --- a/docs/xen-api/wire-protocol.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/wire-protocol.tex Wed Mar 21 18:08:31 2007 -0500 @@ -30,8 +30,13 @@ These types are mapped onto XML-RPC type \item Floats, Bools, DateTimes and Strings map directly to the XML-RPC {\tt double}, {\tt boolean}, {\tt dateTime.iso8601}, and {\tt string} elements. - \item all our ``{\tt ref\_}'' types (e.g.\ {\tt ref\_vm} in the above - example) map to XML-RPC's {\tt String} type. The string itself is the OSF + \item all ``{\tt ref\_}'' types are opaque references, encoded as the + XML-RPC's {\tt String} type. Users of the API should not make assumptions + about the concrete form of these strings and should not expect them to + remain valid after the client's session with the server has terminated. + + \item fields named ``{\tt uuid}'' of type ``{\tt String}'' are mapped to + the XML-RPC {\tt String} type. The string itself is the OSF DCE UUID presentation format (as output by {\tt uuidgen}, etc). \item ints are all assumed to be 64-bit in our API and are encoded as a @@ -82,6 +87,32 @@ These types are mapped onto XML-RPC type \item our {\tt Void} type is transmitted as an empty string. +\end{itemize} + +\subsection{Note on References vs UUIDs} + +References are opaque types --- encoded as XML-RPC strings on the wire --- understood +only by the particular server which generated them. Servers are free to choose +any concrete representation they find convenient; clients should not make any +assumptions or attempt to parse the string contents. References are not guaranteed +to be permanent identifiers for objects; clients should not assume that references +generated during one session are valid for any future session. References do not +allow objects to be compared for equality. Two references to the same object are +not guaranteed to be textually identical. + +UUIDs are intended to be permanent names for objects. They are +guaranteed to be in the OSF DCE UUID presentation format (as output by {\tt uuidgen}. +Clients may store UUIDs on disk and use them to lookup objects in subsequent sessions +with the server. Clients may also test equality on objects by comparing UUID strings. + +The API provides mechanisms +for translating between UUIDs and opaque references. Each class that contains a UUID +field provides: +\begin{itemize} +\item A ``{\tt get\_by\_uuid}'' method that takes a UUID, $u$, and returns an opaque reference +to the server-side object that has UUID=$u$; +\item A {\tt get\_uuid} function (a regular ``field getter'' RPC) that takes an opaque reference, +$r$, and returns the UUID of the server-side object that is referenced by $r$. \end{itemize} \subsection{Return Values/Status Codes} @@ -138,7 +169,7 @@ may look like this: \subsection{Transport Layer} -We ought to support at least +The following transport layers are currently supported: \begin{itemize} \item HTTP/S for remote administration \item HTTP over Unix domain sockets for local administration @@ -247,13 +278,12 @@ call takes the session token as the only \begin{verbatim} >>> all_vms = host.get_resident_VMs(session)['Value'] >>> all_vms -['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc', - '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e'] -\end{verbatim} - -The VM references here are UUIDs, though they may not be that simple in the -future, and you should treat them as opaque strings. Once a reference to a VM -has been acquired a lifecycle operation may be invoked: +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] +\end{verbatim} + +The VM references here have the form {\tt OpaqueRef:X}, though they may not be +that simple in the future, and you should treat them as opaque strings. +Once a reference to a VM has been acquired a lifecycle operation may be invoked: \begin{verbatim} >>> xen.VM.start(session, all_vms[3], False) diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/xenapi-datamodel.tex --- a/docs/xen-api/xenapi-datamodel.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/xenapi-datamodel.tex Wed Mar 21 18:08:31 2007 -0500 @@ -231,7 +231,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt last\_active} & int & Timestamp for last time session was active \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: session} +\subsection{RPCs associated with class: session} \subsubsection{RPC name:~login\_with\_password} {\bf Overview:} @@ -505,7 +505,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt allowed\_operations} & (task\_allowed\_operations) Set & Operations allowed on this task \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: task} +\subsection{RPCs associated with class: task} \subsubsection{RPC name:~cancel} {\bf Overview:} @@ -1022,40 +1022,7 @@ references to objects with match names \hline \multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VM} \\ \multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A -virtual machine (or 'guest'). - -VM booting is controlled by setting one of the two mutually exclusive -groups: "PV", and "HVM". If HVM.boot\_policy is the empty string, then -paravirtual domain building and booting will be used; otherwise the VM will -be loaded as an HVM domain, and booted using an emulated BIOS. - -When paravirtual booting is in use, the PV/bootloader field indicates the -bootloader to use. It may be "pygrub", in which case the platform's -default installation of pygrub will be used, or a full path within the -control domain to some other bootloader. The other fields, PV/kernel, -PV/ramdisk, PV/args and PV/bootloader\_args will be passed to the -bootloader unmodified, and interpretation of those fields is then specific -to the bootloader itself, including the possibility that the bootloader -will ignore some or all of those given values. Finally the paths of all -bootable disks are added to the bootloader commandline (a disk is bootable -if its VBD has the bootable flag set). There may be zero, one or many -bootable disks; the bootloader decides which disk (if any) to boot from. - -If the bootloader is pygrub, then the menu.lst is parsed if present in the -guest's filesystem, otherwise the specified kernel and ramdisk are used, or -an autodetected kernel is used if nothing is specified and autodetection is -possible. PV/args is appended to the kernel command line, no matter which -mechanism is used for finding the kernel. - -If PV/bootloader is empty but PV/kernel is specified, then the kernel and -ramdisk values will be treated as paths within the control domain. If both -PV/bootloader and PV/kernel are empty, then the behaviour is as if -PV/bootloader was specified as "pygrub". - -When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the -boot handling. Only one policy is currently defined: "BIOS order". In -this case, HVM/boot\_params should contain one key-value pair "order" = "N" -where N is the string that will be passed to QEMU.}} \\ +virtual machine (or 'guest').}} \\ \hline Quals & Field & Type & Description \\ \hline @@ -1072,7 +1039,6 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt memory/dynamic\_max} & int & Dynamic maximum (bytes) \\ $\mathit{RW}$ & {\tt memory/dynamic\_min} & int & Dynamic minimum (bytes) \\ $\mathit{RW}$ & {\tt memory/static\_min} & int & Statically-set (i.e. absolute) mininum (bytes) \\ -$\mathit{RW}$ & {\tt VCPUs/policy} & string & the name of the VCPU scheduling policy to be applied \\ $\mathit{RW}$ & {\tt VCPUs/params} & (string $\rightarrow$ string) Map & configuration parameters for the selected VCPU policy \\ $\mathit{RW}$ & {\tt VCPUs/max} & int & Max number of VCPUs \\ $\mathit{RW}$ & {\tt VCPUs/at\_startup} & int & Boot number of VCPUs \\ @@ -1091,12 +1057,8 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\ $\mathit{RW}$ & {\tt HVM/boot\_policy} & string & HVM boot policy \\ $\mathit{RW}$ & {\tt HVM/boot\_params} & (string $\rightarrow$ string) Map & HVM boot params \\ -$\mathit{RW}$ & {\tt platform/std\_VGA} & bool & emulate standard VGA instead of cirrus logic \\ -$\mathit{RW}$ & {\tt platform/serial} & string & redirect serial port to pty \\ -$\mathit{RW}$ & {\tt platform/localtime} & bool & set RTC to local time \\ -$\mathit{RW}$ & {\tt platform/clock\_offset} & bool & timeshift applied to guest's clock \\ -$\mathit{RW}$ & {\tt platform/enable\_audio} & bool & emulate audio \\ -$\mathit{RO}_\mathit{ins}$ & {\tt PCI\_bus} & string & PCI bus path for pass-through devices \\ +$\mathit{RW}$ & {\tt platform} & (string $\rightarrow$ string) Map & platform-specific configuration \\ +$\mathit{RW}$ & {\tt PCI\_bus} & string & PCI bus path for pass-through devices \\ $\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ $\mathit{RO}_\mathit{run}$ & {\tt domid} & int & domain ID (if available, -1 otherwise) \\ $\mathit{RO}_\mathit{run}$ & {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\ @@ -1104,7 +1066,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt guest\_metrics} & VM\_guest\_metrics ref & metrics associated with the running guest \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VM} +\subsection{RPCs associated with class: VM} \subsubsection{RPC name:~clone} {\bf Overview:} @@ -1178,7 +1140,8 @@ void \vspace{0.3cm} -\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE} +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}, {\tt +VM\_HVM\_REQUIRED} \vspace{0.6cm} \subsubsection{RPC name:~pause} @@ -1362,8 +1325,10 @@ void \vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE} + +\vspace{0.6cm} \subsubsection{RPC name:~hard\_reboot} {\bf Overview:} @@ -2212,72 +2177,6 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_VCPUs\_policy} - -{\bf Overview:} -Get the VCPUs/policy field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} string get_VCPUs_policy (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -string -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_VCPUs\_policy} - -{\bf Overview:} -Set the VCPUs/policy field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_VCPUs_policy (session_id s, VM ref self, string value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -{\tt string } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} \subsubsection{RPC name:~get\_VCPUs\_params} {\bf Overview:} @@ -3438,13 +3337,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_platform\_std\_VGA} - -{\bf Overview:} -Get the platform/std\_VGA field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_platform_std_VGA (session_id s, VM ref self)\end{verbatim} +\subsubsection{RPC name:~get\_platform} + +{\bf Overview:} +Get the platform field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_platform (session_id s, VM ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -3462,21 +3361,21 @@ Get the platform/std\_VGA field of the g \noindent {\bf Return Type:} {\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_platform\_std\_VGA} - -{\bf Overview:} -Set the platform/std\_VGA field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_platform_std_VGA (session_id s, VM ref self, bool value)\end{verbatim} +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_platform} + +{\bf Overview:} +Set the platform field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void set_platform (session_id s, VM ref self, (string -> string) Map value)\end{verbatim} \noindent{\bf Arguments:} @@ -3488,7 +3387,7 @@ Set the platform/std\_VGA field of the g {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VM ref } & self & reference to the object \\ \hline -{\tt bool } & value & New value to set \\ \hline +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline \end{tabular} @@ -3504,13 +3403,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_platform\_serial} - -{\bf Overview:} -Get the platform/serial field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} string get_platform_serial (session_id s, VM ref self)\end{verbatim} +\subsubsection{RPC name:~add\_to\_platform} + +{\bf Overview:} +Add the given key-value pair to the platform field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void add_to_platform (session_id s, VM ref self, string key, string value)\end{verbatim} \noindent{\bf Arguments:} @@ -3522,6 +3421,77 @@ Get the platform/serial field of the giv {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VM ref } & self & reference to the object \\ \hline +{\tt string } & key & Key to add \\ \hline + +{\tt string } & value & Value to add \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~remove\_from\_platform} + +{\bf Overview:} +Remove the given key and its corresponding value from the platform field of +the given VM. If the key is not in that Map, then do nothing. + + \noindent {\bf Signature:} +\begin{verbatim} void remove_from_platform (session_id s, VM ref self, string key)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +{\tt string } & key & Key to remove \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_PCI\_bus} + +{\bf Overview:} +Get the PCI\_bus field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} string get_PCI_bus (session_id s, VM ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + \end{tabular} \vspace{0.3cm} @@ -3536,13 +3506,13 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~set\_platform\_serial} - -{\bf Overview:} -Set the platform/serial field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_platform_serial (session_id s, VM ref self, string value)\end{verbatim} +\subsubsection{RPC name:~set\_PCI\_bus} + +{\bf Overview:} +Set the PCI\_bus field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void set_PCI_bus (session_id s, VM ref self, string value)\end{verbatim} \noindent{\bf Arguments:} @@ -3567,236 +3537,6 @@ void -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_platform\_localtime} - -{\bf Overview:} -Get the platform/localtime field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_platform_localtime (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_platform\_localtime} - -{\bf Overview:} -Set the platform/localtime field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_platform_localtime (session_id s, VM ref self, bool value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -{\tt bool } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_platform\_clock\_offset} - -{\bf Overview:} -Get the platform/clock\_offset field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_platform_clock_offset (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_platform\_clock\_offset} - -{\bf Overview:} -Set the platform/clock\_offset field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_platform_clock_offset (session_id s, VM ref self, bool value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -{\tt bool } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_platform\_enable\_audio} - -{\bf Overview:} -Get the platform/enable\_audio field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_platform_enable_audio (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_platform\_enable\_audio} - -{\bf Overview:} -Set the platform/enable\_audio field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_platform_enable_audio (session_id s, VM ref self, bool value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -{\tt bool } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_PCI\_bus} - -{\bf Overview:} -Get the PCI\_bus field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} string get_PCI_bus (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -string -} - - -value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -4245,7 +3985,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VM\_metrics} +\subsection{RPCs associated with class: VM\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -4481,7 +4221,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt other} & (string $\rightarrow$ string) Map & anything else \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VM\_guest\_metrics} +\subsection{RPCs associated with class: VM\_guest\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -4825,7 +4565,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt metrics} & host\_metrics ref & metrics associated with this host. \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: host} +\subsection{RPCs associated with class: host} \subsubsection{RPC name:~disable} {\bf Overview:} @@ -6078,7 +5818,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt memory/free} & int & Host's free memory (bytes) \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: host\_metrics} +\subsection{RPCs associated with class: host\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -6283,7 +6023,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt utilisation} & float & the current CPU utilisation \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: host\_cpu} +\subsection{RPCs associated with class: host\_cpu} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -6677,7 +6417,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt PIFs} & (PIF ref) Set & list of connected pifs \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: network} +\subsection{RPCs associated with class: network} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -7115,7 +6855,72 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF. \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VIF} +\subsection{RPCs associated with class: VIF} +\subsubsection{RPC name:~plug} + +{\bf Overview:} +Hotplug the specified VIF, dynamically attaching it to the running VM. + + \noindent {\bf Signature:} +\begin{verbatim} void plug (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & The VIF to hotplug \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~unplug} + +{\bf Overview:} +Hot-unplug the specified VIF, dynamically unattaching it from the running +VM. + + \noindent {\bf Signature:} +\begin{verbatim} void unplug (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & The VIF to hot-unplug \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -7942,7 +7747,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VIF\_metrics} +\subsection{RPCs associated with class: VIF\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -8148,7 +7953,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt metrics} & PIF\_metrics ref & metrics associated with this PIF. \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: PIF} +\subsection{RPCs associated with class: PIF} \subsubsection{RPC name:~create\_VLAN} {\bf Overview:} @@ -8719,7 +8524,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: PIF\_metrics} +\subsection{RPCs associated with class: PIF\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -8926,7 +8731,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt location} & string & a string that uniquely determines the location of the storage repository; the format of this string depends on the repository's type \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: SR} +\subsection{RPCs associated with class: SR} \subsubsection{RPC name:~clone} {\bf Overview:} @@ -9549,18 +9354,18 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ $\mathit{RW}$ & {\tt name/label} & string & a human-readable name \\ $\mathit{RW}$ & {\tt name/description} & string & a notes field containg human-readable description \\ -$\mathit{RW}$ & {\tt SR} & SR ref & storage repository in which the VDI resides \\ +$\mathit{RO}_\mathit{ins}$ & {\tt SR} & SR ref & storage repository in which the VDI resides \\ $\mathit{RO}_\mathit{run}$ & {\tt VBDs} & (VBD ref) Set & list of vbds that refer to this disk \\ $\mathit{RO}_\mathit{run}$ & {\tt crash\_dumps} & (crashdump ref) Set & list of crash dumps that refer to this disk \\ $\mathit{RW}$ & {\tt virtual\_size} & int & size of disk as presented to the guest (in bytes). Note that, depending on storage backend type, requested size may not be respected exactly \\ $\mathit{RO}_\mathit{run}$ & {\tt physical\_utilisation} & int & amount of physical space that the disk image is currently taking up on the storage repository (in bytes) \\ -$\mathit{RO}_\mathit{ins}$ & {\tt sector\_size} & int & sector size of VDI (in bytes) \\ $\mathit{RO}_\mathit{ins}$ & {\tt type} & vdi\_type & type of the VDI \\ $\mathit{RW}$ & {\tt sharable} & bool & true if this disk may be shared \\ $\mathit{RW}$ & {\tt read\_only} & bool & true if this disk may ONLY be mounted read-only \\ +$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VDI} +\subsection{RPCs associated with class: VDI} \subsubsection{RPC name:~snapshot} {\bf Overview:} @@ -9845,13 +9650,13 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~set\_SR} - -{\bf Overview:} -Set the SR field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} void set_SR (session_id s, VDI ref self, SR ref value)\end{verbatim} +\subsubsection{RPC name:~get\_VBDs} + +{\bf Overview:} +Get the VBDs field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} ((VBD ref) Set) get_VBDs (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -9863,7 +9668,103 @@ Set the SR field of the given VDI. {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -{\tt SR ref } & value & New value to set \\ \hline +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VBD ref) Set +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_crash\_dumps} + +{\bf Overview:} +Get the crash\_dumps field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} ((crashdump ref) Set) get_crash_dumps (session_id s, VDI ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VDI ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(crashdump ref) Set +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_virtual\_size} + +{\bf Overview:} +Get the virtual\_size field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} int get_virtual_size (session_id s, VDI ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VDI ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_virtual\_size} + +{\bf Overview:} +Set the virtual\_size field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} void set_virtual_size (session_id s, VDI ref self, int value)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VDI ref } & self & reference to the object \\ \hline + +{\tt int } & value & New value to set \\ \hline \end{tabular} @@ -9879,13 +9780,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_VBDs} - -{\bf Overview:} -Get the VBDs field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} ((VBD ref) Set) get_VBDs (session_id s, VDI ref self)\end{verbatim} +\subsubsection{RPC name:~get\_physical\_utilisation} + +{\bf Overview:} +Get the physical\_utilisation field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} int get_physical_utilisation (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -9903,21 +9804,21 @@ Get the VBDs field of the given VDI. \noindent {\bf Return Type:} {\tt -(VBD ref) Set -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_crash\_dumps} - -{\bf Overview:} -Get the crash\_dumps field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} ((crashdump ref) Set) get_crash_dumps (session_id s, VDI ref self)\end{verbatim} +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_type} + +{\bf Overview:} +Get the type field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} (vdi_type) get_type (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -9935,21 +9836,21 @@ Get the crash\_dumps field of the given \noindent {\bf Return Type:} {\tt -(crashdump ref) Set -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_virtual\_size} - -{\bf Overview:} -Get the virtual\_size field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} int get_virtual_size (session_id s, VDI ref self)\end{verbatim} +vdi\_type +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_sharable} + +{\bf Overview:} +Get the sharable field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} bool get_sharable (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -9967,21 +9868,21 @@ Get the virtual\_size field of the given \noindent {\bf Return Type:} {\tt -int -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_virtual\_size} - -{\bf Overview:} -Set the virtual\_size field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} void set_virtual_size (session_id s, VDI ref self, int value)\end{verbatim} +bool +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_sharable} + +{\bf Overview:} +Set the sharable field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} void set_sharable (session_id s, VDI ref self, bool value)\end{verbatim} \noindent{\bf Arguments:} @@ -9993,7 +9894,7 @@ Set the virtual\_size field of the given {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -{\tt int } & value & New value to set \\ \hline +{\tt bool } & value & New value to set \\ \hline \end{tabular} @@ -10009,13 +9910,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_physical\_utilisation} - -{\bf Overview:} -Get the physical\_utilisation field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} int get_physical_utilisation (session_id s, VDI ref self)\end{verbatim} +\subsubsection{RPC name:~get\_read\_only} + +{\bf Overview:} +Get the read\_only field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} bool get_read_only (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -10033,21 +9934,21 @@ Get the physical\_utilisation field of t \noindent {\bf Return Type:} {\tt -int -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_sector\_size} - -{\bf Overview:} -Get the sector\_size field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} int get_sector_size (session_id s, VDI ref self)\end{verbatim} +bool +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_read\_only} + +{\bf Overview:} +Set the read\_only field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} void set_read_only (session_id s, VDI ref self, bool value)\end{verbatim} \noindent{\bf Arguments:} @@ -10059,27 +9960,29 @@ Get the sector\_size field of the given {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -int -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_type} - -{\bf Overview:} -Get the type field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} (vdi_type) get_type (session_id s, VDI ref self)\end{verbatim} +{\tt bool } & value & New value to set \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_other\_config} + +{\bf Overview:} +Get the other\_config field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, VDI ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -10097,21 +10000,21 @@ Get the type field of the given VDI. \noindent {\bf Return Type:} {\tt -vdi\_type -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_sharable} - -{\bf Overview:} -Get the sharable field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_sharable (session_id s, VDI ref self)\end{verbatim} +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_other\_config} + +{\bf Overview:} +Set the other\_config field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} void set_other_config (session_id s, VDI ref self, (string -> string) Map value)\end{verbatim} \noindent{\bf Arguments:} @@ -10123,27 +10026,29 @@ Get the sharable field of the given VDI. {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_sharable} - -{\bf Overview:} -Set the sharable field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} void set_sharable (session_id s, VDI ref self, bool value)\end{verbatim} +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~add\_to\_other\_config} + +{\bf Overview:} +Add the given key-value pair to the other\_config field of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} void add_to_other_config (session_id s, VDI ref self, string key, string value)\end{verbatim} \noindent{\bf Arguments:} @@ -10155,7 +10060,9 @@ Set the sharable field of the given VDI. {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -{\tt bool } & value & New value to set \\ \hline +{\tt string } & key & Key to add \\ \hline + +{\tt string } & value & Value to add \\ \hline \end{tabular} @@ -10171,13 +10078,14 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_read\_only} - -{\bf Overview:} -Get the read\_only field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} bool get_read_only (session_id s, VDI ref self)\end{verbatim} +\subsubsection{RPC name:~remove\_from\_other\_config} + +{\bf Overview:} +Remove the given key and its corresponding value from the other\_config +field of the given VDI. If the key is not in that Map, then do nothing. + + \noindent {\bf Signature:} +\begin{verbatim} void remove_from_other_config (session_id s, VDI ref self, string key)\end{verbatim} \noindent{\bf Arguments:} @@ -10189,39 +10097,7 @@ Get the read\_only field of the given VD {\bf type} & {\bf name} & {\bf description} \\ \hline {\tt VDI ref } & self & reference to the object \\ \hline -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -bool -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_read\_only} - -{\bf Overview:} -Set the read\_only field of the given VDI. - - \noindent {\bf Signature:} -\begin{verbatim} void set_read_only (session_id s, VDI ref self, bool value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VDI ref } & self & reference to the object \\ \hline - -{\tt bool } & value & New value to set \\ \hline +{\tt string } & key & Key to remove \\ \hline \end{tabular} @@ -10426,7 +10302,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt metrics} & VBD\_metrics ref & metrics associated with this VBD \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VBD} +\subsection{RPCs associated with class: VBD} \subsubsection{RPC name:~media\_change} {\bf Overview:} @@ -10447,6 +10323,71 @@ devices, detach the VBD and attach a new {\tt VBD ref } & vbd & The vbd representing the CDROM-like device \\ \hline {\tt VDI ref } & vdi & The new VDI to 'insert' \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~plug} + +{\bf Overview:} +Hotplug the specified VBD, dynamically attaching it to the running VM. + + \noindent {\bf Signature:} +\begin{verbatim} void plug (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & The VBD to hotplug \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~unplug} + +{\bf Overview:} +Hot-unplug the specified VBD, dynamically unattaching it from the running +VM. + + \noindent {\bf Signature:} +\begin{verbatim} void unplug (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & The VBD to hot-unplug \\ \hline \end{tabular} @@ -11354,7 +11295,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VBD\_metrics} +\subsection{RPCs associated with class: VBD\_metrics} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -11556,7 +11497,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt currently\_attached} & bool & is the SR currently attached on this host? \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: PBD} +\subsection{RPCs associated with class: PBD} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -11884,7 +11825,39 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt VDI} & VDI ref & the virtual disk \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: crashdump} +\subsection{RPCs associated with class: crashdump} +\subsubsection{RPC name:~destroy} + +{\bf Overview:} +Destroy the specified crashdump. + + \noindent {\bf Signature:} +\begin{verbatim} void destroy (session_id s, crashdump ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt crashdump ref } & self & The crashdump to destroy \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -11999,70 +11972,6 @@ VDI ref value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~create} - -{\bf Overview:} -Create a new crashdump instance, and return its handle. - - \noindent {\bf Signature:} -\begin{verbatim} (crashdump ref) create (session_id s, crashdump record args)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt crashdump record } & args & All constructor arguments \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -crashdump ref -} - - -reference to the newly created object -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~destroy} - -{\bf Overview:} -Destroy the specified crashdump instance. - - \noindent {\bf Signature:} -\begin{verbatim} void destroy (session_id s, crashdump ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt crashdump ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -12148,7 +12057,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt backend} & VM ref & the domain where the backend is located \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: VTPM} +\subsection{RPCs associated with class: VTPM} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -12393,7 +12302,7 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: console} +\subsection{RPCs associated with class: console} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -12828,7 +12737,7 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt fullname} & string & full name \\ \hline \end{longtable} -\subsection{Additional RPCs associated with class: user} +\subsection{RPCs associated with class: user} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -13093,7 +13002,7 @@ all fields from the object \section{Class: debug} \subsection{Fields for class: debug} {\bf Class debug has no fields.} -\subsection{Additional RPCs associated with class: debug} +\subsection{RPCs associated with class: debug} \subsubsection{RPC name:~get\_all} {\bf Overview:} @@ -13467,6 +13376,15 @@ expected and actual VM state at the time \begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim} \begin{center}\rule{10em}{0.1pt}\end{center} +\subsubsection{VM\_HVM\_REQUIRED} + +HVM is required for this operation + +\vspace{0.3cm} +{\bf Signature:} +\begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim} +\begin{center}\rule{10em}{0.1pt}\end{center} + \newpage diff -r 2c087916aaba -r 49ec3725d0c0 docs/xen-api/xenapi.tex --- a/docs/xen-api/xenapi.tex Wed Mar 21 17:03:00 2007 -0500 +++ b/docs/xen-api/xenapi.tex Wed Mar 21 18:08:31 2007 -0500 @@ -16,6 +16,7 @@ \usepackage{a4wide} \usepackage{graphics} \usepackage{longtable} +\usepackage{fancyhdr} \setlength\topskip{0cm} \setlength\topmargin{0cm} @@ -35,7 +36,7 @@ \chapter{Introduction} -This document contains a proposal for a Xen Management API---an interface for +This document contains a description of the Xen Management API---an interface for remotely configuring and controlling virtualised guests running on a Xen-enabled host. diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/arch/x86/mm.c Wed Mar 21 18:08:31 2007 -0500 @@ -49,7 +49,7 @@ #endif unsigned long *phys_to_machine_mapping; -extern char *stack; +extern char stack[]; extern void page_walk(unsigned long virt_addr); void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, @@ -453,7 +453,7 @@ void arch_init_mm(unsigned long* start_p printk(" _text: %p\n", &_text); printk(" _etext: %p\n", &_etext); printk(" _edata: %p\n", &_edata); - printk(" stack start: %p\n", &stack); + printk(" stack start: %p\n", stack); printk(" _end: %p\n", &_end); /* First page follows page table pages and 3 more pages (store page etc) */ diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/gnttab.c --- a/extras/mini-os/gnttab.c Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/gnttab.c Wed Mar 21 18:08:31 2007 -0500 @@ -135,7 +135,7 @@ gnttab_alloc_and_grant(void **map) return gref; } -static const char *gnttabop_error_msgs[] = GNTTABOP_error_msgs; +static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs; const char * gnttabop_error(int16_t status) diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/hypervisor.c --- a/extras/mini-os/hypervisor.c Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/hypervisor.c Wed Mar 21 18:08:31 2007 -0500 @@ -35,8 +35,8 @@ void do_hypervisor_callback(struct pt_regs *regs) { - u32 l1, l2; - unsigned int l1i, l2i, port; + unsigned long l1, l2, l1i, l2i; + unsigned int port; int cpu = 0; shared_info_t *s = HYPERVISOR_shared_info; vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/include/wait.h --- a/extras/mini-os/include/wait.h Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/include/wait.h Wed Mar 21 18:08:31 2007 -0500 @@ -74,6 +74,13 @@ static inline void wake_up(struct wait_q local_irq_restore(flags); \ } while (0) +#define remove_waiter(w) do { \ + unsigned long flags; \ + local_irq_save(flags); \ + remove_wait_queue(&w); \ + local_irq_restore(flags); \ +} while (0) + #define wait_event(wq, condition) do{ \ unsigned long flags; \ if(condition) \ diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/include/xenbus.h --- a/extras/mini-os/include/xenbus.h Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/include/xenbus.h Wed Mar 21 18:08:31 2007 -0500 @@ -13,6 +13,7 @@ char *xenbus_read(xenbus_transaction_t x char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value); char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path); +void wait_for_watch(void); char* xenbus_wait_for_value(const char*,const char*); /* Associates a value with a path. Returns a malloc'd error string on diff -r 2c087916aaba -r 49ec3725d0c0 extras/mini-os/xenbus/xenbus.c --- a/extras/mini-os/xenbus/xenbus.c Wed Mar 21 17:03:00 2007 -0500 +++ b/extras/mini-os/xenbus/xenbus.c Wed Mar 21 18:08:31 2007 -0500 @@ -72,11 +72,12 @@ static void memcpy_from_ring(const void memcpy(dest + c1, ring, c2); } -static inline void wait_for_watch(void) +void wait_for_watch(void) { DEFINE_WAIT(w); add_waiter(w,watch_queue); schedule(); + remove_waiter(w); wake(current); } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -14,11 +14,11 @@ void generic_get_mtrr(unsigned int reg, void generic_get_mtrr(unsigned int reg, unsigned long *base, unsigned int *size, mtrr_type * type) { - dom0_op_t op; + struct xen_platform_op op; - op.cmd = DOM0_READ_MEMTYPE; + op.cmd = XENPF_read_memtype; op.u.read_memtype.reg = reg; - (void)HYPERVISOR_dom0_op(&op); + (void)HYPERVISOR_platform_op(&op); *size = op.u.read_memtype.nr_mfns; *base = op.u.read_memtype.mfn; @@ -36,12 +36,12 @@ unsigned int *usage_table; static void __init set_num_var_ranges(void) { - dom0_op_t op; + struct xen_platform_op op; for (num_var_ranges = 0; ; num_var_ranges++) { - op.cmd = DOM0_READ_MEMTYPE; + op.cmd = XENPF_read_memtype; op.u.read_memtype.reg = num_var_ranges; - if (HYPERVISOR_dom0_op(&op) != 0) + if (HYPERVISOR_platform_op(&op) != 0) break; } } @@ -64,15 +64,15 @@ int mtrr_add_page(unsigned long base, un unsigned int type, char increment) { int error; - dom0_op_t op; + struct xen_platform_op op; mutex_lock(&mtrr_mutex); - op.cmd = DOM0_ADD_MEMTYPE; + op.cmd = XENPF_add_memtype; op.u.add_memtype.mfn = base; op.u.add_memtype.nr_mfns = size; op.u.add_memtype.type = type; - error = HYPERVISOR_dom0_op(&op); + error = HYPERVISOR_platform_op(&op); if (error) { mutex_unlock(&mtrr_mutex); BUG_ON(error > 0); @@ -117,7 +117,7 @@ int mtrr_del_page(int reg, unsigned long unsigned long lbase; unsigned int lsize; int error = -EINVAL; - dom0_op_t op; + struct xen_platform_op op; mutex_lock(&mtrr_mutex); @@ -141,10 +141,10 @@ int mtrr_del_page(int reg, unsigned long goto out; } if (--usage_table[reg] < 1) { - op.cmd = DOM0_DEL_MEMTYPE; + op.cmd = XENPF_del_memtype; op.u.del_memtype.handle = 0; op.u.del_memtype.reg = reg; - error = HYPERVISOR_dom0_op(&op); + error = HYPERVISOR_platform_op(&op); if (error) { BUG_ON(error > 0); goto out; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -2510,10 +2510,10 @@ static int __init io_apic_bug_finalize(v if(sis_apic_bug == -1) sis_apic_bug = 0; if (is_initial_xendomain()) { - dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK }; + struct xen_platform_op op = { .cmd = XENPF_platform_quirk }; op.u.platform_quirk.quirk_id = sis_apic_bug ? QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL; - HYPERVISOR_dom0_op(&op); + HYPERVISOR_platform_op(&op); } return 0; } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -81,7 +81,7 @@ asmlinkage long sys_ioperm(unsigned long t->io_bitmap_ptr = bitmap; set_thread_flag(TIF_IO_BITMAP); - set_iobitmap.bitmap = (char *)bitmap; + set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap); set_iobitmap.nr_ports = IO_BITMAP_BITS; HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -71,12 +71,12 @@ static int do_microcode_update (const vo return -ENOMEM; if (copy_from_user(kbuf, ubuf, len) == 0) { - dom0_op_t op; + struct xen_platform_op op; - op.cmd = DOM0_MICROCODE; + op.cmd = XENPF_microcode_update; set_xen_guest_handle(op.u.microcode.data, kbuf); op.u.microcode.length = len; - err = HYPERVISOR_dom0_op(&op); + err = HYPERVISOR_platform_op(&op); } else err = -EFAULT; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -307,7 +307,8 @@ void exit_thread(void) if (unlikely(test_thread_flag(TIF_IO_BITMAP))) { struct task_struct *tsk = current; struct thread_struct *t = &tsk->thread; - struct physdev_set_iobitmap set_iobitmap = { 0 }; + struct physdev_set_iobitmap set_iobitmap; + memset(&set_iobitmap, 0, sizeof(set_iobitmap)); HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; @@ -606,7 +607,8 @@ struct task_struct fastcall * __switch_t } if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { - iobmp_op.bitmap = (char *)next->io_bitmap_ptr; + set_xen_guest_handle(iobmp_op.bitmap, + (char *)next->io_bitmap_ptr); iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0; mcl->op = __HYPERVISOR_physdev_op; mcl->args[0] = PHYSDEVOP_set_iobitmap; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -30,11 +30,11 @@ static void __devinit quirk_intel_irqbal raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); if (!(word & (1 << 13))) { - dom0_op_t op; + struct xen_platform_op op; printk(KERN_INFO "Disabling irq balancing and affinity\n"); - op.cmd = DOM0_PLATFORM_QUIRK; + op.cmd = XENPF_platform_quirk; op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING; - (void)HYPERVISOR_dom0_op(&op); + (void)HYPERVISOR_platform_op(&op); } /* put back the original value for config space*/ diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -435,7 +435,7 @@ int do_settimeofday(struct timespec *tv) s64 nsec; unsigned int cpu; struct shadow_time_info *shadow; - dom0_op_t op; + struct xen_platform_op op; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; @@ -460,11 +460,11 @@ int do_settimeofday(struct timespec *tv) __normalize_time(&sec, &nsec); if (is_initial_xendomain() && !independent_wallclock) { - op.cmd = DOM0_SETTIME; + op.cmd = XENPF_settime; op.u.settime.secs = sec; op.u.settime.nsecs = nsec; op.u.settime.system_time = shadow->system_timestamp; - HYPERVISOR_dom0_op(&op); + HYPERVISOR_platform_op(&op); update_wallclock(); } else if (independent_wallclock) { nsec -= shadow->system_timestamp; @@ -488,7 +488,7 @@ static void sync_xen_wallclock(unsigned { time_t sec; s64 nsec; - dom0_op_t op; + struct xen_platform_op op; if (!ntp_synced() || independent_wallclock || !is_initial_xendomain()) return; @@ -499,11 +499,11 @@ static void sync_xen_wallclock(unsigned nsec = xtime.tv_nsec + ((jiffies - wall_jiffies) * (u64)NS_PER_TICK); __normalize_time(&sec, &nsec); - op.cmd = DOM0_SETTIME; + op.cmd = XENPF_settime; op.u.settime.secs = sec; op.u.settime.nsecs = nsec; op.u.settime.system_time = processed_system_time; - HYPERVISOR_dom0_op(&op); + HYPERVISOR_platform_op(&op); update_wallclock(); @@ -907,6 +907,10 @@ static void setup_cpu0_timer_irq(void) BUG_ON(per_cpu(timer_irq, 0) < 0); } +static struct vcpu_set_periodic_timer xen_set_periodic_tick = { + .period_ns = NS_PER_TICK +}; + void __init time_init(void) { #ifdef CONFIG_HPET_TIMER @@ -919,6 +923,10 @@ void __init time_init(void) return; } #endif + + HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0, + &xen_set_periodic_tick); + get_time_values_from_xen(0); processed_system_time = per_cpu(shadow_time, 0).system_timestamp; @@ -976,8 +984,10 @@ EXPORT_SYMBOL(jiffies_to_st); */ static void stop_hz_timer(void) { + struct vcpu_set_singleshot_timer singleshot; unsigned int cpu = smp_processor_id(); unsigned long j; + int rc; cpu_set(cpu, nohz_cpu_mask); @@ -997,8 +1007,16 @@ static void stop_hz_timer(void) j = jiffies + 1; } - if (HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0) - BUG(); + singleshot.timeout_abs_ns = jiffies_to_st(j); + singleshot.flags = 0; + rc = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &singleshot); +#ifdef CONFIG_XEN_COMPAT_030004 + if (rc) { + BUG_ON(rc != -ENOSYS); + rc = HYPERVISOR_set_timer_op(singleshot.timeout_abs_ns); + } +#endif + BUG_ON(rc); } static void start_hz_timer(void) @@ -1030,6 +1048,8 @@ void time_resume(void) init_cpu_khz(); for_each_online_cpu(cpu) { + HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu, + &xen_set_periodic_tick); get_time_values_from_xen(cpu); per_cpu(processed_system_time, cpu) = per_cpu(shadow_time, 0).system_timestamp; @@ -1049,6 +1069,9 @@ int local_setup_timer(unsigned int cpu) int seq, irq; BUG_ON(cpu == 0); + + HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu, + &xen_set_periodic_tick); do { seq = read_seqbegin(&xtime_lock); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S Wed Mar 21 18:08:31 2007 -0500 @@ -28,5 +28,5 @@ #define NOTE_KERNELCAP_END ASM_ELF_NOTE_END NOTE_KERNELCAP_BEGIN(1, 1) -NOTE_KERNELCAP(1, "nosegneg") /* Change 1 back to 0 when glibc is fixed! */ +NOTE_KERNELCAP(0, "nosegneg") NOTE_KERNELCAP_END diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Mar 21 18:08:31 2007 -0500 @@ -146,7 +146,7 @@ void xen_tlb_flush_mask(cpumask_t *mask) if ( cpus_empty(*mask) ) return; op.cmd = MMUEXT_TLB_FLUSH_MULTI; - op.arg2.vcpumask = mask->bits; + set_xen_guest_handle(op.arg2.vcpumask, mask->bits); BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); } @@ -165,7 +165,7 @@ void xen_invlpg_mask(cpumask_t *mask, un return; op.cmd = MMUEXT_INVLPG_MULTI; op.arg1.linear_addr = ptr & PAGE_MASK; - op.arg2.vcpumask = mask->bits; + set_xen_guest_handle(op.arg2.vcpumask, mask->bits); BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -256,8 +256,9 @@ void pte_free(struct page *pte) unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT); if (!pte_write(*virt_to_ptep(va))) - BUG_ON(HYPERVISOR_update_va_mapping( - va, pfn_pte(pfn, PAGE_KERNEL), 0)); + if (HYPERVISOR_update_va_mapping( + va, pfn_pte(pfn, PAGE_KERNEL), 0)) + BUG(); } else clear_bit(PG_pinned, &pte->flags); @@ -600,7 +601,7 @@ static void pgd_walk(pgd_t *pgd_base, pg int g, u, m, rc; if (xen_feature(XENFEAT_auto_translated_physmap)) - return 0; + return; for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { if (pgd_none(*pgd)) @@ -672,14 +673,23 @@ void mm_pin_all(void) void mm_pin_all(void) { struct page *page; + unsigned long flags; if (xen_feature(XENFEAT_writable_page_tables)) return; + /* + * Allow uninterrupted access to the pgd_list. Also protects + * __pgd_pin() by disabling preemption. + * All other CPUs must be at a safe point (e.g., in stop_machine + * or offlined entirely). + */ + spin_lock_irqsave(&pgd_lock, flags); for (page = pgd_list; page; page = (struct page *)page->index) { if (!test_bit(PG_pinned, &page->flags)) __pgd_pin((pgd_t *)page_address(page)); } + spin_unlock_irqrestore(&pgd_lock, flags); } void _arch_dup_mmap(struct mm_struct *mm) diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Wed Mar 21 18:08:31 2007 -0500 @@ -21,7 +21,7 @@ #include <linux/gfp.h> #include <linux/module.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #include <xen/interface/memory.h> #include <xen/interface/xencomm.h> #include <xen/interface/version.h> diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Wed Mar 21 18:08:31 2007 -0500 @@ -20,7 +20,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #include <xen/interface/memory.h> #include <xen/interface/xencomm.h> #include <xen/interface/version.h> diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Wed Mar 21 18:08:31 2007 -0500 @@ -22,7 +22,7 @@ #include <linux/gfp.h> #include <linux/module.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #define __XEN__ #include <xen/interface/domctl.h> #include <xen/interface/sysctl.h> @@ -40,25 +40,25 @@ #define ROUND_DIV(v,s) (((v) + (s) - 1) / (s)) static int -xencomm_privcmd_dom0_op(privcmd_hypercall_t *hypercall) -{ - dom0_op_t kern_op; - dom0_op_t __user *user_op = (dom0_op_t __user *)hypercall->arg[0]; +xencomm_privcmd_platform_op(privcmd_hypercall_t *hypercall) +{ + struct xen_platform_op kern_op; + struct xen_platform_op __user *user_op = (struct xen_platform_op __user *)hypercall->arg[0]; struct xencomm_handle *op_desc; struct xencomm_handle *desc = NULL; int ret = 0; - if (copy_from_user(&kern_op, user_op, sizeof(dom0_op_t))) + if (copy_from_user(&kern_op, user_op, sizeof(struct xen_platform_op))) return -EFAULT; - if (kern_op.interface_version != DOM0_INTERFACE_VERSION) + if (kern_op.interface_version != XENPF_INTERFACE_VERSION) return -EACCES; op_desc = xencomm_create_inline(&kern_op); switch (kern_op.cmd) { default: - printk("%s: unknown dom0 cmd %d\n", __func__, kern_op.cmd); + printk("%s: unknown platform cmd %d\n", __func__, kern_op.cmd); return -ENOSYS; } @@ -67,10 +67,10 @@ xencomm_privcmd_dom0_op(privcmd_hypercal return ret; } - ret = xencomm_arch_hypercall_dom0_op(op_desc); + ret = xencomm_arch_hypercall_platform_op(op_desc); /* FIXME: should we restore the handle? */ - if (copy_to_user(user_op, &kern_op, sizeof(dom0_op_t))) + if (copy_to_user(user_op, &kern_op, sizeof(struct xen_platform_op))) ret = -EFAULT; if (desc) @@ -638,8 +638,8 @@ privcmd_hypercall(privcmd_hypercall_t *h privcmd_hypercall(privcmd_hypercall_t *hypercall) { switch (hypercall->op) { - case __HYPERVISOR_dom0_op: - return xencomm_privcmd_dom0_op(hypercall); + case __HYPERVISOR_platform_op: + return xencomm_privcmd_platform_op(hypercall); case __HYPERVISOR_domctl: return xencomm_privcmd_domctl(hypercall); case __HYPERVISOR_sysctl: diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -59,7 +59,7 @@ asmlinkage long sys_ioperm(unsigned long memset(bitmap, 0xff, IO_BITMAP_BYTES); t->io_bitmap_ptr = bitmap; - set_iobitmap.bitmap = (char *)bitmap; + set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap); set_iobitmap.nr_ports = IO_BITMAP_BITS; HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -50,7 +50,7 @@ #include <asm/pda.h> #include <asm/prctl.h> #include <asm/kdebug.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #include <xen/interface/physdev.h> #include <xen/interface/vcpu.h> #include <asm/desc.h> @@ -304,7 +304,8 @@ void exit_thread(void) struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); #endif #ifdef CONFIG_XEN - struct physdev_set_iobitmap iobmp_op = { 0 }; + struct physdev_set_iobitmap iobmp_op; + memset(&iobmp_op, 0, sizeof(iobmp_op)); #endif kfree(t->io_bitmap_ptr); @@ -540,7 +541,8 @@ __switch_to(struct task_struct *prev_p, } if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { - iobmp_op.bitmap = (char *)next->io_bitmap_ptr; + set_xen_guest_handle(iobmp_op.bitmap, + (char *)next->io_bitmap_ptr); iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0; mcl->op = __HYPERVISOR_physdev_op; mcl->args[0] = PHYSDEVOP_set_iobitmap; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -597,8 +597,10 @@ void __init xen_init_pt(void) early_make_page_readonly(level2_kernel_pgt, XENFEAT_writable_page_tables); - xen_pgd_pin(__pa_symbol(init_level4_pgt)); - xen_pgd_pin(__pa_symbol(init_level4_user_pgt)); + if (!xen_feature(XENFEAT_writable_page_tables)) { + xen_pgd_pin(__pa_symbol(init_level4_pgt)); + xen_pgd_pin(__pa_symbol(init_level4_user_pgt)); + } set_pgd((pgd_t *)(init_level4_user_pgt + 511), mk_kernel_pgd(__pa_symbol(level3_user_pgt))); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -79,14 +79,17 @@ void mm_pin(struct mm_struct *mm) spin_lock(&mm->page_table_lock); mm_walk(mm, PAGE_KERNEL_RO); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)mm->pgd, - pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO), - UVMF_TLB_FLUSH)); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__user_pgd(mm->pgd), - pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL_RO), - UVMF_TLB_FLUSH)); + if (HYPERVISOR_update_va_mapping( + (unsigned long)mm->pgd, + pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO), + UVMF_TLB_FLUSH)) + BUG(); + if (HYPERVISOR_update_va_mapping( + (unsigned long)__user_pgd(mm->pgd), + pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, + PAGE_KERNEL_RO), + UVMF_TLB_FLUSH)) + BUG(); xen_pgd_pin(__pa(mm->pgd)); /* kernel */ xen_pgd_pin(__pa(__user_pgd(mm->pgd))); /* user */ mm->context.pinned = 1; @@ -106,12 +109,15 @@ void mm_unpin(struct mm_struct *mm) xen_pgd_unpin(__pa(mm->pgd)); xen_pgd_unpin(__pa(__user_pgd(mm->pgd))); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)mm->pgd, - pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0)); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__user_pgd(mm->pgd), - pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL), 0)); + if (HYPERVISOR_update_va_mapping( + (unsigned long)mm->pgd, + pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0)) + BUG(); + if (HYPERVISOR_update_va_mapping( + (unsigned long)__user_pgd(mm->pgd), + pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, + PAGE_KERNEL), 0)) + BUG(); mm_walk(mm, PAGE_KERNEL); xen_tlb_flush(); mm->context.pinned = 0; @@ -127,43 +133,50 @@ void mm_pin_all(void) if (xen_feature(XENFEAT_writable_page_tables)) return; + /* + * Allow uninterrupted access to the mm_unpinned list. We don't + * actually take the mm_unpinned_lock as it is taken inside mm_pin(). + * All other CPUs must be at a safe point (e.g., in stop_machine + * or offlined entirely). + */ + preempt_disable(); while (!list_empty(&mm_unpinned)) mm_pin(list_entry(mm_unpinned.next, struct mm_struct, context.unpinned)); + preempt_enable(); } void _arch_dup_mmap(struct mm_struct *mm) { - if (!mm->context.pinned) - mm_pin(mm); + if (!mm->context.pinned) + mm_pin(mm); } void _arch_exit_mmap(struct mm_struct *mm) { - struct task_struct *tsk = current; - - task_lock(tsk); - - /* - * We aggressively remove defunct pgd from cr3. We execute unmap_vmas() - * *much* faster this way, as no tlb flushes means bigger wrpt batches. - */ - if ( tsk->active_mm == mm ) - { - tsk->active_mm = &init_mm; - atomic_inc(&init_mm.mm_count); - - switch_mm(mm, &init_mm, tsk); - - atomic_dec(&mm->mm_count); - BUG_ON(atomic_read(&mm->mm_count) == 0); - } - - task_unlock(tsk); - - if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) && - !mm->context.has_foreign_mappings ) - mm_unpin(mm); + struct task_struct *tsk = current; + + task_lock(tsk); + + /* + * We aggressively remove defunct pgd from cr3. We execute unmap_vmas() + * *much* faster this way, as no tlb flushes means bigger wrpt batches. + */ + if (tsk->active_mm == mm) { + tsk->active_mm = &init_mm; + atomic_inc(&init_mm.mm_count); + + switch_mm(mm, &init_mm, tsk); + + atomic_dec(&mm->mm_count); + BUG_ON(atomic_read(&mm->mm_count) == 0); + } + + task_unlock(tsk); + + if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) && + !mm->context.has_foreign_mappings ) + mm_unpin(mm); } struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) @@ -183,8 +196,9 @@ void pte_free(struct page *pte) unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT); if (!pte_write(*virt_to_ptep(va))) - BUG_ON(HYPERVISOR_update_va_mapping( - va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0)); + if (HYPERVISOR_update_va_mapping( + va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0)) + BUG(); ClearPageForeign(pte); init_page_count(pte); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c Wed Mar 21 18:08:31 2007 -0500 @@ -504,7 +504,6 @@ static struct tpm_vendor_specific tpm_vt }; struct tpm_chip *init_vtpm(struct device *dev, - struct tpm_virtual_device *tvd, struct tpm_private *tp) { long rc; @@ -516,7 +515,6 @@ struct tpm_chip *init_vtpm(struct device return ERR_PTR(-ENOMEM); vtpm_state_init(vtpms); - vtpms->tpmvd = tvd; vtpms->tpm_private = tp; chip = tpm_register_hardware(dev, &tpm_vtpm); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h Wed Mar 21 18:08:31 2007 -0500 @@ -3,16 +3,6 @@ struct tpm_chip; struct tpm_private; - -struct tpm_virtual_device { - /* - * This field indicates the maximum size the driver can - * transfer in one chunk. It is filled in by the front-end - * driver and should be propagated to the generic tpm driver - * for allocation of buffers. - */ - unsigned int max_tx_size; -}; struct vtpm_state { struct transmission *current_request; @@ -30,8 +20,6 @@ struct vtpm_state { unsigned long disconnect_time; - struct tpm_virtual_device *tpmvd; - /* * The following is a private structure of the underlying * driver. It is passed as parameter in the send function. @@ -51,7 +39,6 @@ int vtpm_vd_send(struct tpm_private * tp /* these functions are offered by tpm_vtpm.c */ struct tpm_chip *init_vtpm(struct device *, - struct tpm_virtual_device *, struct tpm_private *); void cleanup_vtpm(struct device *); int vtpm_vd_recv(const struct tpm_chip* chip, diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Wed Mar 21 18:08:31 2007 -0500 @@ -369,10 +369,6 @@ static void backend_changed(struct xenbu } } -struct tpm_virtual_device tvd = { - .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE, -}; - static int tpmfront_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { @@ -383,7 +379,7 @@ static int tpmfront_probe(struct xenbus_ if (!tp) return -ENOMEM; - tp->chip = init_vtpm(&dev->dev, &tvd, tp); + tp->chip = init_vtpm(&dev->dev, tp); if (IS_ERR(tp->chip)) return PTR_ERR(tp->chip); @@ -500,11 +496,6 @@ static void __init init_tpm_xenbus(void) xenbus_register_frontend(&tpmfront); } -static void __exit exit_tpm_xenbus(void) -{ - xenbus_unregister_driver(&tpmfront); -} - static int tpmif_allocate_tx_buffers(struct tpm_private *tp) { unsigned int i; @@ -530,13 +521,11 @@ static void tpmif_rx_action(unsigned lon static void tpmif_rx_action(unsigned long priv) { struct tpm_private *tp = (struct tpm_private *)priv; - int i = 0; unsigned int received; unsigned int offset = 0; u8 *buffer; - tpmif_tx_request_t *tx; - tx = &tp->tx->ring[i].req; + tpmif_tx_request_t *tx = &tp->tx->ring[i].req; atomic_set(&tp->tx_busy, 0); wake_up_interruptible(&tp->wait_q); @@ -545,7 +534,7 @@ static void tpmif_rx_action(unsigned lon buffer = kmalloc(received, GFP_ATOMIC); if (!buffer) - goto exit; + return; for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) { struct tx_buffer *txb = tp->tx_buffers[i]; @@ -566,10 +555,6 @@ static void tpmif_rx_action(unsigned lon vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember); kfree(buffer); - -exit: - - return; } @@ -730,13 +715,6 @@ static int __init tpmif_init(void) } -void __exit tpmif_exit(void) -{ - exit_tpm_xenbus(); - tpm_private_put(); - gnttab_free_grant_references(gref_head); -} - module_init(tpmif_init); MODULE_LICENSE("Dual BSD/GPL"); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/Kconfig --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Wed Mar 21 18:08:31 2007 -0500 @@ -13,7 +13,7 @@ if XEN if XEN config XEN_INTERFACE_VERSION hex - default 0x00030203 + default 0x00030205 menu "XEN" @@ -227,6 +227,9 @@ choice config XEN_COMPAT_030002_AND_LATER bool "3.0.2 and later" + config XEN_COMPAT_030004_AND_LATER + bool "3.0.4 and later" + config XEN_COMPAT_LATEST_ONLY bool "no compatibility code" @@ -236,6 +239,10 @@ config XEN_COMPAT_030002 bool default XEN_COMPAT_030002_AND_LATER +config XEN_COMPAT_030004 + bool + default XEN_COMPAT_030002_AND_LATER || XEN_COMPAT_030004_AND_LATER + endmenu config HAVE_IRQ_IGNORE_UNHANDLED diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Wed Mar 21 18:08:31 2007 -0500 @@ -299,7 +299,9 @@ static void tap_backend_changed(struct x * and disk info to xenstore */ err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info, - NULL); + NULL); + if (XENBUS_EXIST_ERR(err)) + return; if (err) { xenbus_dev_error(dev, err, "getting info"); return; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/char/mem.c --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Wed Mar 21 18:08:31 2007 -0500 @@ -27,7 +27,7 @@ #include <asm/hypervisor.h> #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE -static inline int valid_phys_addr_range(unsigned long addr, size_t *count) +static inline int valid_phys_addr_range(unsigned long addr, size_t count) { return 1; } @@ -44,7 +44,7 @@ static ssize_t read_mem(struct file * fi ssize_t read = 0, sz; void __iomem *v; - if (!valid_phys_addr_range(p, &count)) + if (!valid_phys_addr_range(p, count)) return -EFAULT; while (count > 0) { @@ -95,7 +95,7 @@ static ssize_t write_mem(struct file * f ssize_t written = 0, sz; void __iomem *v; - if (!valid_phys_addr_range(p, &count)) + if (!valid_phys_addr_range(p, count)) return -EFAULT; while (count > 0) { diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Mar 21 18:08:31 2007 -0500 @@ -348,8 +348,11 @@ void xencons_rx(char *buf, unsigned len, #ifdef CONFIG_MAGIC_SYSRQ if (sysrq_enabled) { if (buf[i] == '\x0f') { /* ^O */ - sysrq_requested = jiffies; - continue; /* don't print the sysrq key */ + if (!sysrq_requested) { + sysrq_requested = jiffies; + continue; /* don't print sysrq key */ + } + sysrq_requested = 0; } else if (sysrq_requested) { unsigned long sysrq_timeout = sysrq_requested + HZ*2; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Wed Mar 21 18:08:31 2007 -0500 @@ -11,7 +11,6 @@ #include <asm/mmu_context.h> #include <xen/evtchn.h> #include <asm/hypervisor.h> -#include <xen/interface/dom0_ops.h> #include <xen/xenbus.h> #include <linux/cpu.h> #include <linux/kthread.h> @@ -85,7 +84,7 @@ static void post_suspend(int suspend_can pfn_to_mfn(xen_start_info->console.domU.mfn); } else { #ifdef CONFIG_SMP - cpu_initialized_map = cpumask_of_cpu(0); + cpu_initialized_map = cpu_online_map; #endif } @@ -181,20 +180,6 @@ static int take_machine_down(void *p_fas time_resume(); local_irq_enable(); - if (fast_suspend && !suspend_cancelled) { - /* - * In fast-suspend mode the APs may not be brought back online - * when we resume. In that case we do it here. - */ - for_each_online_cpu(cpu) { - if (cpu == 0) - continue; - cpu_set_initialized(cpu); - err = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); - BUG_ON(err); - } - } - return suspend_cancelled; } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Mar 21 18:08:31 2007 -0500 @@ -110,6 +110,7 @@ static unsigned int alloc_index = 0; static inline unsigned long alloc_mfn(void) { + BUG_ON(alloc_index == 0); return mfn_list[--alloc_index]; } @@ -552,6 +553,7 @@ static void net_rx_action(unsigned long *(int *)skb->cb = nr_frags; if (!xen_feature(XENFEAT_auto_translated_physmap) && + !((netif_t *)netdev_priv(skb->dev))->copying_receiver && check_mfn(nr_frags + 1)) { /* Memory squeeze? Back off for an arbitrary while. */ if ( net_ratelimit() ) @@ -1265,7 +1267,7 @@ static void net_tx_action(unsigned long /* Check the remap error code. */ if (unlikely(netbk_tx_check_mop(skb, &mop))) { - printk(KERN_ALERT "#### netback grant fails\n"); + DPRINTK("netback grant failed.\n"); skb_shinfo(skb)->nr_frags = 0; kfree_skb(skb); continue; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c Wed Mar 21 18:08:31 2007 -0500 @@ -349,16 +349,12 @@ void pciback_config_free_dev(struct pci_ int pciback_config_add_field_offset(struct pci_dev *dev, struct config_field *field, - unsigned int offset) + unsigned int base_offset) { int err = 0; struct pciback_dev_data *dev_data = pci_get_drvdata(dev); struct config_field_entry *cfg_entry; void *tmp; - - /* silently ignore duplicate fields */ - if (pciback_field_is_dup(dev, field->offset)) - goto out; cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL); if (!cfg_entry) { @@ -368,7 +364,12 @@ int pciback_config_add_field_offset(stru cfg_entry->data = NULL; cfg_entry->field = field; - cfg_entry->base_offset = offset; + cfg_entry->base_offset = base_offset; + + /* silently ignore duplicate fields */ + err = pciback_field_is_dup(dev,OFFSET(cfg_entry)); + if (err) + goto out; if (field->init) { tmp = field->init(dev, OFFSET(cfg_entry)); diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c Wed Mar 21 18:08:31 2007 -0500 @@ -32,16 +32,14 @@ static inline void register_quirk(struct list_add_tail(&quirk->quirks_list, &pciback_quirks); } -int pciback_field_is_dup(struct pci_dev *dev, int reg) +int pciback_field_is_dup(struct pci_dev *dev, unsigned int reg) { int ret = 0; struct pciback_dev_data *dev_data = pci_get_drvdata(dev); - struct config_field *field; struct config_field_entry *cfg_entry; list_for_each_entry(cfg_entry, &dev_data->config_fields, list) { - field = cfg_entry->field; - if (field->offset == reg) { + if ( OFFSET(cfg_entry) == reg) { ret = 1; break; } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h Wed Mar 21 18:08:31 2007 -0500 @@ -30,6 +30,6 @@ void pciback_config_field_free(struct co int pciback_config_quirk_release(struct pci_dev *dev); -int pciback_field_is_dup(struct pci_dev *dev, int reg); +int pciback_field_is_dup(struct pci_dev *dev, unsigned int reg); #endif diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Wed Mar 21 18:08:31 2007 -0500 @@ -589,10 +589,6 @@ static int pcistub_reg_add(int domain, i } dev = psdev->dev; - /* check for duplicate field */ - if (pciback_field_is_dup(dev, reg)) - goto out; - field = kzalloc(sizeof(*field), GFP_ATOMIC); if (!field) { err = -ENOMEM; @@ -728,10 +724,10 @@ static ssize_t pcistub_quirk_show(struct if (count >= PAGE_SIZE) goto out; - count += scnprintf(buf + count, PAGE_SIZE - - count, "\t\t%08x:%01x:%08x\n", - field->offset, field->size, - field->mask); + count += scnprintf(buf + count, PAGE_SIZE - count, + "\t\t%08x:%01x:%08x\n", + cfg_entry->base_offset + field->offset, + field->size, field->mask); } } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Mar 21 18:08:31 2007 -0500 @@ -28,7 +28,6 @@ #include <asm/hypervisor.h> #include <xen/public/privcmd.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> #include <xen/xen_proc.h> static struct proc_dir_entry *privcmd_intf; diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Mar 21 18:08:31 2007 -0500 @@ -110,7 +110,6 @@ int xb_write(const void *data, unsigned /* Read indexes, then verify. */ cons = intf->req_cons; prod = intf->req_prod; - mb(); if (!check_indexes(cons, prod)) { intf->req_cons = intf->req_prod = 0; return -EIO; @@ -122,15 +121,18 @@ int xb_write(const void *data, unsigned if (avail > len) avail = len; + /* Must write data /after/ reading the consumer index. */ + mb(); + memcpy(dst, data, avail); data += avail; len -= avail; - /* Other side must not see new header until data is there. */ + /* Other side must not see new producer until data is there. */ wmb(); intf->req_prod += avail; - /* This implies mb() before other side sees interrupt. */ + /* Implies mb(): other side will see the updated producer. */ notify_remote_via_evtchn(xen_store_evtchn); } @@ -165,7 +167,6 @@ int xb_read(void *data, unsigned len) /* Read indexes, then verify. */ cons = intf->rsp_cons; prod = intf->rsp_prod; - mb(); if (!check_indexes(cons, prod)) { intf->rsp_cons = intf->rsp_prod = 0; return -EIO; @@ -177,7 +178,7 @@ int xb_read(void *data, unsigned len) if (avail > len) avail = len; - /* We must read header before we read data. */ + /* Must read data /after/ reading the producer index. */ rmb(); memcpy(data, src, avail); @@ -190,7 +191,7 @@ int xb_read(void *data, unsigned len) pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); - /* Implies mb(): they will see new header. */ + /* Implies mb(): other side will see the updated consumer. */ notify_remote_via_evtchn(xen_store_evtchn); } diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-i386/kexec.h --- a/linux-2.6-xen-sparse/include/asm-i386/kexec.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-i386/kexec.h Wed Mar 21 18:08:31 2007 -0500 @@ -46,6 +46,9 @@ /* The native architecture */ #define KEXEC_ARCH KEXEC_ARCH_386 + +/* We can also handle crash dumps from 64 bit kernel. */ +#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) #define MAX_NOTE_BYTES 1024 diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Wed Mar 21 18:08:31 2007 -0500 @@ -201,11 +201,11 @@ HYPERVISOR_set_timer_op( } static inline int -HYPERVISOR_dom0_op( - dom0_op_t *dom0_op) -{ - dom0_op->interface_version = DOM0_INTERFACE_VERSION; - return _hypercall1(int, dom0_op, dom0_op); +HYPERVISOR_platform_op( + struct xen_platform_op *platform_op) +{ + platform_op->interface_version = XENPF_INTERFACE_VERSION; + return _hypercall1(int, platform_op, platform_op); } static inline int diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Wed Mar 21 18:08:31 2007 -0500 @@ -38,7 +38,7 @@ #include <linux/version.h> #include <linux/errno.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #include <xen/interface/event_channel.h> #include <xen/interface/physdev.h> #include <xen/interface/sched.h> diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h Wed Mar 21 18:08:31 2007 -0500 @@ -143,11 +143,4 @@ static inline void pci_dma_burst_advice( /* generic pci stuff */ #include <asm-generic/pci.h> -/* On Xen we have to scan all functions since Xen hides bridges from - * us. If a bridge is at fn=0 and that slot has a multifunction - * device, we won't find the additional devices without scanning all - * functions. */ -#undef pcibios_scan_all_fns -#define pcibios_scan_all_fns(a, b) 1 - #endif /* __i386_PCI_H */ diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Mar 21 18:08:31 2007 -0500 @@ -120,9 +120,9 @@ HYPERVISOR_set_timer_op(u64 timeout) } static inline int -xencomm_arch_hypercall_dom0_op(struct xencomm_handle *op) -{ - return _hypercall1(int, dom0_op, op); +xencomm_arch_hypercall_platform_op(struct xencomm_handle *op) +{ + return _hypercall1(int, platform_op, op); } static inline int diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Wed Mar 21 18:08:31 2007 -0500 @@ -51,7 +51,7 @@ extern int running_on_xen; #include <linux/version.h> #include <linux/errno.h> #include <xen/interface/xen.h> -#include <xen/interface/dom0_ops.h> +#include <xen/interface/platform.h> #include <xen/interface/event_channel.h> #include <xen/interface/physdev.h> #include <xen/interface/sched.h> diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Wed Mar 21 18:08:31 2007 -0500 @@ -204,11 +204,11 @@ HYPERVISOR_set_timer_op( } static inline int -HYPERVISOR_dom0_op( - dom0_op_t *dom0_op) -{ - dom0_op->interface_version = DOM0_INTERFACE_VERSION; - return _hypercall1(int, dom0_op, dom0_op); +HYPERVISOR_platform_op( + struct xen_platform_op *platform_op) +{ + platform_op->interface_version = XENPF_INTERFACE_VERSION; + return _hypercall1(int, platform_op, platform_op); } static inline int diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h Wed Mar 21 18:08:31 2007 -0500 @@ -163,11 +163,4 @@ static inline void pcibios_add_platform_ #include <asm-generic/pci.h> #endif -/* On Xen we have to scan all functions since Xen hides bridges from - * us. If a bridge is at fn=0 and that slot has a multifunction - * device, we won't find the additional devices without scanning all - * functions. */ -#undef pcibios_scan_all_fns -#define pcibios_scan_all_fns(a, b) 1 - #endif /* __x8664_PCI_H */ diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/kernel/kexec.c --- a/linux-2.6-xen-sparse/kernel/kexec.c Wed Mar 21 17:03:00 2007 -0500 +++ b/linux-2.6-xen-sparse/kernel/kexec.c Wed Mar 21 18:08:31 2007 -0500 @@ -330,13 +330,27 @@ static int kimage_is_destination_range(s return 0; } -static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order) +static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order, unsigned long limit) { struct page *pages; pages = alloc_pages(gfp_mask, order); if (pages) { unsigned int count, i; +#ifdef CONFIG_XEN + int address_bits; + + if (limit == ~0UL) + address_bits = BITS_PER_LONG; + else + address_bits = long_log2(limit); + + if (xen_create_contiguous_region((unsigned long)page_address(pages), + order, address_bits) < 0) { + __free_pages(pages, order); + return NULL; + } +#endif pages->mapping = NULL; set_page_private(pages, order); count = 1 << order; @@ -355,6 +369,9 @@ static void kimage_free_pages(struct pag count = 1 << order; for (i = 0; i < count; i++) ClearPageReserved(page + i); +#ifdef CONFIG_XEN + xen_destroy_contiguous_region((unsigned long)page_address(page), order); +#endif __free_pages(page, order); } @@ -400,7 +417,7 @@ static struct page *kimage_alloc_normal_ do { unsigned long pfn, epfn, addr, eaddr; - pages = kimage_alloc_pages(GFP_KERNEL, order); + pages = kimage_alloc_pages(GFP_KERNEL, order, KEXEC_CONTROL_MEMORY_LIMIT); if (!pages) break; pfn = kexec_page_to_pfn(pages); @@ -709,7 +726,7 @@ static struct page *kimage_alloc_page(st kimage_entry_t *old; /* Allocate a page, if we run out of memory give up */ - page = kimage_alloc_pages(gfp_mask, 0); + page = kimage_alloc_pages(gfp_mask, 0, KEXEC_SOURCE_MEMORY_LIMIT); if (!page) return NULL; /* If the page cannot be used file it away */ diff -r 2c087916aaba -r 49ec3725d0c0 linux-2.6-xen-sparse/mm/Kconfig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/mm/Kconfig Wed Mar 21 18:08:31 2007 -0500 @@ -0,0 +1,157 @@ +config SELECT_MEMORY_MODEL + def_bool y + depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL + +choice + prompt "Memory model" + depends on SELECT_MEMORY_MODEL + default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT + default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT + default FLATMEM_MANUAL + +config FLATMEM_MANUAL + bool "Flat Memory" + depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE + help + This option allows you to change some of the ways that + Linux manages its memory internally. Most users will + only have one option here: FLATMEM. This is normal + and a correct option. + + Some users of more advanced features like NUMA and + memory hotplug may have different options here. + DISCONTIGMEM is an more mature, better tested system, + but is incompatible with memory hotplug and may suffer + decreased performance over SPARSEMEM. If unsure between + "Sparse Memory" and "Discontiguous Memory", choose + "Discontiguous Memory". + + If unsure, choose this option (Flat Memory) over any other. + +config DISCONTIGMEM_MANUAL + bool "Discontiguous Memory" + depends on ARCH_DISCONTIGMEM_ENABLE + help + This option provides enhanced support for discontiguous + memory systems, over FLATMEM. These systems have holes + in their physical address spaces, and this option provides + more efficient handling of these holes. However, the vast + majority of hardware has quite flat address spaces, and + can have degraded performance from extra overhead that + this option imposes. + + Many NUMA configurations will have this as the only option. + + If unsure, choose "Flat Memory" over this option. + +config SPARSEMEM_MANUAL + bool "Sparse Memory" + depends on ARCH_SPARSEMEM_ENABLE + help + This will be the only option for some systems, including + memory hotplug systems. This is normal. + + For many other systems, this will be an alternative to + "Discontiguous Memory". This option provides some potential + performance benefits, along with decreased code complexity, + but it is newer, and more experimental. + + If unsure, choose "Discontiguous Memory" or "Flat Memory" + over this option. + +endchoice + +config DISCONTIGMEM + def_bool y + depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL + +config SPARSEMEM + def_bool y + depends on SPARSEMEM_MANUAL + +config FLATMEM + def_bool y + depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL + +config FLAT_NODE_MEM_MAP + def_bool y + depends on !SPARSEMEM + +# +# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's +# to represent different areas of memory. This variable allows +# those dependencies to exist individually. +# +config NEED_MULTIPLE_NODES + def_bool y + depends on DISCONTIGMEM || NUMA + +config HAVE_MEMORY_PRESENT + def_bool y + depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM + +# +# SPARSEMEM_EXTREME (which is the default) does some bootmem +# allocations when memory_present() is called. If this can not +# be done on your architecture, select this option. However, +# statically allocating the mem_section[] array can potentially +# consume vast quantities of .bss, so be careful. +# +# This option will also potentially produce smaller runtime code +# with gcc 3.4 and later. +# +config SPARSEMEM_STATIC + def_bool n + +# +# Architectecture platforms which require a two level mem_section in SPARSEMEM +# must select this option. This is usually for architecture platforms with +# an extremely sparse physical address space. +# +config SPARSEMEM_EXTREME + def_bool y + depends on SPARSEMEM && !SPARSEMEM_STATIC + +# eventually, we can have this option just 'select SPARSEMEM' +config MEMORY_HOTPLUG + bool "Allow for memory hot-add" + depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG + depends on (IA64 || X86 || PPC64) + +comment "Memory hotplug is currently incompatible with Software Suspend" + depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND + +# Heavily threaded applications may benefit from splitting the mm-wide +# page_table_lock, so that faults on different parts of the user address +# space can be handled with less contention: split it at this NR_CPUS. +# Default to 4 for wider testing, though 8 might be more appropriate. +# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock. +# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes. +# XEN on x86 architecture uses the mapping field on pagetable pages to store a +# pointer to the destructor. This conflicts with pte_lock_deinit(). +# +config SPLIT_PTLOCK_CPUS + int + default "4096" if ARM && !CPU_CACHE_VIPT + default "4096" if PARISC && !PA20 + default "4096" if X86_XEN || X86_64_XEN + default "4" + +# +# support for page migration +# +config MIGRATION + bool "Page migration" + def_bool y + depends on NUMA + help + Allows the migration of the physical location of pages of processes + while the virtual addresses are not changed. This is useful for + example on NUMA systems to put pages nearer to the processors accessing + the page. + +config RESOURCES_64BIT + bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL) + default 64BIT + help + This option allows memory and IO resources to be 64 bit. diff -r 2c087916aaba -r 49ec3725d0c0 patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch Wed Mar 21 18:08:31 2007 -0500 @@ -0,0 +1,30 @@ +From: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> + +In file included from arch/i386/kernel/setup.c:46: +include/linux/crash_dump.h:19:36: warning: extra tokens at end of #ifndef directive + +Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> +Cc: Andi Kleen <ak@xxxxxxx> +Cc: Horms <horms@xxxxxxxxxxxx> +Cc: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> +Cc: Magnus Damm <magnus.damm@xxxxxxxxx> +Cc: Vivek Goyal <vgoyal@xxxxxxxxxx> +Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> +--- + + include/linux/crash_dump.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix include/linux/crash_dump.h +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix ++++ a/include/linux/crash_dump.h +@@ -16,7 +16,7 @@ extern struct proc_dir_entry *proc_vmcor + + /* Architecture code defines this if there are other possible ELF + * machine types, e.g. on bi-arch capable hardware. */ +-#ifndef vmcore_elf_check_arch_cross(x) ++#ifndef vmcore_elf_check_arch_cross + #define vmcore_elf_check_arch_cross(x) 0 + #endif + +_ diff -r 2c087916aaba -r 49ec3725d0c0 patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps.patch Wed Mar 21 18:08:31 2007 -0500 @@ -0,0 +1,66 @@ +From: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> + +The specific case I am encountering is kdump under Xen with a 64 bit +hypervisor and 32 bit kernel/userspace. The dump created is 64 bit due to +the hypervisor but the dump kernel is 32 bit for maximum compatibility. + +It's possibly less likely to be useful in a purely native scenario but I +see no reason to disallow it. + +Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> +Acked-by: Vivek Goyal <vgoyal@xxxxxxxxxx> +Cc: Horms <horms@xxxxxxxxxxxx> +Cc: Magnus Damm <magnus.damm@xxxxxxxxx> +Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> +Cc: Andi Kleen <ak@xxxxxxx> +Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> +--- + + fs/proc/vmcore.c | 2 +- + include/asm-i386/kexec.h | 3 +++ + include/linux/crash_dump.h | 8 ++++++++ + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff -puN fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps fs/proc/vmcore.c +--- a/fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps ++++ a/fs/proc/vmcore.c +@@ -514,7 +514,7 @@ static int __init parse_crash_elf64_head + /* Do some basic Verification. */ + if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || + (ehdr.e_type != ET_CORE) || +- !elf_check_arch(&ehdr) || ++ !vmcore_elf_check_arch(&ehdr) || + ehdr.e_ident[EI_CLASS] != ELFCLASS64 || + ehdr.e_ident[EI_VERSION] != EV_CURRENT || + ehdr.e_version != EV_CURRENT || +diff -puN include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/asm-i386/kexec.h +--- a/include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps ++++ a/include/asm-i386/kexec.h +@@ -47,6 +47,9 @@ + /* The native architecture */ + #define KEXEC_ARCH KEXEC_ARCH_386 + ++/* We can also handle crash dumps from 64 bit kernel. */ ++#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64) ++ + #define MAX_NOTE_BYTES 1024 + + /* CPU does not save ss and esp on stack if execution is already +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/linux/crash_dump.h +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps ++++ a/include/linux/crash_dump.h +@@ -14,5 +14,13 @@ extern ssize_t copy_oldmem_page(unsigned + extern const struct file_operations proc_vmcore_operations; + extern struct proc_dir_entry *proc_vmcore; + ++/* Architecture code defines this if there are other possible ELF ++ * machine types, e.g. on bi-arch capable hardware. */ ++#ifndef vmcore_elf_check_arch_cross(x) ++#define vmcore_elf_check_arch_cross(x) 0 ++#endif ++ ++#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) ++ + #endif /* CONFIG_CRASH_DUMP */ + #endif /* LINUX_CRASHDUMP_H */ +_ diff -r 2c087916aaba -r 49ec3725d0c0 patches/linux-2.6.18/series --- a/patches/linux-2.6.18/series Wed Mar 21 17:03:00 2007 -0500 +++ b/patches/linux-2.6.18/series Wed Mar 21 18:08:31 2007 -0500 @@ -19,3 +19,5 @@ fixaddr-top.patch fixaddr-top.patch git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch softlockup-no-idle-hz.patch +allow-i386-crash-kernels-to-handle-x86_64-dumps.patch +allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch diff -r 2c087916aaba -r 49ec3725d0c0 patches/linux-2.6.18/softlockup-no-idle-hz.patch --- a/patches/linux-2.6.18/softlockup-no-idle-hz.patch Wed Mar 21 17:03:00 2007 -0500 +++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch Wed Mar 21 18:08:31 2007 -0500 @@ -34,7 +34,7 @@ diff -pruN ../orig-linux-2.6.18/kernel/s + !per_cpu(watchdog_task, this_cpu)) + return MAX_JIFFY_OFFSET; + -+ return min_t(long, 0, touch_timestamp + HZ - jiffies); ++ return max_t(long, 0, touch_timestamp + HZ - jiffies); +} + /* diff -r 2c087916aaba -r 49ec3725d0c0 tools/Rules.mk --- a/tools/Rules.mk Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/Rules.mk Wed Mar 21 18:08:31 2007 -0500 @@ -22,6 +22,11 @@ LDFLAGS += $(shell getconf LFS_LDFLAGS) # 32-bit x86 does not perform well with -ve segment accesses on Xen. CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs) CFLAGS += $(CFLAGS-y) + +# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers) +ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn) +$(error Xen tools require at least gcc-3.4) +endif %.opic: %.c $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< diff -r 2c087916aaba -r 49ec3725d0c0 tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/blktap/drivers/block-qcow.c Wed Mar 21 18:08:31 2007 -0500 @@ -1057,6 +1057,7 @@ int tdqcow_queue_write(struct disk_drive index_in_cluster+n); if (!cluster_offset) { DPRINTF("Ooops, no write cluster offset!\n"); + aio_unlock(s, sector); return cb(dd, -EIO, sector, nb_sectors, id, private); } diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/Makefile --- a/tools/firmware/Makefile Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/Makefile Wed Mar 21 18:08:31 2007 -0500 @@ -14,10 +14,10 @@ SUBDIRS += hvmloader .PHONY: all all: - @set -e; if ! `which bcc 1>/dev/null 2>/dev/null`; then \ + @set -e; if [ $$((`( bcc -v 2>&1 | grep version || echo 0.0.0 ) | cut -d' ' -f 3 | awk -F. '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -lt $$((0x00100e)) ] ; then \ echo "***********************************************************"; \ - echo "WARNING: Install dev86 package to build firmware!"; \ - echo " (http://www.cix.co.uk/~mayday)"; \ + echo "Require dev86 package version >= 0.16.14 to build firmware!"; \ + echo "(visit http://www.cix.co.uk/~mayday for more information)"; \ echo "***********************************************************"; \ else \ for subdir in $(SUBDIRS); do \ diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/32bitbios_support.c --- a/tools/firmware/hvmloader/32bitbios_support.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/32bitbios_support.c Wed Mar 21 18:08:31 2007 -0500 @@ -17,158 +17,129 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. */ + #include <inttypes.h> #include <elf.h> #ifdef __sun__ #include <sys/machelf.h> #endif -#include <xen/hvm/e820.h> #include "util.h" #include "config.h" #include "../rombios/32bit/32bitbios_flat.h" #include "../rombios/32bit/jumptable.h" - -/* - * relocate ELF file of type ET_REL - */ -static int relocate_elf(unsigned char *elfarray) { +/* Relocate ELF file of type ET_REL */ +static void relocate_elf(char *elfarray) +{ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; - int i; + Elf32_Sym *syms, *sym; + Elf32_Rel *rels; + char *code; + uint32_t *loc, fix; + int i, j; - if (ehdr->e_type != ET_REL) { - printf("Not a relocatable BIOS object file. Has type %d, need %d\n", - ehdr->e_type, ET_REL); - return -1; - } + for ( i = 0; i < ehdr->e_shnum; i++ ) + shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset]; - for (i = 0; i < ehdr->e_shnum; i++) { - if (!(shdr[i]).sh_flags & SHF_ALLOC) { - shdr[i].sh_addr = 0; + for ( i = 0; i < ehdr->e_shnum; i++ ) + { + if ( shdr[i].sh_type == SHT_RELA ) + printf("Unsupported section type SHT_RELA\n"); + + if ( shdr[i].sh_type != SHT_REL ) continue; - } - shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset]; - } - for (i = 0; i < ehdr->e_shnum; i++) { - if (shdr[i].sh_type == SHT_REL && shdr[i].sh_addr != 0) { - Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]); - Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]); - Elf32_Sym *syms = (Elf32_Sym *)symtabsec->sh_addr; - Elf32_Rel *rels = (Elf32_Rel *)shdr[i].sh_addr; - unsigned char *code = (unsigned char *)targetsec->sh_addr; - int j; + syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr; + rels = (Elf32_Rel *)shdr[i].sh_addr; + code = (char *)shdr[shdr[i].sh_info].sh_addr; - for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) { - int idx = ELF32_R_SYM(rels[j].r_info); - Elf32_Sym *symbol = &syms[idx]; - uint32_t *loc = (uint32_t *)&code[rels[j].r_offset]; - uint32_t fix = shdr[symbol->st_shndx].sh_addr + - symbol->st_value; + for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ ) + { + sym = &syms[ELF32_R_SYM(rels[j].r_info)]; + loc = (uint32_t *)&code[rels[j].r_offset]; + fix = shdr[sym->st_shndx].sh_addr + sym->st_value; - switch (ELF32_R_TYPE(rels[j].r_info)) { - case R_386_PC32: - *loc += (fix - (uint32_t)loc); - break; + switch ( ELF32_R_TYPE(rels[j].r_info) ) + { + case R_386_PC32: + *loc += fix - (uint32_t)loc; + break; - case R_386_32: - *loc += fix; - break; - } + case R_386_32: + *loc += fix; + break; } - } else if (shdr[i].sh_type == SHT_RELA) { - return -2; } } - return 0; } -/* scan the rombios for the destination of the jumptable */ -static char* get_jump_table_start(void) +/* Scan the rombios for the destination of the jump table. */ +static char *get_jump_table_start(void) { char *bios_mem; for ( bios_mem = (char *)ROMBIOS_BEGIN; bios_mem != (char *)ROMBIOS_END; - bios_mem++ ) { - if (strncmp(bios_mem, "___JMPT", 7) == 0) + bios_mem++ ) + if ( !strncmp(bios_mem, "___JMPT", 7) ) return bios_mem; - } return NULL; } -/* copy relocated jumptable into the rombios */ -static int copy_jumptable(unsigned char *elfarray) +/* Copy relocated jumptable into the rombios. */ +static void copy_jumptable(char *elfarray) { - int rc = 0; Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; - Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx]; - char *secstrings = (char *)&elfarray[shdr_strings->sh_offset]; - uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start(); - uint32_t *biosjumptable = NULL; + char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset]; + char *jump_table = get_jump_table_start(); int i; - if (rombiosjumptable == NULL) { - return -3; + /* Find the section with the jump table and copy to lower BIOS memory. */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) ) + break; + + if ( i == ehdr->e_shnum ) + { + printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); + return; } - /* find the section with the jump table and copy to lower BIOS memory */ - for (i = 0; i < ehdr->e_shnum; i++) { - if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) { - uint32_t biosjumptableentries; - biosjumptable = (uint32_t *)shdr[i].sh_addr; - biosjumptableentries = shdr[i].sh_size / 4; - for (int j = 0; j < biosjumptableentries; j++) { - rombiosjumptable[j] = biosjumptable[j]; - if (biosjumptable[j] == 0 && - j < (biosjumptableentries - 1)) { - printf("WARNING: jumptable entry %d is NULL!\n",j); - } - } - break; - } + if ( jump_table == NULL ) + { + printf("Could not find jump table in file.\n"); + return; } - if (biosjumptable == NULL) { - printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); - rc = -4; + memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size); +} + +static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize) +{ + uint32_t mask = (64 * 1024) - 1; + char *highbiosarea; + + highbiosarea = (char *)(long) + e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */ + E820_RESERVED, + (uint64_t)0xffffffff); + if ( highbiosarea == NULL ) + { + printf("No available memory for BIOS high memory area\n"); + return; } - return 0; + memcpy(highbiosarea, elfarray, elfarraysize); + relocate_elf(highbiosarea); + copy_jumptable(highbiosarea); } -static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize) +void highbios_setup(void) { - int rc = 0; - uint32_t mask = (64 * 1024) - 1; - uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */ - unsigned char *highbiosarea; - - highbiosarea = (unsigned char *)(long) - e820_malloc((uint64_t)to_malloc, - E820_RESERVED, - (uint64_t)0xffffffff); - - if (highbiosarea != 0) { - memcpy(highbiosarea, elfarray, elfarraysize); - rc = relocate_elf(highbiosarea); - if (rc == 0) { - rc = copy_jumptable(highbiosarea); - } - } else { - rc = -5; - } - - return rc; + relocate_32bitbios((char *)highbios_array, sizeof(highbios_array)); } - -int highbios_setup(void) -{ - return relocate_32bitbios((unsigned char *)highbios_array, - sizeof(highbios_array)); -} diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/acpi/acpi2_0.h --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Wed Mar 21 18:08:31 2007 -0500 @@ -49,8 +49,8 @@ struct acpi_header { uint32_t length; uint8_t revision; uint8_t checksum; - uint8_t oem_id[6]; - uint8_t oem_table_id[8]; + char oem_id[6]; + char oem_table_id[8]; uint32_t oem_revision; uint32_t creator_id; uint32_t creator_revision; @@ -90,7 +90,7 @@ struct acpi_10_rsdp { struct acpi_10_rsdp { uint64_t signature; uint8_t checksum; - uint8_t oem_id[6]; + char oem_id[6]; uint8_t reserved; uint32_t rsdt_address; }; @@ -101,7 +101,7 @@ struct acpi_20_rsdp { struct acpi_20_rsdp { uint64_t signature; uint8_t checksum; - uint8_t oem_id[6]; + char oem_id[6]; uint8_t revision; uint32_t rsdt_address; uint32_t length; @@ -143,9 +143,9 @@ struct acpi_20_tcpa { #define ACPI_2_0_TCPA_LAML_SIZE (64*1024) /* - * Fixed ACPI Description Table Structure (FADT). - */ -struct acpi_20_fadt { + * Fixed ACPI Description Table Structure (FADT) in ACPI 1.0. + */ +struct acpi_10_fadt { struct acpi_header header; uint32_t firmware_ctrl; uint32_t dsdt; @@ -185,6 +185,51 @@ struct acpi_20_fadt { uint16_t iapc_boot_arch; uint8_t reserved1; uint32_t flags; +}; + +/* + * Fixed ACPI Description Table Structure (FADT). + */ +struct acpi_20_fadt { + struct acpi_header header; + uint32_t firmware_ctrl; + uint32_t dsdt; + uint8_t reserved0; + uint8_t preferred_pm_profile; + uint16_t sci_int; + uint32_t smi_cmd; + uint8_t acpi_enable; + uint8_t acpi_disable; + uint8_t s4bios_req; + uint8_t pstate_cnt; + uint32_t pm1a_evt_blk; + uint32_t pm1b_evt_blk; + uint32_t pm1a_cnt_blk; + uint32_t pm1b_cnt_blk; + uint32_t pm2_cnt_blk; + uint32_t pm_tmr_blk; + uint32_t gpe0_blk; + uint32_t gpe1_blk; + uint8_t pm1_evt_len; + uint8_t pm1_cnt_len; + uint8_t pm2_cnt_len; + uint8_t pm_tmr_len; + uint8_t gpe0_blk_len; + uint8_t gpe1_blk_len; + uint8_t gpe1_base; + uint8_t cst_cnt; + uint16_t p_lvl2_lat; + uint16_t p_lvl3_lat; + uint16_t flush_size; + uint16_t flush_stride; + uint8_t duty_offset; + uint8_t duty_width; + uint8_t day_alrm; + uint8_t mon_alrm; + uint8_t century; + uint16_t iapc_boot_arch; + uint8_t reserved1; + uint32_t flags; struct acpi_20_generic_address reset_reg; uint8_t reset_value; uint8_t reserved2[3]; @@ -345,6 +390,7 @@ struct acpi_20_madt_intsrcovr { #define ACPI_2_0_XSDT_REVISION 0x01 #define ACPI_2_0_TCPA_REVISION 0x02 #define ACPI_2_0_HPET_REVISION 0x01 +#define ACPI_1_0_FADT_REVISION 0x01 #pragma pack () diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/acpi/build.c Wed Mar 21 18:08:31 2007 -0500 @@ -20,9 +20,9 @@ #include "ssdt_tpm.h" #include "../config.h" #include "../util.h" -#include <xen/hvm/e820.h> - -#define align16(sz) (((sz) + 15) & ~15) + +#define align16(sz) (((sz) + 15) & ~15) +#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d)) extern struct acpi_20_rsdp Rsdp; extern struct acpi_20_rsdt Rsdt; @@ -57,8 +57,8 @@ int construct_madt(struct acpi_20_madt * memset(madt, 0, sizeof(*madt)); madt->header.signature = ACPI_2_0_MADT_SIGNATURE; madt->header.revision = ACPI_2_0_MADT_REVISION; - strncpy(madt->header.oem_id, ACPI_OEM_ID, 6); - strncpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID, 8); + fixed_strcpy(madt->header.oem_id, ACPI_OEM_ID); + fixed_strcpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID); madt->header.oem_revision = ACPI_OEM_REVISION; madt->header.creator_id = ACPI_CREATOR_ID; madt->header.creator_revision = ACPI_CREATOR_REVISION; @@ -131,8 +131,8 @@ int construct_hpet(struct acpi_20_hpet * memset(hpet, 0, sizeof(*hpet)); hpet->header.signature = ACPI_2_0_HPET_SIGNATURE; hpet->header.revision = ACPI_2_0_HPET_REVISION; - strncpy(hpet->header.oem_id, ACPI_OEM_ID, 6); - strncpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID, 8); + fixed_strcpy(hpet->header.oem_id, ACPI_OEM_ID); + fixed_strcpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID); hpet->header.oem_revision = ACPI_OEM_REVISION; hpet->header.creator_id = ACPI_CREATOR_ID; hpet->header.creator_revision = ACPI_CREATOR_REVISION; @@ -150,6 +150,7 @@ int construct_processor_objects(uint8_t { static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 }; static const char hex[] = "0123456789ABCDEF"; + static const char pr_scope[] = "\\_PR_"; unsigned int i, length, nr_cpus = get_vcpu_nr(); struct acpi_header *hdr; uint8_t *p = buf; @@ -161,8 +162,8 @@ int construct_processor_objects(uint8_t hdr = (struct acpi_header *)p; hdr->signature = ASCII32('S','S','D','T'); hdr->revision = 2; - strncpy(hdr->oem_id, ACPI_OEM_ID, 6); - strncpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID, 8); + fixed_strcpy(hdr->oem_id, ACPI_OEM_ID); + fixed_strcpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID); hdr->oem_revision = ACPI_OEM_REVISION; hdr->creator_id = ACPI_CREATOR_ID; hdr->creator_revision = ACPI_CREATOR_REVISION; @@ -176,7 +177,7 @@ int construct_processor_objects(uint8_t *p++ = 0x10; /* PkgLength (includes length bytes!). */ - length = 1 + 5 + (nr_cpus * sizeof(pdat)); + length = 1 + strlen(pr_scope) + (nr_cpus * sizeof(pdat)); if ( length <= 0x3f ) { *p++ = length; @@ -195,8 +196,8 @@ int construct_processor_objects(uint8_t } /* NameString */ - strncpy(p, "\\_PR_", 5); - p += 5; + strncpy(p, pr_scope, strlen(pr_scope)); + p += strlen(pr_scope); /* * 3. Processor Objects. @@ -263,8 +264,8 @@ int construct_secondary_tables(uint8_t * tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE; tcpa->header.length = sizeof(*tcpa); tcpa->header.revision = ACPI_2_0_TCPA_REVISION; - strncpy(tcpa->header.oem_id, ACPI_OEM_ID, 6); - strncpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID, 8); + fixed_strcpy(tcpa->header.oem_id, ACPI_OEM_ID); + fixed_strcpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID); tcpa->header.oem_revision = ACPI_OEM_REVISION; tcpa->header.creator_id = ACPI_CREATOR_ID; tcpa->header.creator_revision = ACPI_CREATOR_REVISION; @@ -291,6 +292,7 @@ int acpi_build_tables(uint8_t *buf) struct acpi_20_rsdt *rsdt; struct acpi_20_xsdt *xsdt; struct acpi_20_fadt *fadt; + struct acpi_10_fadt *fadt_10; struct acpi_20_facs *facs; unsigned char *dsdt; unsigned long secondary_tables[16]; @@ -303,6 +305,25 @@ int acpi_build_tables(uint8_t *buf) dsdt = (unsigned char *)&buf[offset]; memcpy(dsdt, &AmlCode, DsdtLen); offset += align16(DsdtLen); + + /* + * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2 + * or above properly, notably Windows 2000, which tries to copy FADT + * into a 116 bytes buffer thus causing an overflow. The solution is to + * link the higher revision FADT with the XSDT only and introduce a + * compatible revision 1 FADT that is linked with the RSDT. Refer to: + * http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt + */ + fadt_10 = (struct acpi_10_fadt *)&buf[offset]; + memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt)); + offset += align16(sizeof(struct acpi_10_fadt)); + fadt_10->header.length = sizeof(struct acpi_10_fadt); + fadt_10->header.revision = ACPI_1_0_FADT_REVISION; + fadt_10->dsdt = (unsigned long)dsdt; + fadt_10->firmware_ctrl = (unsigned long)facs; + set_checksum(fadt_10, + offsetof(struct acpi_header, checksum), + sizeof(struct acpi_10_fadt)); fadt = (struct acpi_20_fadt *)&buf[offset]; memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt)); @@ -330,7 +351,7 @@ int acpi_build_tables(uint8_t *buf) rsdt = (struct acpi_20_rsdt *)&buf[offset]; memcpy(rsdt, &Rsdt, sizeof(struct acpi_header)); - rsdt->entry[0] = (unsigned long)fadt; + rsdt->entry[0] = (unsigned long)fadt_10; for ( i = 0; secondary_tables[i]; i++ ) rsdt->entry[i+1] = secondary_tables[i]; rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t); diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/hvmloader.c Wed Mar 21 18:08:31 2007 -0500 @@ -29,7 +29,6 @@ #include "pci_regs.h" #include <xen/version.h> #include <xen/hvm/params.h> -#include <xen/hvm/e820.h> /* memory map */ #define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 @@ -38,23 +37,53 @@ #define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 -/* invoke SVM's paged realmode support */ -#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001 - -/* - * C runtime start off - */ asm( " .text \n" " .globl _start \n" "_start: \n" + /* C runtime kickoff. */ " cld \n" " cli \n" + " movl $stack_top,%esp \n" + " movl %esp,%ebp \n" + " call main \n" + /* Relocate real-mode trampoline to 0x0. */ + " mov $trampoline_start,%esi \n" + " xor %edi,%edi \n" + " mov $trampoline_end,%ecx \n" + " sub %esi,%ecx \n" + " rep movsb \n" + /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */ " lgdt gdt_desr \n" - " movl $stack_top, %esp \n" - " movl %esp, %ebp \n" - " call main \n" - " ud2 \n" + " mov $0x0010,%ax \n" + " mov %ax,%ds \n" + " mov %ax,%es \n" + " mov %ax,%fs \n" + " mov %ax,%gs \n" + " mov %ax,%ss \n" + /* Initialise all 32-bit GPRs to zero. */ + " xor %eax,%eax \n" + " xor %ebx,%ebx \n" + " xor %ecx,%ecx \n" + " xor %edx,%edx \n" + " xor %esp,%esp \n" + " xor %ebp,%ebp \n" + " xor %esi,%esi \n" + " xor %edi,%edi \n" + /* Enter real mode, reload all segment registers and IDT. */ + " ljmp $0x8,$0x0 \n" + "trampoline_start: .code16 \n" + " mov %eax,%cr0 \n" + " ljmp $0,$1f-trampoline_start\n" + "1: mov %ax,%ds \n" + " mov %ax,%es \n" + " mov %ax,%fs \n" + " mov %ax,%gs \n" + " mov %ax,%ss \n" + " lidt 1f-trampoline_start \n" + " ljmp $0xf000,$0xfff0 \n" + "1: .word 0x3ff,0,0 \n" + "trampoline_end: .code32 \n" " \n" "gdt_desr: \n" " .word gdt_end - gdt - 1 \n" @@ -63,8 +92,8 @@ asm( " .align 8 \n" "gdt: \n" " .quad 0x0000000000000000 \n" - " .quad 0x00CF92000000FFFF \n" - " .quad 0x00CF9A000000FFFF \n" + " .quad 0x00009a000000ffff \n" /* Ring 0 code, base 0 limit 0xffff */ + " .quad 0x000092000000ffff \n" /* Ring 0 data, base 0 limit 0xffff */ "gdt_end: \n" " \n" " .bss \n" @@ -81,19 +110,6 @@ cirrus_check(void) { outw(0x3C4, 0x9206); return inb(0x3C5) == 0x12; -} - -static int -vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx) -{ - int eax; - - __asm__ __volatile__ ( - ".byte 0x0F,0x01,0xD9" - : "=a" (eax) - : "a"(function), - "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) ); - return eax; } static int @@ -280,25 +296,57 @@ static void pci_setup(void) } } -static -int must_load_nic(void) -{ - /* If the network card is in the boot order, load the Etherboot - * option ROM. Read the boot order bytes from CMOS and check - * if any of them are 0x4. */ +/* + * If the network card is in the boot order, load the Etherboot option ROM. + * Read the boot order bytes from CMOS and check if any of them are 0x4. + */ +static int must_load_nic(void) +{ uint8_t boot_order; - /* Read CMOS register 0x3d (boot choices 0 and 1) */ - outb(0x70, 0x3d); - boot_order = inb(0x71); - if ( (boot_order & 0xf) == 0x4 || (boot_order & 0xf0) == 0x40 ) + /* Read CMOS register 0x3d (boot choices 0 and 1). */ + boot_order = cmos_inb(0x3d); + if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) ) return 1; - /* Read CMOS register 0x38 (boot choice 2 and FDD test flag) */ - outb(0x70, 0x38); - boot_order = inb(0x71); - if ( (boot_order & 0xf0) == 0x40 ) - return 1; - return 0; + + /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */ + boot_order = cmos_inb(0x38); + return ((boot_order & 0xf0) == 0x40); +} + +/* Replace possibly erroneous memory-size CMOS fields with correct values. */ +static void cmos_write_memory_size(void) +{ + struct e820entry *map = E820_MAP; + int i, nr = *E820_MAP_NR; + uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0; + + for ( i = 0; i < nr; i++ ) + if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) ) + break; + + if ( i != nr ) + { + alt_mem = ext_mem = map[i].addr + map[i].size; + ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0; + if ( ext_mem > 0xffff ) + ext_mem = 0xffff; + alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0; + } + + /* All BIOSes: conventional memory (640kB). */ + cmos_outb(0x15, (uint8_t)(base_mem >> 0)); + cmos_outb(0x16, (uint8_t)(base_mem >> 8)); + + /* All BIOSes: extended memory (1kB chunks above 1MB). */ + cmos_outb(0x17, (uint8_t)( ext_mem >> 0)); + cmos_outb(0x18, (uint8_t)( ext_mem >> 8)); + cmos_outb(0x30, (uint8_t)( ext_mem >> 0)); + cmos_outb(0x31, (uint8_t)( ext_mem >> 8)); + + /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */ + cmos_outb(0x34, (uint8_t)( alt_mem >> 0)); + cmos_outb(0x35, (uint8_t)( alt_mem >> 8)); } int main(void) @@ -349,13 +397,9 @@ int main(void) ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000); } - if ( check_amd() ) - { - /* AMD implies this is SVM */ - printf("SVM go ...\n"); - vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0); - } - else + cmos_write_memory_size(); + + if ( !check_amd() ) { printf("Loading VMXAssist ...\n"); memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS, @@ -368,7 +412,7 @@ int main(void) ); } - printf("Failed to invoke ROMBIOS\n"); + printf("Invoking ROMBIOS ...\n"); return 0; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/smbios.c Wed Mar 21 18:08:31 2007 -0500 @@ -22,7 +22,6 @@ #include <stdint.h> #include <xen/version.h> -#include <xen/hvm/e820.h> #include "smbios.h" #include "smbios_types.h" #include "util.h" @@ -129,47 +128,32 @@ write_smbios_tables(void *start, return (size_t)((char *)p - (char *)start); } -/* This tries to figure out how much pseudo-physical memory (in MB) - is allocated to the current domU. - - It iterates through the e820 table, adding up the 'usable' and - 'reserved' entries and rounding up to the nearest MB. - - The e820map is not at e820 in hvmloader, so this uses the - E820_MAP_* constants from e820.h to pick it up where libxenguest - left it. - */ +/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */ static uint64_t get_memsize(void) { - struct e820entry *map = NULL; - uint8_t num_entries = 0; + struct e820entry *map = E820_MAP; + uint8_t num_entries = *E820_MAP_NR; uint64_t memsize = 0; - uint8_t i; - - map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); - num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); - - /* walk through e820map, ignoring any entries that aren't marked - as usable or reserved. */ - + int i; + + /* + * Walk through e820map, ignoring any entries that aren't marked + * as usable or reserved. + */ for ( i = 0; i < num_entries; i++ ) { - if (map->type == E820_RAM || map->type == E820_RESERVED) + if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) ) memsize += map->size; map++; } - /* Round up to the nearest MB. The user specifies domU - pseudo-physical memory in megabytes, so not doing this - could easily lead to reporting one less MB than the user - specified. */ - if ( memsize & ((1<<20)-1) ) - memsize = (memsize >> 20) + 1; - else - memsize = (memsize >> 20); - - return memsize; + /* + * Round up to the nearest MB. The user specifies domU pseudo-physical + * memory in megabytes, so not doing this could easily lead to reporting + * one less MB than the user specified. + */ + return (memsize + (1 << 20) - 1) >> 20; } void diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/util.c Wed Mar 21 18:08:31 2007 -0500 @@ -27,17 +27,17 @@ void outb(uint16_t addr, uint8_t val) { - __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outb %%al, %%dx" : : "d" (addr), "a" (val) ); } void outw(uint16_t addr, uint16_t val) { - __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outw %%ax, %%dx" : : "d" (addr), "a" (val) ); } void outl(uint16_t addr, uint32_t val) { - __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outl %%eax, %%dx" : : "d" (addr), "a" (val) ); } uint8_t inb(uint16_t addr) @@ -59,6 +59,18 @@ uint32_t inl(uint16_t addr) uint32_t val; __asm__ __volatile__ ( "inl %%dx,%%eax" : "=a" (val) : "d" (addr) ); return val; +} + +uint8_t cmos_inb(uint8_t idx) +{ + outb(0x70, idx); + return inb(0x71); +} + +void cmos_outb(uint8_t idx, uint8_t val) +{ + outb(0x70, idx); + outb(0x71, val); } char *itoa(char *a, unsigned int i) @@ -280,9 +292,6 @@ uuid_to_string(char *dest, uint8_t *uuid *p = '\0'; } -#include <xen/hvm/e820.h> -#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) -#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask) { uint64_t addr = 0; diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/hvmloader/util.h Wed Mar 21 18:08:31 2007 -0500 @@ -25,6 +25,10 @@ uint8_t inb(uint16_t addr); uint8_t inb(uint16_t addr); uint16_t inw(uint16_t addr); uint32_t inl(uint16_t addr); + +/* CMOS access */ +uint8_t cmos_inb(uint8_t idx); +void cmos_outb(uint8_t idx, uint8_t val); /* APIC access */ uint32_t ioapic_read(uint32_t reg); @@ -78,9 +82,13 @@ int vprintf(const char *fmt, va_list ap) /* Allocate region of specified type in the e820 table. */ uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); +/* General e820 access. */ +#include <xen/hvm/e820.h> +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) +#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) + /* Prepare the 32bit BIOS */ -int highbios_setup(void); - +void highbios_setup(void); #define isdigit(c) ((c) >= '0' && (c) <= '9') diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/rombios/32bit/tcgbios/tcgbios.c --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Wed Mar 21 18:08:31 2007 -0500 @@ -95,13 +95,15 @@ struct ptti_cust *TCG_CommandList[] = { }; /* local function prototypes */ -static void sha1(const unsigned char *data, uint32_t length, unsigned char *hash); +static void sha1(const unsigned char *data, uint32_t length, + unsigned char *hash); static uint32_t TCG_ShutdownPreBootInterface(uint32_t ebx); static uint32_t HashAll32(struct hai *hai, unsigned char *hash, uint32_t magic, uint32_t ecx, uint32_t edx); static uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, struct hleeo *hleeo, - uint32_t magic, uint32_t ecx, uint32_t edx); + uint32_t magic, uint32_t ecx, + uint32_t edx); static uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo, uint32_t ebx, uint32_t ecx, uint32_t edx); static uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto, @@ -181,8 +183,7 @@ uint32_t MA_InitTPM(uint16_t startupcode } static -uint32_t MA_Transmit(unsigned char *cmdbuffer, - unsigned char *respbuffer, +uint32_t MA_Transmit(unsigned char *cmdbuffer, unsigned char *respbuffer, uint32_t respbufferlen) { uint32_t rc = 0; @@ -289,15 +290,14 @@ void tcpa_acpi_init(void) uint32_t ctr = 0; /* get RSDT from RSDP */ rsdt = (struct acpi_20_rsdt *)rsdp->rsdt_address; - /* rsdt may be anywhere in 32bit space */ length = rsdt->header.length; off = 36; while ((off + 3) < length) { /* try all pointers to structures */ tcpa = (struct acpi_20_tcpa *)rsdt->entry[ctr]; /* valid TCPA ACPI table ? */ - if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature && - acpi_validate_entry(&tcpa->header) == 0) { + if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature + && acpi_validate_entry(&tcpa->header) == 0) { found = 1; break; } @@ -311,7 +311,6 @@ void tcpa_acpi_init(void) tcpa = 0; } - /* initialize the TCPA part of the EBDA with our data */ tcpa_acpi.tcpa_ptr = tcpa; tcpa_acpi.lasa_last_ptr = 0; tcpa_acpi.entry_count = 0; @@ -748,9 +747,7 @@ void tcpa_measure_post(Bit32u from, Bit3 } static -uint32_t SendCommand32(uint32_t idx, - struct pttto *pttto, - uint32_t size_ptto) +uint32_t SendCommand32(uint32_t idx, struct pttto *pttto, uint32_t size_ptto) { uint32_t rc = 0; struct pttti *pttti = (struct pttti *)TCG_CommandList[idx]; @@ -796,7 +793,8 @@ uint32_t tcpa_initialize_tpm(uint32_t ph uint32_t pttto_size = sizeof(_pttto); if (rc == 0) { - rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto, pttto_size); + rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto, + pttto_size); } if (rc == 0 && physpres != 0) { @@ -884,11 +882,8 @@ uint32_t _TCG_TPM_Extend(unsigned char * static -uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, - struct hleeo *hleeo, - uint32_t magic, - uint32_t ecx, - uint32_t edx) +uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, struct hleeo *hleeo, + uint32_t magic, uint32_t ecx, uint32_t edx) { uint32_t rc = 0; uint16_t size; @@ -978,11 +973,8 @@ uint32_t HashLogExtendEvent32(struct hle static -uint32_t PassThroughToTPM32(struct pttti *pttti, - struct pttto *pttto, - uint32_t magic, - uint32_t ecx, - uint32_t edx) +uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto, + uint32_t magic, uint32_t ecx, uint32_t edx) { uint32_t rc = 0; uint8_t *cmd32; @@ -1047,9 +1039,7 @@ uint32_t TCG_ShutdownPreBootInterface(ui static uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo, - uint32_t ebx, - uint32_t ecx, - uint32_t edx) + uint32_t ebx, uint32_t ecx, uint32_t edx) { uint32_t rc = 0; uint16_t size; @@ -1144,9 +1134,7 @@ uint32_t HashLogEvent32(struct hlei *hle static uint32_t HashAll32(struct hai *hai, unsigned char *hash, - uint32_t magic, - uint32_t ecx, - uint32_t edx) + uint32_t magic, uint32_t ecx, uint32_t edx) { uint32_t rc = 0; @@ -1187,9 +1175,7 @@ uint32_t HashAll32(struct hai *hai, unsi static uint32_t TSS32(struct ti *ti, struct to *to, - uint32_t ebx, - uint32_t ecx, - uint32_t edx) + uint32_t ebx, uint32_t ecx, uint32_t edx) { uint32_t rc = 0; if (TCG_IsShutdownPreBootInterface() == 0) { @@ -1209,11 +1195,11 @@ uint32_t TSS32(struct ti *ti, struct to static uint32_t CompactHashLogExtendEvent32(unsigned char *buffer, - uint32_t info, - uint32_t magic, - uint32_t length, - uint32_t pcrindex, - uint32_t *edx_ptr) + uint32_t info, + uint32_t magic, + uint32_t length, + uint32_t pcrindex, + uint32_t *edx_ptr) { uint32_t rc = 0; struct hleeo hleeo; @@ -1356,9 +1342,7 @@ void sha1_do(sha1_ctx *ctx, const unsign /* treat data in 64-byte chunks */ for (offset = 0; length - offset >= 64; offset += 64) { - /* copy into the 'w' array */ memcpy(w, data32 + offset, 64); - /* hash the block in the 'w' array */ sha1_block((uint32_t *)w, ctx); bits += (64 * 8); } @@ -1408,7 +1392,8 @@ void sha1(const unsigned char *data, uin } -uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds, uint32_t flags_ptr) +uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds, + uint32_t flags_ptr) { uint16_t DS = esds >> 16; uint16_t ES = esds & 0xffff; @@ -1435,7 +1420,6 @@ uint32_t TCGInterruptHandler(pushad_regs } } break; - case 0x01: regs->u.r32.eax = HashLogExtendEvent32((struct hleei_short*) diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/rombios/32bitgateway.c --- a/tools/firmware/rombios/32bitgateway.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/rombios/32bitgateway.c Wed Mar 21 18:08:31 2007 -0500 @@ -153,26 +153,17 @@ realmode_gdtdesc: ;to be used in real switch_to_realmode: ; Implementation of switching from protected mode to real mode - ; restores all registers and prepares cs, es, ds, ss to be used - ; in real mode + ; prepares cs, es, ds, ss to be used in real mode + ; spills eax START_PM_CODE ; need to fix up the stack to return in 16 bit mode ; currently the 32 bit return address is on the stack - push bp ;pop@A1 - mov bp, sp - push eax ;pop@X - - mov eax, [bp] ; return address low 16bits - ; and 'bp' are being moved - mov 2[bp], eax - - pop eax ;@X - add sp, #2 ; adjust stack for 'lost' bytes - - push eax ;pop@1 - push bx ;pop@2 - push si ;pop@3 + pop eax + push ax + + push bx ;pop@1 + push si ;pop@2 call _ebda_ss_offset32 ; get the offset of the ss mov bx, ax ; entry within the ebda. @@ -229,10 +220,8 @@ switch_to_realmode_goon_2: sti ; allow interrupts - pop si ;@3 - pop bx ;@2 - pop eax ;@1 - pop bp ;@A1 + pop si ;@2 + pop bx ;@1 ret diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/rombios/rombios.c Wed Mar 21 18:08:31 2007 -0500 @@ -4196,178 +4196,86 @@ ASM_END case 0xe8: switch(regs.u.r8.al) { - case 0x20: // coded by osmaker aka K.J. - if(regs.u.r32.edx == 0x534D4150) /* SMAP */ - { -#ifdef HVMASSIST - if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) { - Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14; - - if (regs.u.r16.bx + 0x14 <= e820_table_size) { - memcpyb(ES, regs.u.r16.di, - 0xe000, 0x10 + regs.u.r16.bx, 0x14); - } - regs.u.r32.ebx += 0x14; - if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size) - regs.u.r32.ebx = 0; - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; - CLEAR_CF(); - return; - } else if (regs.u.r16.bx == 1) { - extended_memory_size = inb_cmos(0x35); - extended_memory_size <<= 8; - extended_memory_size |= inb_cmos(0x34); - extended_memory_size *= 64; - if (extended_memory_size > 0x3bc000) // greater than EFF00000??? - { - extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 - } - extended_memory_size *= 1024; - extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off - - if (extended_memory_size <= 15728640) - { - extended_memory_size = inb_cmos(0x31); - extended_memory_size <<= 8; - extended_memory_size |= inb_cmos(0x30); - extended_memory_size *= 1024; - } - - write_word(ES, regs.u.r16.di, 0x0000); - write_word(ES, regs.u.r16.di+2, 0x0010); - write_word(ES, regs.u.r16.di+4, 0x0000); - write_word(ES, regs.u.r16.di+6, 0x0000); - - write_word(ES, regs.u.r16.di+8, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+10, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+12, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+14, extended_memory_size); - - write_word(ES, regs.u.r16.di+16, 0x1); - write_word(ES, regs.u.r16.di+18, 0x0); - - regs.u.r32.ebx = 0; - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; - CLEAR_CF(); - return; - } else { /* AX=E820, DX=534D4150, BX unrecognized */ - goto int15_unimplemented; - } -#else - switch(regs.u.r16.bx) - { - case 0: - write_word(ES, regs.u.r16.di, 0x00); - write_word(ES, regs.u.r16.di+2, 0x00); - write_word(ES, regs.u.r16.di+4, 0x00); - write_word(ES, regs.u.r16.di+6, 0x00); - - write_word(ES, regs.u.r16.di+8, 0xFC00); - write_word(ES, regs.u.r16.di+10, 0x0009); - write_word(ES, regs.u.r16.di+12, 0x0000); - write_word(ES, regs.u.r16.di+14, 0x0000); - - write_word(ES, regs.u.r16.di+16, 0x1); - write_word(ES, regs.u.r16.di+18, 0x0); - - regs.u.r32.ebx = 1; - - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; - CLEAR_CF(); - return; - break; - case 1: - extended_memory_size = inb_cmos(0x35); - extended_memory_size <<= 8; - extended_memory_size |= inb_cmos(0x34); - extended_memory_size *= 64; - if(extended_memory_size > 0x3bc000) // greater than EFF00000??? - { - extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 - } - extended_memory_size *= 1024; - extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off - - if(extended_memory_size <= 15728640) - { - extended_memory_size = inb_cmos(0x31); - extended_memory_size <<= 8; - extended_memory_size |= inb_cmos(0x30); - extended_memory_size *= 1024; - } - - write_word(ES, regs.u.r16.di, 0x0000); - write_word(ES, regs.u.r16.di+2, 0x0010); - write_word(ES, regs.u.r16.di+4, 0x0000); - write_word(ES, regs.u.r16.di+6, 0x0000); - - write_word(ES, regs.u.r16.di+8, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+10, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+12, extended_memory_size); - extended_memory_size >>= 16; - write_word(ES, regs.u.r16.di+14, extended_memory_size); - - write_word(ES, regs.u.r16.di+16, 0x1); - write_word(ES, regs.u.r16.di+18, 0x0); - - regs.u.r32.ebx = 0; - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; - CLEAR_CF(); - return; - break; - default: /* AX=E820, DX=534D4150, BX unrecognized */ - goto int15_unimplemented; + case 0x20: { + Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14; + + if (regs.u.r32.edx != 0x534D4150) /* SMAP */ + goto int15_unimplemented; + + if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) { + if (regs.u.r16.bx + 0x14 <= e820_table_size) + memcpyb(ES, regs.u.r16.di, + 0xe000, 0x10 + regs.u.r16.bx, 0x14); + regs.u.r32.ebx += 0x14; + if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size) + regs.u.r32.ebx = 0; + } else if (regs.u.r16.bx == 1) { + Bit32u base, type; + Bit16u off; + for (off = 0; off < e820_table_size; off += 0x14) { + base = read_dword(0xe000, 0x10 + off); + type = read_dword(0xe000, 0x20 + off); + if ((base >= 0x100000) && (type == 1)) break; } -#endif - } else { - // if DX != 0x534D4150) - goto int15_unimplemented; - } + if (off == e820_table_size) { + SET_CF(); + break; + } + memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14); + regs.u.r32.ebx = 0; + } else { /* AX=E820, DX=534D4150, BX unrecognized */ + goto int15_unimplemented; + } + + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; + CLEAR_CF(); break; - - case 0x01: - // do we have any reason to fail here ? - CLEAR_CF(); - - // my real system sets ax and bx to 0 - // this is confirmed by Ralph Brown list - // but syslinux v1.48 is known to behave - // strangely if ax is set to 0 - // regs.u.r16.ax = 0; - // regs.u.r16.bx = 0; - - // Get the amount of extended memory (above 1M) - regs.u.r8.cl = inb_cmos(0x30); - regs.u.r8.ch = inb_cmos(0x31); + } + + case 0x01: { + Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14; + Bit32u base, type, size; + + // do we have any reason to fail here ? + CLEAR_CF(); + + // Get the amount of extended memory (above 1M) + regs.u.r8.cl = inb_cmos(0x30); + regs.u.r8.ch = inb_cmos(0x31); - // limit to 15M - if(regs.u.r16.cx > 0x3c00) - { - regs.u.r16.cx = 0x3c00; - } - - // Get the amount of extended memory above 16M in 64k blocs - regs.u.r8.dl = inb_cmos(0x34); - regs.u.r8.dh = inb_cmos(0x35); - - // Set configured memory equal to extended memory - regs.u.r16.ax = regs.u.r16.cx; - regs.u.r16.bx = regs.u.r16.dx; - break; + // limit to 15M + if (regs.u.r16.cx > (15*1024)) + regs.u.r16.cx = 15*1024; + + // Find first RAM E820 entry >= 1MB. + for (off = 0; off < e820_table_size; off += 0x14) { + base = read_dword(0xe000, 0x10 + off); + type = read_dword(0xe000, 0x20 + off); + if ((base >= 0x100000) && (type == 1)) + break; + } + + // If there is RAM above 16MB, return amount in 64kB chunks. + regs.u.r16.dx = 0; + if (off != e820_table_size) { + size = base + read_dword(0xe000, 0x18 + off); + if (size > 0x1000000) { + size -= 0x1000000; + regs.u.r16.dx = (Bit16u)(size >> 16); + } + } + + // Set configured memory equal to extended memory + regs.u.r16.ax = regs.u.r16.cx; + regs.u.r16.bx = regs.u.r16.dx; + break; + } default: /* AH=0xE8?? but not implemented */ - goto int15_unimplemented; - } - break; + goto int15_unimplemented; + } + break; int15_unimplemented: // fall into the default default: @@ -7792,10 +7700,11 @@ ASM_END bootdrv = (Bit8u)(status>>8); bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment); - /* Canonicalize bootseg:bootip */ #if BX_TCGBIOS tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L); #endif + + /* Canonicalize bootseg:bootip */ bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; break; @@ -7812,8 +7721,6 @@ ASM_END #if BX_TCGBIOS tcpa_ipl((Bit32u)bootseg); /* specs: 8.2.3 steps 4 and 5 */ #endif - /* Debugging info */ - printf("Booting from %x:%x\n", bootseg, bootip); /* Jump to the boot vector */ ASM_START diff -r 2c087916aaba -r 49ec3725d0c0 tools/firmware/rombios/tcgbios.c --- a/tools/firmware/rombios/tcgbios.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/firmware/rombios/tcgbios.c Wed Mar 21 18:08:31 2007 -0500 @@ -227,6 +227,8 @@ int1a_function32(regs, ES, DS, FLAGS) Bit16u ES, DS, FLAGS; { Bit16u rc; + + BX_DEBUG_INT1A("int1a_32: AX=%04x\n", regs.u.r16.ax); switch (regs.u.r8.ah) { case 0xbb: @@ -256,8 +258,10 @@ int1a_function32(regs, ES, DS, FLAGS) default: SET_CF(); } + break; default: SET_CF(); break; } -} + BX_DEBUG_INT1A("int1a_32: FLAGS=%04x\n", FLAGS); +} diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/ide.c Wed Mar 21 18:08:31 2007 -0500 @@ -396,17 +396,41 @@ typedef struct PCIIDEState { #ifdef DMA_MULTI_THREAD +static pthread_t ide_dma_thread; static int file_pipes[2]; static void ide_dma_loop(BMDMAState *bm); static void dma_thread_loop(BMDMAState *bm); +extern int suspend_requested; static void *dma_thread_func(void* opaque) { BMDMAState* req; - - while (read(file_pipes[0], &req, sizeof(req))) { - dma_thread_loop(req); + fd_set fds; + int rv, nfds = file_pipes[0] + 1; + struct timeval tm; + + while (1) { + + /* Wait at most a second for the pipe to become readable */ + FD_ZERO(&fds); + FD_SET(file_pipes[0], &fds); + tm.tv_sec = 1; + tm.tv_usec = 0; + rv = select(nfds, &fds, NULL, NULL, &tm); + + if (rv != 0) { + if (read(file_pipes[0], &req, sizeof(req)) == 0) + return NULL; + dma_thread_loop(req); + } else { + if (suspend_requested) { + /* Need to tidy up the DMA thread so that we don't end up + * finishing operations after the domain's ioreqs are + * drained and its state saved */ + return NULL; + } + } } return NULL; @@ -414,23 +438,40 @@ static void *dma_thread_func(void* opaqu static void dma_create_thread(void) { - pthread_t tid; int rt; + pthread_attr_t a; if (pipe(file_pipes) != 0) { fprintf(stderr, "create pipe failed\n"); exit(1); } - if ((rt = pthread_create(&tid, NULL, dma_thread_func, NULL))) { + if ((rt = pthread_attr_init(&a)) + || (rt = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE))) { + fprintf(stderr, "Oops, dma thread attr setup failed, errno=%d\n", rt); + exit(1); + } + + if ((rt = pthread_create(&ide_dma_thread, &a, dma_thread_func, NULL))) { fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt); exit(1); } - - if ((rt = pthread_detach(tid))) { - fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt); - exit(1); - } +} + +void ide_stop_dma_thread(void) +{ + int rc; + /* Make sure the IDE DMA thread is stopped */ + if ( (rc = pthread_join(ide_dma_thread, NULL)) != 0 ) + { + fprintf(stderr, "Oops, error collecting IDE DMA thread (%s)\n", + strerror(rc)); + } +} + +#else +void ide_stop_dma_thread(void) +{ } #endif /* DMA_MULTI_THREAD */ diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/usb-hid.c --- a/tools/ioemu/hw/usb-hid.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/usb-hid.c Wed Mar 21 18:08:31 2007 -0500 @@ -517,6 +517,49 @@ static void usb_mouse_handle_destroy(USB qemu_free(s); } +void usb_mouse_save(QEMUFile *f, void *opaque) +{ + USBMouseState *s = (USBMouseState*)opaque; + + qemu_put_be32s(f, &s->dx); + qemu_put_be32s(f, &s->dy); + qemu_put_be32s(f, &s->dz); + qemu_put_be32s(f, &s->buttons_state); + qemu_put_be32s(f, &s->x); + qemu_put_be32s(f, &s->y); + qemu_put_be32s(f, &s->kind); + qemu_put_be32s(f, &s->mouse_grabbed); + qemu_put_be32s(f, &s->status_changed); + +} + +int usb_mouse_load(QEMUFile *f, void *opaque, int version_id) +{ + USBMouseState *s = (USBMouseState*)opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be32s(f, &s->dx); + qemu_get_be32s(f, &s->dy); + qemu_get_be32s(f, &s->dz); + qemu_get_be32s(f, &s->buttons_state); + qemu_get_be32s(f, &s->x); + qemu_get_be32s(f, &s->y); + qemu_get_be32s(f, &s->kind); + qemu_get_be32s(f, &s->mouse_grabbed); + qemu_get_be32s(f, &s->status_changed); + + if ( s->kind == USB_TABLET) { + fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n"); + qemu_add_mouse_event_handler(usb_tablet_event, s, 1); + } else if ( s->kind == USB_MOUSE) { + fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n"); + qemu_add_mouse_event_handler(usb_mouse_event, s, 0); + } +} + + USBDevice *usb_tablet_init(void) { USBMouseState *s; @@ -536,6 +579,8 @@ USBDevice *usb_tablet_init(void) pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); + register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s); + return (USBDevice *)s; } @@ -558,5 +603,7 @@ USBDevice *usb_mouse_init(void) pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); + register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s); + return (USBDevice *)s; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/usb-ohci.c --- a/tools/ioemu/hw/usb-ohci.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/usb-ohci.c Wed Mar 21 18:08:31 2007 -0500 @@ -1186,5 +1186,7 @@ void usb_ohci_init(struct PCIBus *bus, i qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach); } + register_savevm("OHCI USB", 0, 1, generic_pci_save, generic_pci_load, ohci); + ohci_reset(ohci); } diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/usb-uhci.c --- a/tools/ioemu/hw/usb-uhci.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/usb-uhci.c Wed Mar 21 18:08:31 2007 -0500 @@ -658,6 +658,50 @@ static void uhci_map(PCIDevice *pci_dev, register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); } +void uhci_usb_save(QEMUFile *f, void *opaque) +{ + int i; + UHCIState *s = (UHCIState*)opaque; + + qemu_put_be16s(f, &s->cmd); + qemu_put_be16s(f, &s->status); + qemu_put_be16s(f, &s->intr); + qemu_put_be16s(f, &s->frnum); + qemu_put_be32s(f, &s->fl_base_addr); + qemu_put_8s(f, &s->sof_timing); + qemu_put_8s(f, &s->status2); + + for(i = 0; i < NB_PORTS; i++) { + qemu_put_be16s(f, &s->ports[i].ctrl); + } + + qemu_put_timer(f, s->frame_timer); +} + +int uhci_usb_load(QEMUFile *f, void *opaque, int version_id) +{ + int i; + UHCIState *s = (UHCIState*)opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be16s(f, &s->cmd); + qemu_get_be16s(f, &s->status); + qemu_get_be16s(f, &s->intr); + qemu_get_be16s(f, &s->frnum); + qemu_get_be32s(f, &s->fl_base_addr); + qemu_get_8s(f, &s->sof_timing); + qemu_get_8s(f, &s->status2); + + for(i = 0; i < NB_PORTS; i++) { + qemu_get_be16s(f, &s->ports[i].ctrl); + } + + qemu_get_timer(f, s->frame_timer); + +} + void usb_uhci_init(PCIBus *bus, int devfn) { UHCIState *s; @@ -693,4 +737,8 @@ void usb_uhci_init(PCIBus *bus, int devf to rely on this. */ pci_register_io_region(&s->dev, 4, 0x20, PCI_ADDRESS_SPACE_IO, uhci_map); -} + + register_savevm("UHCI_usb_pci", 0, 1, generic_pci_save, generic_pci_load, s); + + register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, uhci_usb_load, s); +} diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/usb.c --- a/tools/ioemu/hw/usb.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/usb.c Wed Mar 21 18:08:31 2007 -0500 @@ -191,3 +191,43 @@ int set_usb_string(uint8_t *buf, const c } return q - buf; } + +void generic_usb_save(QEMUFile* f, void *opaque) +{ + USBDevice *s = (USBDevice*)opaque; + + qemu_put_be32s(f, &s->speed); + qemu_put_8s(f, &s->addr); + qemu_put_be32s(f, &s->state); + + qemu_put_buffer(f, s->setup_buf, 8); + qemu_put_buffer(f, s->data_buf, 1024); + + qemu_put_be32s(f, &s->remote_wakeup); + qemu_put_be32s(f, &s->setup_state); + qemu_put_be32s(f, &s->setup_len); + qemu_put_be32s(f, &s->setup_index); + +} + +int generic_usb_load(QEMUFile* f, void *opaque, int version_id) +{ + USBDevice *s = (USBDevice*)opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be32s(f, &s->speed); + qemu_get_8s(f, &s->addr); + qemu_get_be32s(f, &s->state); + + qemu_get_buffer(f, s->setup_buf, 8); + qemu_get_buffer(f, s->data_buf, 1024); + + qemu_get_be32s(f, &s->remote_wakeup); + qemu_get_be32s(f, &s->setup_state); + qemu_get_be32s(f, &s->setup_len); + qemu_get_be32s(f, &s->setup_index); + + return 0; +} diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/hw/usb.h --- a/tools/ioemu/hw/usb.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/hw/usb.h Wed Mar 21 18:08:31 2007 -0500 @@ -176,3 +176,9 @@ USBDevice *usb_tablet_init(void); /* usb-msd.c */ USBDevice *usb_msd_init(const char *filename); + +/* usb.c */ +void generic_usb_save(QEMUFile* f, void *opaque); +int generic_usb_load(QEMUFile* f, void *opaque, int version_id); + + diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/target-i386-dm/exec-dm.c --- a/tools/ioemu/target-i386-dm/exec-dm.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/target-i386-dm/exec-dm.c Wed Mar 21 18:08:31 2007 -0500 @@ -450,6 +450,9 @@ static inline int paddr_is_ram(target_ph #define phys_ram_addr(x) (phys_ram_base + (x)) #endif +extern unsigned long *logdirty_bitmap; +extern unsigned long logdirty_bitmap_size; + void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write) { @@ -485,9 +488,20 @@ void cpu_physical_memory_rw(target_phys_ l = 1; } } else if (paddr_is_ram(addr)) { - /* Reading from RAM */ + /* Writing to RAM */ ptr = phys_ram_addr(addr); memcpy(ptr, buf, l); + if (logdirty_bitmap != NULL) { + /* Record that we have dirtied this frame */ + unsigned long pfn = addr >> TARGET_PAGE_BITS; + if (pfn / 8 >= logdirty_bitmap_size) { + fprintf(logfile, "dirtying pfn %x >= bitmap size %x\n", + pfn, logdirty_bitmap_size * 8); + } else { + logdirty_bitmap[pfn / HOST_LONG_BITS] + |= 1UL << pfn % HOST_LONG_BITS; + } + } #ifdef __ia64__ sync_icache(ptr, l); #endif diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/target-i386-dm/helper2.c Wed Mar 21 18:08:31 2007 -0500 @@ -439,6 +439,18 @@ void cpu_ioreq_xor(CPUState *env, ioreq_ req->data = tmp1; } +void cpu_ioreq_xchg(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1; + + if (req->data_is_ptr != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + write_physical(req->addr, req->size, &req->data); + req->data = tmp1; +} + void __handle_ioreq(CPUState *env, ioreq_t *req) { if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4) @@ -462,6 +474,9 @@ void __handle_ioreq(CPUState *env, ioreq break; case IOREQ_TYPE_XOR: cpu_ioreq_xor(env, req); + break; + case IOREQ_TYPE_XCHG: + cpu_ioreq_xchg(env, req); break; default: hw_error("Invalid ioreq type 0x%x\n", req->type); @@ -577,7 +592,28 @@ int main_loop(void) destroy_hvm_domain(); else { char qemu_file[20]; + ioreq_t *req; + int rc; + sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid); + xc_domain_pause(xc_handle, domid); + + /* Pull all outstanding ioreqs through the system */ + handle_buffered_io(env); + main_loop_wait(1); /* For the select() on events */ + + /* Stop the IDE thread */ + ide_stop_dma_thread(); + + /* Make sure that all outstanding IO responses are handled too */ + if ( xc_hvm_drain_io(xc_handle, domid) != 0 ) + { + fprintf(stderr, "error clearing ioreq rings (%s)\n", + strerror(errno)); + return -1; + } + + /* Save the device state */ if (qemu_savevm(qemu_file) < 0) fprintf(stderr, "qemu save fail.\n"); } diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/vl.c Wed Mar 21 18:08:31 2007 -0500 @@ -841,10 +841,22 @@ void qemu_get_timer(QEMUFile *f, QEMUTim #ifdef CONFIG_DM static void timer_save(QEMUFile *f, void *opaque) { + /* need timer for save/restoe qemu_timer in usb_uhci */ + if (cpu_ticks_enabled) { + hw_error("cannot save state if virtual timers are running"); + } + qemu_put_be64s(f, &cpu_clock_offset); } static int timer_load(QEMUFile *f, void *opaque, int version_id) { + if (version_id != 1) + return -EINVAL; + if (cpu_ticks_enabled) { + return -EINVAL; + } + + qemu_get_be64s(f, &cpu_clock_offset); return 0; } #else /* !CONFIG_DM */ @@ -3900,6 +3912,7 @@ static int usb_device_add(const char *de const char *p; USBDevice *dev; USBPort *port; + char usb_name[256] = "USB "; if (!free_usb_ports) return -1; @@ -3936,6 +3949,12 @@ static int usb_device_add(const char *de free_usb_ports = port->next; port->next = used_usb_ports; used_usb_ports = port; + + pstrcpy(usb_name + strlen(usb_name), + sizeof(usb_name) - strlen(usb_name), + devname); + register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev); + usb_attach(port, dev); return 0; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/vl.h Wed Mar 21 18:08:31 2007 -0500 @@ -843,6 +843,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn); int pmac_ide_init (BlockDriverState **hd_table, SetIRQFunc *set_irq, void *irq_opaque, int irq); +void ide_stop_dma_thread(void); /* cdrom.c */ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); diff -r 2c087916aaba -r 49ec3725d0c0 tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/ioemu/xenstore.c Wed Mar 21 18:08:31 2007 -0500 @@ -11,9 +11,14 @@ #include "vl.h" #include "block_int.h" #include <unistd.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> static struct xs_handle *xsh = NULL; -static char *hd_filename[MAX_DISKS]; +static char *media_filename[MAX_DISKS]; static QEMUTimer *insert_timer = NULL; #define UWAIT_MAX (30*1000000) /* thirty seconds */ @@ -40,10 +45,10 @@ static void insert_media(void *opaque) int i; for (i = 0; i < MAX_DISKS; i++) { - if (hd_filename[i]) { - do_change(bs_table[i]->device_name, hd_filename[i]); - free(hd_filename[i]); - hd_filename[i] = NULL; + if (media_filename[i] && bs_table[i]) { + do_change(bs_table[i]->device_name, media_filename[i]); + free(media_filename[i]); + media_filename[i] = NULL; } } } @@ -82,7 +87,7 @@ void xenstore_parse_domain_config(int do unsigned int len, num, hd_index; for(i = 0; i < MAX_DISKS; i++) - hd_filename[i] = NULL; + media_filename[i] = NULL; xsh = xs_daemon_open(); if (xsh == NULL) { @@ -128,19 +133,12 @@ void xenstore_parse_domain_config(int do continue; free(type); type = xs_read(xsh, XBT_NULL, buf, &len); - /* read params to get the patch of the image -- read it last - * so that we have its path in buf when setting up the - * watch */ if (pasprintf(&buf, "%s/params", bpath) == -1) continue; free(params); params = xs_read(xsh, XBT_NULL, buf, &len); if (params == NULL) continue; - if (params[0]) { - hd_filename[hd_index] = params; /* strdup() */ - params = NULL; /* don't free params on re-use */ - } /* * check if device has a phantom vbd; the phantom is hooked * to the frontend device (for ease of cleanup), so lookup @@ -151,37 +149,41 @@ void xenstore_parse_domain_config(int do continue; free(fpath); fpath = xs_read(xsh, XBT_NULL, buf, &len); - if (fpath != NULL) { + if (fpath) { if (pasprintf(&buf, "%s/dev", fpath) == -1) continue; + free(params); params = xs_read(xsh, XBT_NULL, buf , &len); - if (params != NULL) { - free(hd_filename[hd_index]); - hd_filename[hd_index] = params; - params = NULL; /* don't free params on re-use */ + if (params) { /* * wait for device, on timeout silently fail because we will * fail to open below */ - waitForDevice(hd_filename[hd_index]); + waitForDevice(params); } } + bs_table[hd_index] = bdrv_new(dev); - /* re-establish buf */ - if (pasprintf(&buf, "%s/params", bpath) == -1) - continue; /* check if it is a cdrom */ if (type && !strcmp(type, "cdrom")) { bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM); - xs_watch(xsh, buf, dev); + if (pasprintf(&buf, "%s/params", bpath) != -1) + xs_watch(xsh, buf, dev); } - if (hd_filename[hd_index]) { - if (bdrv_open(bs_table[hd_index], hd_filename[hd_index], - 0 /* snapshot */) < 0) + /* open device now if media present */ + if (params[0]) { + if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0) fprintf(stderr, "qemu: could not open hard disk image '%s'\n", - hd_filename[hd_index]); + params); } } + + /* Set a watch for log-dirty requests from the migration tools */ + if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) { + xs_watch(xsh, buf, "logdirty"); + fprintf(logfile, "Watching %s\n", buf); + } + out: free(type); @@ -201,6 +203,116 @@ int xenstore_fd(void) return -1; } +unsigned long *logdirty_bitmap = NULL; +unsigned long logdirty_bitmap_size; +extern int vga_ram_size, bios_size; + +void xenstore_process_logdirty_event(void) +{ + char *act; + static char *active_path = NULL; + static char *next_active_path = NULL; + static char *seg = NULL; + unsigned int len; + int i; + + fprintf(logfile, "Triggered log-dirty buffer switch\n"); + + if (!seg) { + char *path, *p, *key_ascii, key_terminated[17] = {0,}; + key_t key; + int shmid; + + /* Find and map the shared memory segment for log-dirty bitmaps */ + if (!(path = xs_get_domain_path(xsh, domid))) { + fprintf(logfile, "Log-dirty: can't get domain path in store\n"); + exit(1); + } + if (!(path = realloc(path, strlen(path) + + strlen("/logdirty/next-active") + 1))) { + fprintf(logfile, "Log-dirty: out of memory\n"); + exit(1); + } + strcat(path, "/logdirty/"); + p = path + strlen(path); + strcpy(p, "key"); + + key_ascii = xs_read(xsh, XBT_NULL, path, &len); + if (!key_ascii) { + /* No key yet: wait for the next watch */ + free(path); + return; + } + strncpy(key_terminated, key_ascii, 16); + free(key_ascii); + key = (key_t) strtoull(key_terminated, NULL, 16); + + /* Figure out how bit the log-dirty bitmaps are */ + logdirty_bitmap_size = ((phys_ram_size + 0x20 + - (vga_ram_size + bios_size)) + >> (TARGET_PAGE_BITS)); /* nr of bits in map*/ + if (logdirty_bitmap_size > HVM_BELOW_4G_MMIO_START >> TARGET_PAGE_BITS) + logdirty_bitmap_size += + HVM_BELOW_4G_MMIO_LENGTH >> TARGET_PAGE_BITS; /* still bits */ + logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1) + / HOST_LONG_BITS); /* longs */ + logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */ + + /* Map the shared-memory segment */ + if ((shmid = shmget(key, + 2 * logdirty_bitmap_size, + S_IRUSR|S_IWUSR)) == -1 + || (seg = shmat(shmid, NULL, 0)) == (void *)-1) { + fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n", + (unsigned long long) key, strerror(errno)); + exit(1); + } + + fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg); + + /* Double-check that the bitmaps are the size we expect */ + if (logdirty_bitmap_size != *(uint32_t *)seg) { + fprintf(logfile, "Log-dirty: got %lu, calc %lu\n", + *(uint32_t *)seg, logdirty_bitmap_size); + return; + } + + /* Remember the paths for the next-active and active entries */ + strcpy(p, "active"); + if (!(active_path = strdup(path))) { + fprintf(logfile, "Log-dirty: out of memory\n"); + exit(1); + } + strcpy(p, "next-active"); + if (!(next_active_path = strdup(path))) { + fprintf(logfile, "Log-dirty: out of memory\n"); + exit(1); + } + free(path); + } + + /* Read the required active buffer from the store */ + act = xs_read(xsh, XBT_NULL, next_active_path, &len); + if (!act) { + fprintf(logfile, "Log-dirty: can't read next-active\n"); + exit(1); + } + + /* Switch buffers */ + i = act[0] - '0'; + if (i != 0 && i != 1) { + fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act); + exit(1); + } + logdirty_bitmap = seg + i * logdirty_bitmap_size; + + /* Ack that we've switched */ + xs_write(xsh, XBT_NULL, active_path, act, len); + free(act); +} + + + void xenstore_process_event(void *opaque) { char **vec, *image = NULL; @@ -209,6 +321,11 @@ void xenstore_process_event(void *opaque vec = xs_read_watch(xsh, &num); if (!vec) return; + + if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) { + xenstore_process_logdirty_event(); + goto out; + } if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) || strlen(vec[XS_WATCH_TOKEN]) != 3) @@ -220,13 +337,13 @@ void xenstore_process_event(void *opaque do_eject(0, vec[XS_WATCH_TOKEN]); bs_table[hd_index]->filename[0] = 0; - if (hd_filename[hd_index]) { - free(hd_filename[hd_index]); - hd_filename[hd_index] = NULL; + if (media_filename[hd_index]) { + free(media_filename[hd_index]); + media_filename[hd_index] = NULL; } if (image[0]) { - hd_filename[hd_index] = strdup(image); + media_filename[hd_index] = strdup(image); xenstore_check_new_media_present(5000); } diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/Makefile --- a/tools/libxc/Makefile Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/Makefile Wed Mar 21 18:08:31 2007 -0500 @@ -58,7 +58,7 @@ GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_p CFLAGS += -Werror -Wmissing-prototypes CFLAGS += -fno-strict-aliasing -CFLAGS += $(INCLUDES) -I. +CFLAGS += $(INCLUDES) -I. -I../xenstore # Needed for posix_fadvise64() in xc_linux.c CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_core.c --- a/tools/libxc/xc_core.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_core.c Wed Mar 21 18:08:31 2007 -0500 @@ -349,11 +349,7 @@ xc_domain_dumpcore_via_callback(int xc_h /* Map the shared info frame */ live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, info.shared_info_frame); - if ( !live_shinfo -#ifdef __ia64__ - && !info.hvm -#endif - ) + if ( !live_shinfo && !info.hvm ) { PERROR("Couldn't map live_shinfo"); goto out; diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_core_ia64.c --- a/tools/libxc/xc_core_ia64.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_core_ia64.c Wed Mar 21 18:08:31 2007 -0500 @@ -22,6 +22,28 @@ #include "xc_core.h" #include "xc_efi.h" #include "xc_dom.h" +#include <inttypes.h> + +static int +xc_memory_map_cmp(const void *lhs__, const void *rhs__) +{ + const struct xc_core_memory_map *lhs = + (const struct xc_core_memory_map *)lhs__; + const struct xc_core_memory_map *rhs = + (const struct xc_core_memory_map *)rhs__; + + if (lhs->addr < rhs->addr) + return -1; + if (lhs->addr > rhs->addr) + return 1; + + /* memory map overlap isn't allowed. complain */ + DPRINTF("duplicated addresses are detected " + "(0x%" PRIx64 ", 0x%" PRIx64 "), " + "(0x%" PRIx64 ", 0x%" PRIx64 ")\n", + lhs->addr, lhs->size, rhs->addr, rhs->size); + return 0; +} int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info) @@ -111,6 +133,7 @@ memory_map_get_old_hvm(int xc_handle, xc } *mapp = map; *nr_entries = i; + qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp); return 0; out: @@ -196,6 +219,7 @@ xc_core_arch_memory_map_get(int xc_handl ret = 0; out: munmap(memmap_info, PAGE_SIZE); + qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp); return ret; old: diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_core_x86.c --- a/tools/libxc/xc_core_x86.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_core_x86.c Wed Mar 21 18:08:31 2007 -0500 @@ -21,12 +21,15 @@ #include "xg_private.h" #include "xc_core.h" +static int max_gpfn(int xc_handle, domid_t domid) +{ + return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid); +} + int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info) { - if ( info->hvm ) - return 1; - return 0; + return info->hvm; } int @@ -35,14 +38,14 @@ xc_core_arch_memory_map_get(int xc_handl xc_core_memory_map_t **mapp, unsigned int *nr_entries) { - unsigned long max_pfn = live_shinfo->arch.max_pfn; - xc_core_memory_map_t *map = NULL; + unsigned long max_pfn = max_gpfn(xc_handle, info->domid); + xc_core_memory_map_t *map; map = malloc(sizeof(*map)); - if ( !map ) + if ( map == NULL ) { PERROR("Could not allocate memory"); - goto out; + return -1; } map->addr = 0; @@ -51,11 +54,6 @@ xc_core_arch_memory_map_get(int xc_handl *mapp = map; *nr_entries = 1; return 0; - -out: - if ( map ) - free(map); - return -1; } int @@ -67,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d xen_pfn_t *live_p2m_frame_list_list = NULL; xen_pfn_t *live_p2m_frame_list = NULL; uint32_t dom = info->domid; - unsigned long max_pfn = live_shinfo->arch.max_pfn; + unsigned long max_pfn = max_gpfn(xc_handle, info->domid); int ret = -1; int err; diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_dom_x86.c --- a/tools/libxc/xc_dom_x86.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_dom_x86.c Wed Mar 21 18:08:31 2007 -0500 @@ -434,23 +434,11 @@ static int vcpu_x86_32(struct xc_dom_ima { vcpu_guest_context_x86_32_t *ctxt = ptr; xen_pfn_t cr3_pfn; - int i; xc_dom_printf("%s: called\n", __FUNCTION__); /* clear everything */ memset(ctxt, 0, sizeof(*ctxt)); - - /* Virtual IDT is empty at start-of-day. */ - for ( i = 0; i < 256; i++ ) - { - ctxt->trap_ctxt[i].vector = i; - ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_32; - } - - /* No callback handlers. */ - ctxt->event_callback_cs = FLAT_KERNEL_CS_X86_32; - ctxt->failsafe_callback_cs = FLAT_KERNEL_CS_X86_32; ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32; ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32; @@ -465,11 +453,10 @@ static int vcpu_x86_32(struct xc_dom_ima dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ - ctxt->kernel_ss = FLAT_KERNEL_SS_X86_32; - ctxt->kernel_sp = - dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; - - ctxt->flags = VGCF_in_kernel_X86_32; + ctxt->kernel_ss = ctxt->user_regs.ss; + ctxt->kernel_sp = ctxt->user_regs.esp; + + ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32; if ( dom->parms.pae == 2 /* extended_cr3 */ || dom->parms.pae == 3 /* bimodal */ ) ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); @@ -486,19 +473,11 @@ static int vcpu_x86_64(struct xc_dom_ima { vcpu_guest_context_x86_64_t *ctxt = ptr; xen_pfn_t cr3_pfn; - int i; xc_dom_printf("%s: called\n", __FUNCTION__); /* clear everything */ memset(ctxt, 0, sizeof(*ctxt)); - - /* Virtual IDT is empty at start-of-day. */ - for ( i = 0; i < 256; i++ ) - { - ctxt->trap_ctxt[i].vector = i; - ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_64; - } ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64; ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64; @@ -513,11 +492,10 @@ static int vcpu_x86_64(struct xc_dom_ima dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */ - ctxt->kernel_ss = FLAT_KERNEL_SS_X86_64; - ctxt->kernel_sp = - dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; - - ctxt->flags = VGCF_in_kernel_X86_64; + ctxt->kernel_ss = ctxt->user_regs.ss; + ctxt->kernel_sp = ctxt->user_regs.esp; + + ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64; cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn); xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_hvm_build.c Wed Mar 21 18:08:31 2007 -0500 @@ -137,6 +137,12 @@ static void build_e820map(void *e820_pag e820entry[nr_map].type = E820_RAM; nr_map++; + /* Explicitly reserve space for special pages (ioreq and xenstore). */ + e820entry[nr_map].addr = mem_size - PAGE_SIZE * 3; + e820entry[nr_map].size = PAGE_SIZE * 3; + e820entry[nr_map].type = E820_RESERVED; + nr_map++; + if ( extra_mem_size ) { e820entry[nr_map].addr = (1ULL << 32); @@ -280,7 +286,6 @@ static int setup_guest(int xc_handle, /* NB. evtchn_upcall_mask is unused: leave as zero. */ memset(&shared_info->evtchn_mask[0], 0xff, sizeof(shared_info->evtchn_mask)); - shared_info->arch.max_pfn = page_array[nr_pages - 1]; munmap(shared_info, PAGE_SIZE); if ( v_end > HVM_BELOW_4G_RAM_END ) @@ -302,9 +307,15 @@ static int setup_guest(int xc_handle, /* Set [er]ip in the way that's right for Xen */ if ( strstr(caps, "x86_64") ) + { ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry); + ctxt->c64.flags = VGCF_online; + } else + { ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry); + ctxt->c32.flags = VGCF_online; + } return 0; @@ -344,7 +355,7 @@ static int xc_hvm_build_internal(int xc_ memset(&launch_domctl, 0, sizeof(launch_domctl)); launch_domctl.domain = (domid_t)domid; - launch_domctl.u.vcpucontext.vcpu = 0; + launch_domctl.u.vcpucontext.vcpu = 0; set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c); launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; rc = xc_domctl(xc_handle, &launch_domctl); diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_hvm_restore.c --- a/tools/libxc/xc_hvm_restore.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_hvm_restore.c Wed Mar 21 18:08:31 2007 -0500 @@ -70,9 +70,6 @@ int xc_hvm_restore(int xc_handle, int io { DECLARE_DOMCTL; - /* The new domain's shared-info frame number. */ - unsigned long shared_info_frame; - /* A copy of the CPU context of the guest. */ vcpu_guest_context_t ctxt; @@ -86,8 +83,6 @@ int xc_hvm_restore(int xc_handle, int io uint8_t *hvm_buf = NULL; unsigned long long v_end, memsize; unsigned long shared_page_nr; - shared_info_t *shared_info = NULL; - xen_pfn_t arch_max_pfn; unsigned long pfn; unsigned int prev_pc, this_pc; @@ -96,10 +91,11 @@ int xc_hvm_restore(int xc_handle, int io /* Types of the pfns in the current region */ unsigned long region_pfn_type[MAX_BATCH_SIZE]; - struct xen_add_to_physmap xatp; - /* Number of pages of memory the guest has. *Not* the same as max_pfn. */ unsigned long nr_pages; + + /* The size of an array big enough to contain all guest pfns */ + unsigned long pfn_array_size = max_pfn + 1; /* hvm guest mem size (Mb) */ memsize = (unsigned long long)*store_mfn; @@ -127,7 +123,7 @@ int xc_hvm_restore(int xc_handle, int io } - pfns = malloc(max_pfn * sizeof(xen_pfn_t)); + pfns = malloc(pfn_array_size * sizeof(xen_pfn_t)); if (pfns == NULL) { ERROR("memory alloc failed"); errno = ENOMEM; @@ -139,11 +135,10 @@ int xc_hvm_restore(int xc_handle, int io goto out; } - for ( i = 0; i < max_pfn; i++ ) + for ( i = 0; i < pfn_array_size; i++ ) pfns[i] = i; - for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < max_pfn; i++ ) + for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < pfn_array_size; i++ ) pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; - arch_max_pfn = pfns[max_pfn - 1];/* used later */ /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */ rc = xc_domain_memory_populate_physmap( @@ -281,6 +276,14 @@ int xc_hvm_restore(int xc_handle, int io else shared_page_nr = (v_end >> PAGE_SHIFT) - 1; + /* Paranoia: clean pages. */ + if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) || + xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) || + xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) { + ERROR("error clearing comms frames!\n"); + goto out; + } + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1); xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2); xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr); @@ -288,6 +291,33 @@ int xc_hvm_restore(int xc_handle, int io /* caculate the store_mfn , wrong val cause hang when introduceDomain */ *store_mfn = (v_end >> PAGE_SHIFT) - 2; DPRINTF("hvm restore:calculate new store_mfn=0x%lx,v_end=0x%llx..\n", *store_mfn, v_end); + + if (!read_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) { + ERROR("error read nr vcpu !\n"); + goto out; + } + DPRINTF("hvm restore:get nr_vcpus=%d.\n", nr_vcpus); + + for (i =0; i < nr_vcpus; i++) { + if (!read_exact(io_fd, &rec_len, sizeof(uint32_t))) { + ERROR("error read vcpu context size!\n"); + goto out; + } + if (rec_len != sizeof(ctxt)) { + ERROR("vcpu context size dismatch!\n"); + goto out; + } + + if (!read_exact(io_fd, &(ctxt), sizeof(ctxt))) { + ERROR("error read vcpu context.\n"); + goto out; + } + + if ( (rc = xc_vcpu_setcontext(xc_handle, dom, i, &ctxt)) ) { + ERROR("Could not set vcpu context, rc=%d", rc); + goto out; + } + } /* restore hvm context including pic/pit/shpage */ if (!read_exact(io_fd, &rec_len, sizeof(uint32_t))) { @@ -311,56 +341,6 @@ int xc_hvm_restore(int xc_handle, int io ERROR("error set hvm buffer!\n"); goto out; } - - if (!read_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) { - ERROR("error read nr vcpu !\n"); - goto out; - } - DPRINTF("hvm restore:get nr_vcpus=%d.\n", nr_vcpus); - - for (i =0; i < nr_vcpus; i++) { - if (!read_exact(io_fd, &rec_len, sizeof(uint32_t))) { - ERROR("error read vcpu context size!\n"); - goto out; - } - if (rec_len != sizeof(ctxt)) { - ERROR("vcpu context size dismatch!\n"); - goto out; - } - - if (!read_exact(io_fd, &(ctxt), sizeof(ctxt))) { - ERROR("error read vcpu context.\n"); - goto out; - } - - if ( (rc = xc_vcpu_setcontext(xc_handle, dom, i, &ctxt)) ) { - ERROR("Could not set vcpu context, rc=%d", rc); - goto out; - } - } - - /* Shared-info pfn */ - if (!read_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) { - ERROR("reading the shared-info pfn failed!\n"); - goto out; - } - /* Map the shared-info frame where it was before */ - xatp.domid = dom; - xatp.space = XENMAPSPACE_shared_info; - xatp.idx = 0; - xatp.gpfn = shared_info_frame; - if ( (rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) != 0 ) { - ERROR("setting the shared-info pfn failed!\n"); - goto out; - } - if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) || - ((shared_info = xc_map_foreign_range( - xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, - shared_info_frame)) == NULL) ) - goto out; - /* shared_info.arch.max_pfn is used by dump-core */ - shared_info->arch.max_pfn = arch_max_pfn; - munmap(shared_info, PAGE_SIZE); rc = 0; goto out; diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_hvm_save.c --- a/tools/libxc/xc_hvm_save.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_hvm_save.c Wed Mar 21 18:08:31 2007 -0500 @@ -27,11 +27,13 @@ #include <stdlib.h> #include <unistd.h> #include <sys/time.h> -#include <xen/hvm/e820.h> #include "xc_private.h" #include "xg_private.h" #include "xg_save_restore.h" + +#include <xen/hvm/e820.h> +#include <xen/hvm/params.h> /* ** Default values for important tuning parameters. Can override by passing @@ -49,11 +51,30 @@ static unsigned long max_mfn; /* virtual starting address of the hypervisor */ static unsigned long hvirt_start; -/* #levels of page tables used by the currrent guest */ +/* #levels of page tables used by the current guest */ static unsigned int pt_levels; -/* total number of pages used by the current guest */ -static unsigned long max_pfn; +/* Shared-memory bitmaps for getting log-dirty bits from qemu */ +static unsigned long *qemu_bitmaps[2]; +static int qemu_active; +static int qemu_non_active; + +int xc_hvm_drain_io(int handle, domid_t dom) +{ + DECLARE_HYPERCALL; + xen_hvm_drain_io_t arg; + int rc; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_drain_io; + hypercall.arg[1] = (unsigned long)&arg; + arg.domid = dom; + if ( lock_pages(&arg, sizeof(arg)) != 0 ) + return -1; + rc = do_xen_hypercall(handle, &hypercall); + unlock_pages(&arg, sizeof(arg)); + return rc; +} /* ** During (live) save/migrate, we maintain a number of bitmaps to track @@ -61,7 +82,8 @@ static unsigned long max_pfn; */ #define BITS_PER_LONG (sizeof(unsigned long) * 8) -#define BITMAP_SIZE ((max_pfn + BITS_PER_LONG - 1) / 8) +#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) +#define BITMAP_SIZE (BITS_TO_LONGS(pfn_array_size) * sizeof(unsigned long)) #define BITMAP_ENTRY(_nr,_bmap) \ ((unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG] @@ -107,6 +129,7 @@ static inline int permute( int i, int nr return i; } + static uint64_t tv_to_us(struct timeval *new) { @@ -183,7 +206,7 @@ static int print_stats(int xc_handle, ui return 0; } -static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn, +static int analysis_phase(int xc_handle, uint32_t domid, int pfn_array_size, unsigned long *arr, int runs) { long long start, now; @@ -196,7 +219,7 @@ static int analysis_phase(int xc_handle, int i; xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN, - arr, max_pfn, NULL, 0, NULL); + arr, pfn_array_size, NULL, 0, NULL); DPRINTF("#Flush\n"); for ( i = 0; i < 40; i++ ) { usleep(50000); @@ -236,7 +259,7 @@ static int suspend_and_state(int (*suspe if (info->shutdown && info->shutdown_reason == SHUTDOWN_suspend) - return 0; // success + return 0; // success if (info->paused) { // try unpausing domain, wait, and retest @@ -261,17 +284,26 @@ static int suspend_and_state(int (*suspe } int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, - uint32_t max_factor, uint32_t flags, int (*suspend)(int)) + uint32_t max_factor, uint32_t flags, int (*suspend)(int), + void *(*init_qemu_maps)(int, unsigned), + void (*qemu_flip_buffer)(int, int)) { xc_dominfo_t info; int rc = 1, i, j, last_iter, iter = 0; int live = (flags & XCFLAGS_LIVE); int debug = (flags & XCFLAGS_DEBUG); + int stdvga = (flags & XCFLAGS_STDVGA); int sent_last_iter, skip_this_iter; - /* The new domain's shared-info frame number. */ - unsigned long shared_info_frame; + /* The highest guest-physical frame number used by the current guest */ + unsigned long max_pfn; + + /* The size of an array big enough to contain all guest pfns */ + unsigned long pfn_array_size; + + /* Other magic frames: ioreqs and xenstore comms */ + unsigned long ioreq_pfn, bufioreq_pfn, store_pfn; /* A copy of the CPU context of the guest. */ vcpu_guest_context_t ctxt; @@ -283,15 +315,12 @@ int xc_hvm_save(int xc_handle, int io_fd uint32_t hvm_buf_size; uint8_t *hvm_buf = NULL; - /* Live mapping of shared info structure */ - shared_info_t *live_shinfo = NULL; - /* base of the region in which domain memory is mapped */ unsigned char *region_base = NULL; uint32_t rec_size, nr_vcpus; - /* power of 2 order of max_pfn */ + /* power of 2 order of pfn_array_size */ int order_nr; /* bitmap of pages: @@ -337,7 +366,6 @@ int xc_hvm_save(int xc_handle, int io_fd ERROR("HVM:Could not get vcpu context"); goto out; } - shared_info_frame = info.shared_info_frame; /* cheesy sanity check */ if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) { @@ -346,10 +374,12 @@ int xc_hvm_save(int xc_handle, int io_fd goto out; } - /* Map the shared info frame */ - if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ, shared_info_frame))) { - ERROR("HVM:Couldn't map live_shinfo"); + if ( xc_get_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, &store_pfn) + || xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, &ioreq_pfn) + || xc_get_hvm_param(xc_handle, dom, + HVM_PARAM_BUFIOREQ_PFN, &bufioreq_pfn) ) + { + ERROR("HVM: Could not read magic PFN parameters"); goto out; } @@ -357,8 +387,6 @@ int xc_hvm_save(int xc_handle, int io_fd "nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); if (live) { - ERROR("hvm domain doesn't support live migration now.\n"); - goto out; if (xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, @@ -368,6 +396,7 @@ int xc_hvm_save(int xc_handle, int io_fd } last_iter = 0; + DPRINTF("hvm domain live migration debug start: logdirty enable.\n"); } else { /* This is a non-live suspend. Issue the call back to get the @@ -388,26 +417,43 @@ int xc_hvm_save(int xc_handle, int io_fd /* Calculate the highest PFN of "normal" memory: * HVM memory is sequential except for the VGA and MMIO holes. */ - max_pfn = info.nr_pages; + max_pfn = info.nr_pages - 1; + /* If the domain has a Cirrus framebuffer and we haven't already + * suspended qemu-dm, it will have 8MB of framebuffer memory + * still allocated, which we don't want to copy: qemu will save it + * for us later */ + if ( live && !stdvga ) + max_pfn -= 0x800; /* Skip the VGA hole from 0xa0000 to 0xc0000 */ - max_pfn += 0x20; + max_pfn += 0x20; /* Skip the MMIO hole: 256MB just below 4GB */ if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) ) max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT); - skip_this_iter = 0;/*XXX*/ + /* Size of any array that covers 0 ... max_pfn */ + pfn_array_size = max_pfn + 1; + /* pretend we sent all the pages last iteration */ - sent_last_iter = max_pfn; - - /* calculate the power of 2 order of max_pfn, e.g. + sent_last_iter = pfn_array_size; + + /* calculate the power of 2 order of pfn_array_size, e.g. 15->4 16->4 17->5 */ - for (i = max_pfn-1, order_nr = 0; i ; i >>= 1, order_nr++) + for (i = pfn_array_size-1, order_nr = 0; i ; i >>= 1, order_nr++) continue; /* Setup to_send / to_fix and to_skip bitmaps */ to_send = malloc(BITMAP_SIZE); to_skip = malloc(BITMAP_SIZE); + + if (live) { + /* Get qemu-dm logging dirty pages too */ + void *seg = init_qemu_maps(dom, BITMAP_SIZE); + qemu_bitmaps[0] = seg; + qemu_bitmaps[1] = seg + BITMAP_SIZE; + qemu_active = 0; + qemu_non_active = 1; + } hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0); if ( hvm_buf_size == -1 ) @@ -435,7 +481,7 @@ int xc_hvm_save(int xc_handle, int io_fd return 1; } - analysis_phase(xc_handle, dom, max_pfn, to_skip, 0); + analysis_phase(xc_handle, dom, pfn_array_size, to_skip, 0); /* We want zeroed memory so use calloc rather than malloc. */ @@ -465,9 +511,10 @@ int xc_hvm_save(int xc_handle, int io_fd DPRINTF("Saving HVM domain memory pages: iter %d 0%%", iter); - while( N < max_pfn ){ - - unsigned int this_pc = (N * 100) / max_pfn; + while( N < pfn_array_size ){ + + unsigned int this_pc = (N * 100) / pfn_array_size; + int rc; if ((this_pc - prev_pc) >= 5) { DPRINTF("\b\b\b\b%3d%%", this_pc); @@ -476,9 +523,9 @@ int xc_hvm_save(int xc_handle, int io_fd /* slightly wasteful to peek the whole array evey time, but this is fast enough for the moment. */ - if (!last_iter && xc_shadow_control( - xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, - to_skip, max_pfn, NULL, 0, NULL) != max_pfn) { + if (!last_iter && (rc = xc_shadow_control( + xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, + pfn_array_size, NULL, 0, NULL)) != pfn_array_size) { ERROR("Error peeking HVM shadow bitmap"); goto out; } @@ -486,11 +533,11 @@ int xc_hvm_save(int xc_handle, int io_fd /* load pfn_batch[] with the mfn of all the pages we're doing in this batch. */ - for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) { - - int n = permute(N, max_pfn, order_nr); - - if (debug) { + for (batch = 0; batch < MAX_BATCH_SIZE && N < pfn_array_size; N++){ + + int n = permute(N, pfn_array_size, order_nr); + + if (0&&debug) { DPRINTF("%d pfn= %08lx %d \n", iter, (unsigned long)n, test_bit(n, to_send)); } @@ -505,7 +552,10 @@ int xc_hvm_save(int xc_handle, int io_fd /* Skip PFNs that aren't really there */ if ((n >= 0xa0 && n < 0xc0) /* VGA hole */ || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) - && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */ + && n < (1ULL << 32) >> PAGE_SHIFT) /* 4G MMIO hole */ + || n == store_pfn + || n == ioreq_pfn + || n == bufioreq_pfn) continue; /* @@ -570,7 +620,7 @@ int xc_hvm_save(int xc_handle, int io_fd print_stats( xc_handle, dom, sent_this_iter, &stats, 1); DPRINTF("Total pages sent= %ld (%.2fx)\n", - total_sent, ((float)total_sent)/max_pfn ); + total_sent, ((float)total_sent)/pfn_array_size ); } if (last_iter && debug){ @@ -597,7 +647,7 @@ int xc_hvm_save(int xc_handle, int io_fd ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) || (iter >= max_iters) || (sent_this_iter+skip_this_iter < 50) || - (total_sent > max_pfn*max_factor) ) { + (total_sent > pfn_array_size*max_factor) ) { DPRINTF("Start last iteration for HVM domain\n"); last_iter = 1; @@ -608,23 +658,36 @@ int xc_hvm_save(int xc_handle, int io_fd goto out; } - DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n", - info.shared_info_frame, + DPRINTF("SUSPEND eip %08lx edx %08lx\n", (unsigned long)ctxt.user_regs.eip, (unsigned long)ctxt.user_regs.edx); } if (xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, - max_pfn, NULL, 0, &stats) != max_pfn) { + pfn_array_size, NULL, + 0, &stats) != pfn_array_size) { ERROR("Error flushing shadow PT"); goto out; } + /* Pull in the dirty bits from qemu too */ + if (!last_iter) { + qemu_active = qemu_non_active; + qemu_non_active = qemu_active ? 0 : 1; + qemu_flip_buffer(dom, qemu_active); + for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) { + to_send[j] |= qemu_bitmaps[qemu_non_active][j]; + qemu_bitmaps[qemu_non_active][j] = 0; + } + } else { + for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) + to_send[j] |= qemu_bitmaps[qemu_active][j]; + } + sent_last_iter = sent_this_iter; print_stats(xc_handle, dom, sent_this_iter, &stats, 1); - } @@ -640,20 +703,6 @@ int xc_hvm_save(int xc_handle, int io_fd goto out; } - if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, - hvm_buf_size)) == -1) { - ERROR("HVM:Could not get hvm buffer"); - goto out; - } - - if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) { - ERROR("error write hvm buffer size"); - goto out; - } - - if ( !write_exact(io_fd, hvm_buf, rec_size) ) { - ERROR("write HVM info failed!\n"); - } /* save vcpu/vmcs context */ if (!write_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) { @@ -682,12 +731,21 @@ int xc_hvm_save(int xc_handle, int io_fd } } - /* Shared-info pfn */ - if (!write_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) { - ERROR("write shared-info pfn failed!\n"); - goto out; - } - + if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, + hvm_buf_size)) == -1) { + ERROR("HVM:Could not get hvm buffer"); + goto out; + } + + if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) { + ERROR("error write hvm buffer size"); + goto out; + } + + if ( !write_exact(io_fd, hvm_buf, rec_size) ) { + ERROR("write HVM info failed!\n"); + } + /* Success! */ rc = 0; diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_linux_restore.c Wed Mar 21 18:08:31 2007 -0500 @@ -189,6 +189,7 @@ int xc_linux_restore(int xc_handle, int uint64_t vcpumap = 1ULL; unsigned int max_vcpu_id = 0; + int new_ctxt_format = 0; max_pfn = nr_pfns; @@ -372,6 +373,7 @@ int xc_linux_restore(int xc_handle, int } if (j == -2) { + new_ctxt_format = 1; if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) || (max_vcpu_id >= 64) || !read_exact(io_fd, &vcpumap, sizeof(uint64_t))) { @@ -797,6 +799,9 @@ int xc_linux_restore(int xc_handle, int goto out; } + if ( !new_ctxt_format ) + ctxt.flags |= VGCF_online; + if (i == 0) { /* * Uncanonicalise the suspend-record frame number and poke diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_misc.c --- a/tools/libxc/xc_misc.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_misc.c Wed Mar 21 18:08:31 2007 -0500 @@ -29,6 +29,25 @@ int xc_readconsolering(int xc_handle, *pnr_chars = sysctl.u.readconsole.count; unlock_pages(buffer, nr_chars); + + return ret; +} + +int xc_send_debug_keys(int xc_handle, char *keys) +{ + int ret, len = strlen(keys); + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_debug_keys; + set_xen_guest_handle(sysctl.u.debug_keys.keys, keys); + sysctl.u.debug_keys.nr_keys = len; + + if ( (ret = lock_pages(keys, len)) != 0 ) + return ret; + + ret = do_sysctl(xc_handle, &sysctl); + + unlock_pages(keys, len); return ret; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_private.c Wed Mar 21 18:08:31 2007 -0500 @@ -23,7 +23,7 @@ void xc_default_error_handler(const xc_e fprintf(stderr, "ERROR %s: %s\n", desc, err->message); } -const xc_error const *xc_get_last_error(void) +const xc_error *xc_get_last_error(void) { return &last_error; } @@ -263,6 +263,15 @@ int xc_memory_op(int xc_handle, goto out1; } break; + case XENMEM_current_reservation: + case XENMEM_maximum_reservation: + case XENMEM_maximum_gpfn: + if ( lock_pages(arg, sizeof(domid_t)) ) + { + PERROR("Could not lock"); + goto out1; + } + break; } ret = do_xen_hypercall(xc_handle, &hypercall); @@ -286,6 +295,11 @@ int xc_memory_op(int xc_handle, break; case XENMEM_add_to_physmap: unlock_pages(arg, sizeof(struct xen_add_to_physmap)); + break; + case XENMEM_current_reservation: + case XENMEM_maximum_reservation: + case XENMEM_maximum_gpfn: + unlock_pages(arg, sizeof(domid_t)); break; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xc_ptrace_core.c --- a/tools/libxc/xc_ptrace_core.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xc_ptrace_core.c Wed Mar 21 18:08:31 2007 -0500 @@ -390,7 +390,6 @@ map_gmfn_to_offset_elf(unsigned long gmf { /* * linear search - * There is no gurantee that those tables are sorted. */ unsigned long i; if (current_is_auto_translated_physmap) { diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xenctrl.h Wed Mar 21 18:08:31 2007 -0500 @@ -467,6 +467,8 @@ int xc_readconsolering(int xc_handle, unsigned int *pnr_chars, int clear); +int xc_send_debug_keys(int xc_handle, char *keys); + typedef xen_sysctl_physinfo_t xc_physinfo_t; int xc_physinfo(int xc_handle, xc_physinfo_t *info); @@ -770,19 +772,19 @@ typedef struct { * data pointed to are only valid until the next call to * libxc. */ -const xc_error const *xc_get_last_error(void); +const xc_error *xc_get_last_error(void); /* * Clear the last error */ void xc_clear_last_error(void); -typedef void (*xc_error_handler)(const xc_error const* err); +typedef void (*xc_error_handler)(const xc_error * const err); /* * The default error handler which prints to stderr */ -void xc_default_error_handler(const xc_error const* err); +void xc_default_error_handler(const xc_error * const err); /* * Convert an error code into a text description diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xenguest.h Wed Mar 21 18:08:31 2007 -0500 @@ -12,6 +12,7 @@ #define XCFLAGS_LIVE 1 #define XCFLAGS_DEBUG 2 #define XCFLAGS_HVM 4 +#define XCFLAGS_STDVGA 8 /** @@ -31,8 +32,10 @@ int xc_linux_save(int xc_handle, int io_ * @return 0 on success, -1 on failure */ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, - uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, - int (*suspend)(int domid)); + uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, + int (*suspend)(int domid), + void *(*init_qemu_maps)(int, unsigned), + void (*qemu_flip_buffer)(int, int)); /** * This function will restore a saved domain running Linux. @@ -155,6 +158,8 @@ int xc_get_hvm_param( int xc_get_hvm_param( int handle, domid_t dom, int param, unsigned long *value); +int xc_hvm_drain_io(int handle, domid_t dom); + /* PowerPC specific. */ int xc_prose_build(int xc_handle, uint32_t domid, diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxc/xg_private.c Wed Mar 21 18:08:31 2007 -0500 @@ -201,7 +201,9 @@ __attribute__((weak)) __attribute__((weak)) int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags, - int (*suspend)(int domid)) + int (*suspend)(int domid), + void *(*init_qemu_maps)(int, unsigned), + void (*qemu_flip_buffer)(int, int)) { errno = ENOSYS; return -1; @@ -225,6 +227,11 @@ __attribute__((weak)) int xc_get_hvm_par __attribute__((weak)) int xc_set_hvm_param( int handle, domid_t dom, int param, unsigned long value) +{ + return -ENOSYS; +} + +__attribute__((weak)) int xc_hvm_drain_io(int handle, domid_t dom) { return -ENOSYS; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/include/xen_crashdump.h --- a/tools/libxen/include/xen_crashdump.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/include/xen_crashdump.h Wed Mar 21 18:08:31 2007 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, XenSource Inc. + * Copyright (c) 2006-2007, XenSource Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -162,20 +162,6 @@ xen_crashdump_get_by_uuid(xen_session *s /** - * Create a new crashdump instance, and return its handle. - */ -extern bool -xen_crashdump_create(xen_session *session, xen_crashdump *result, xen_crashdump_record *record); - - -/** - * Destroy the specified crashdump instance. - */ -extern bool -xen_crashdump_destroy(xen_session *session, xen_crashdump crashdump); - - -/** * Get the uuid field of the given crashdump. */ extern bool @@ -197,6 +183,13 @@ xen_crashdump_get_vdi(xen_session *sessi /** + * Destroy the specified crashdump + */ +extern bool +xen_crashdump_destroy(xen_session *session, xen_crashdump self); + + +/** * Return a list of all the crashdumps known to the system. */ extern bool diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/include/xen_vbd.h --- a/tools/libxen/include/xen_vbd.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/include/xen_vbd.h Wed Mar 21 18:08:31 2007 -0500 @@ -72,7 +72,6 @@ typedef struct xen_vbd_record struct xen_vm_record_opt *vm; struct xen_vdi_record_opt *vdi; char *device; - char *image; bool bootable; enum xen_vbd_mode mode; enum xen_vbd_type type; @@ -358,6 +357,22 @@ xen_vbd_media_change(xen_session *sessio /** + * Hotplug the specified VBD, dynamically attaching it to the running + * VM + */ +extern bool +xen_vbd_plug(xen_session *session, xen_vbd self); + + +/** + * Hot-unplug the specified VBD, dynamically unattaching it from the + * running VM + */ +extern bool +xen_vbd_unplug(xen_session *session, xen_vbd self); + + +/** * Return a list of all the VBDs known to the system. */ extern bool diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/include/xen_vdi.h --- a/tools/libxen/include/xen_vdi.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/include/xen_vdi.h Wed Mar 21 18:08:31 2007 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, XenSource Inc. + * Copyright (c) 2006-2007, XenSource Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +22,7 @@ #include "xen_common.h" #include "xen_crashdump_decl.h" #include "xen_sr_decl.h" +#include "xen_string_string_map.h" #include "xen_vbd_decl.h" #include "xen_vdi_decl.h" #include "xen_vdi_type.h" @@ -73,11 +74,10 @@ typedef struct xen_vdi_record struct xen_crashdump_record_opt_set *crash_dumps; int64_t virtual_size; int64_t physical_utilisation; - int64_t sector_size; - char *location; enum xen_vdi_type type; bool sharable; bool read_only; + xen_string_string_map *other_config; } xen_vdi_record; /** @@ -251,13 +251,6 @@ xen_vdi_get_physical_utilisation(xen_ses /** - * Get the sector_size field of the given VDI. - */ -extern bool -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi); - - -/** * Get the type field of the given VDI. */ extern bool @@ -279,6 +272,13 @@ xen_vdi_get_read_only(xen_session *sessi /** + * Get the other_config field of the given VDI. + */ +extern bool +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi); + + +/** * Set the name/label field of the given VDI. */ extern bool @@ -293,13 +293,6 @@ xen_vdi_set_name_description(xen_session /** - * Set the SR field of the given VDI. - */ -extern bool -xen_vdi_set_sr(xen_session *session, xen_vdi vdi, xen_sr sr); - - -/** * Set the virtual_size field of the given VDI. */ extern bool @@ -318,6 +311,30 @@ xen_vdi_set_sharable(xen_session *sessio */ extern bool xen_vdi_set_read_only(xen_session *session, xen_vdi vdi, bool read_only); + + +/** + * Set the other_config field of the given VDI. + */ +extern bool +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config); + + +/** + * Add the given key-value pair to the other_config field of the given + * VDI. + */ +extern bool +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value); + + +/** + * Remove the given key and its corresponding value from the + * other_config field of the given VDI. If the key is not in that Map, then + * do nothing. + */ +extern bool +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key); /** diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/include/xen_vif.h --- a/tools/libxen/include/xen_vif.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/include/xen_vif.h Wed Mar 21 18:08:31 2007 -0500 @@ -332,6 +332,22 @@ xen_vif_remove_from_qos_algorithm_params /** + * Hotplug the specified VIF, dynamically attaching it to the running + * VM + */ +extern bool +xen_vif_plug(xen_session *session, xen_vif self); + + +/** + * Hot-unplug the specified VIF, dynamically unattaching it from the + * running VM + */ +extern bool +xen_vif_unplug(xen_session *session, xen_vif self); + + +/** * Return a list of all the VIFs known to the system. */ extern bool diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/include/xen_vm.h --- a/tools/libxen/include/xen_vm.h Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/include/xen_vm.h Wed Mar 21 18:08:31 2007 -0500 @@ -40,39 +40,6 @@ * The VM class. * * A virtual machine (or 'guest'). - * - * VM booting is controlled by setting one of the two mutually exclusive - * groups: "PV", and "HVM". If HVM.boot_policy is the empty string, then - * paravirtual domain building and booting will be used; otherwise the VM will - * be loaded as an HVM domain, and booted using an emulated BIOS. - * - * When paravirtual booting is in use, the PV/bootloader field indicates the - * bootloader to use. It may be "pygrub", in which case the platform's - * default installation of pygrub will be used, or a full path within the - * control domain to some other bootloader. The other fields, PV/kernel, - * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader - * unmodified, and interpretation of those fields is then specific to the - * bootloader itself, including the possibility that the bootloader will - * ignore some or all of those given values. Finally the paths of all bootable - * disks are added to the bootloader commandline (a disk is bootable if its - * VBD has the bootable flag set). There may be zero, one or many bootable - * disks; the bootloader decides which disk (if any) to boot from. - * - * If the bootloader is pygrub, then the menu.lst is parsed if present in the - * guest's filesystem, otherwise the specified kernel and ramdisk are used, or - * an autodetected kernel is used if nothing is specified and autodetection is - * possible. PV/args is appended to the kernel command line, no matter which - * mechanism is used for finding the kernel. - * - * If PV/bootloader is empty but PV/kernel is specified, then the kernel and - * ramdisk values will be treated as paths within the control domain. If both - * PV/bootloader and PV/kernel are empty, then the behaviour is as if - * PV/bootloader was specified as "pygrub". - * - * When using HVM booting, HVM/boot_policy and HVM/boot_params specify the - * boot handling. Only one policy is currently defined: "BIOS order". In - * this case, HVM/boot_params should contain one key-value pair "order" = "N" - * where N is the string that will be passed to QEMU.. */ @@ -120,7 +87,6 @@ typedef struct xen_vm_record int64_t memory_dynamic_max; int64_t memory_dynamic_min; int64_t memory_static_min; - char *vcpus_policy; xen_string_string_map *vcpus_params; int64_t vcpus_max; int64_t vcpus_at_startup; @@ -139,11 +105,7 @@ typedef struct xen_vm_record char *pv_bootloader_args; char *hvm_boot_policy; xen_string_string_map *hvm_boot_params; - bool platform_std_vga; - char *platform_serial; - bool platform_localtime; - bool platform_clock_offset; - bool platform_enable_audio; + xen_string_string_map *platform; char *pci_bus; xen_string_string_map *other_config; int64_t domid; @@ -360,13 +322,6 @@ xen_vm_get_memory_static_min(xen_session /** - * Get the VCPUs/policy field of the given VM. - */ -extern bool -xen_vm_get_vcpus_policy(xen_session *session, char **result, xen_vm vm); - - -/** * Get the VCPUs/params field of the given VM. */ extern bool @@ -493,38 +448,10 @@ xen_vm_get_hvm_boot_params(xen_session * /** - * Get the platform/std_VGA field of the given VM. - */ -extern bool -xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm); - - -/** - * Get the platform/serial field of the given VM. - */ -extern bool -xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm); - - -/** - * Get the platform/localtime field of the given VM. - */ -extern bool -xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm); - - -/** - * Get the platform/clock_offset field of the given VM. - */ -extern bool -xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm); - - -/** - * Get the platform/enable_audio field of the given VM. - */ -extern bool -xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm); + * Get the platform field of the given VM. + */ +extern bool +xen_vm_get_platform(xen_session *session, xen_string_string_map **result, xen_vm vm); /** @@ -630,13 +557,6 @@ xen_vm_set_memory_dynamic_min(xen_sessio */ extern bool xen_vm_set_memory_static_min(xen_session *session, xen_vm vm, int64_t static_min); - - -/** - * Set the VCPUs/policy field of the given VM. - */ -extern bool -xen_vm_set_vcpus_policy(xen_session *session, xen_vm vm, char *policy); /** @@ -765,38 +685,32 @@ xen_vm_remove_from_hvm_boot_params(xen_s /** - * Set the platform/std_VGA field of the given VM. - */ -extern bool -xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga); - - -/** - * Set the platform/serial field of the given VM. - */ -extern bool -xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial); - - -/** - * Set the platform/localtime field of the given VM. - */ -extern bool -xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime); - - -/** - * Set the platform/clock_offset field of the given VM. - */ -extern bool -xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset); - - -/** - * Set the platform/enable_audio field of the given VM. - */ -extern bool -xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio); + * Set the platform field of the given VM. + */ +extern bool +xen_vm_set_platform(xen_session *session, xen_vm vm, xen_string_string_map *platform); + + +/** + * Add the given key-value pair to the platform field of the given VM. + */ +extern bool +xen_vm_add_to_platform(xen_session *session, xen_vm vm, char *key, char *value); + + +/** + * Remove the given key and its corresponding value from the platform + * field of the given VM. If the key is not in that Map, then do nothing. + */ +extern bool +xen_vm_remove_from_platform(xen_session *session, xen_vm vm, char *key); + + +/** + * Set the PCI_bus field of the given VM. + */ +extern bool +xen_vm_set_pci_bus(xen_session *session, xen_vm vm, char *pci_bus); /** diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_common.c --- a/tools/libxen/src/xen_common.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_common.c Wed Mar 21 18:08:31 2007 -0500 @@ -110,7 +110,7 @@ static size_t size_of_member(const abstr static size_t size_of_member(const abstract_type *); static const char * -get_val_as_string(const struct abstract_type *, void *, char *); +get_val_as_string(const struct abstract_type *, void *, char *, size_t); void @@ -666,8 +666,7 @@ static void parse_into(xen_session *s, x { if (!is_container_node(value_node, "value") || value_node->children->type != XML_ELEMENT_NODE || - 0 != strcmp((char *)value_node->children->name, "struct") || - value_node->children->children == NULL) + 0 != strcmp((char *)value_node->children->name, "struct")) { server_error(s, "Expected Map from the server, but didn't get it"); @@ -890,6 +889,9 @@ static size_t size_of_member(const abstr case REF: return sizeof(arbitrary_record_opt *); + case STRUCT: + return type->struct_size; + default: assert(false); } @@ -1183,7 +1185,8 @@ add_struct_value(const struct abstract_t case INT: case ENUM: { - const char *val_as_string = get_val_as_string(type, value, buf); + const char *val_as_string = + get_val_as_string(type, value, buf, sizeof(buf)); adder(node, key, "string", val_as_string); } break; @@ -1215,7 +1218,8 @@ add_struct_value(const struct abstract_t for (size_t i = 0; i < set_val->size; i++) { - void *member_value = set_val->contents + (i * member_size); + void *member_value = (char *)set_val->contents + + (i * member_size); add_struct_value(member_type, member_value, add_unnamed_value, NULL, data_node); } @@ -1254,7 +1258,7 @@ add_struct_value(const struct abstract_t void *r_value = contents + (i * member_size) + r_offset; const char *l_value_as_string = - get_val_as_string(l_type, l_value, buf); + get_val_as_string(l_type, l_value, buf, sizeof(buf)); add_struct_value(r_type, r_value, add_struct_member, l_value_as_string, struct_node); @@ -1270,7 +1274,8 @@ add_struct_value(const struct abstract_t static const char * -get_val_as_string(const struct abstract_type *type, void *value, char *buf) +get_val_as_string(const struct abstract_type *type, void *value, char *buf, + size_t bufsize) { switch (type->typename) { @@ -1304,7 +1309,7 @@ get_val_as_string(const struct abstract_ case INT: { int64_t val = *(int64_t *)value; - snprintf(buf, sizeof(buf), "%"PRId64, val); + snprintf(buf, bufsize, "%"PRId64, val); return buf; } break; diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_crashdump.c --- a/tools/libxen/src/xen_crashdump.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_crashdump.c Wed Mar 21 18:08:31 2007 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, XenSource Inc. + * Copyright (c) 2006-2007, XenSource Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -115,37 +115,6 @@ xen_crashdump_get_by_uuid(xen_session *s bool -xen_crashdump_create(xen_session *session, xen_crashdump *result, xen_crashdump_record *record) -{ - abstract_value param_values[] = - { - { .type = &xen_crashdump_record_abstract_type_, - .u.struct_val = record } - }; - - abstract_type result_type = abstract_type_string; - - *result = NULL; - XEN_CALL_("crashdump.create"); - return session->ok; -} - - -bool -xen_crashdump_destroy(xen_session *session, xen_crashdump crashdump) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = crashdump } - }; - - xen_call_(session, "crashdump.destroy", param_values, 1, NULL, NULL); - return session->ok; -} - - -bool xen_crashdump_get_vm(xen_session *session, xen_vm *result, xen_crashdump crashdump) { abstract_value param_values[] = @@ -180,6 +149,20 @@ xen_crashdump_get_vdi(xen_session *sessi bool +xen_crashdump_destroy(xen_session *session, xen_crashdump self) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = self } + }; + + xen_call_(session, "crashdump.destroy", param_values, 1, NULL, NULL); + return session->ok; +} + + +bool xen_crashdump_get_all(xen_session *session, struct xen_crashdump_set **result) { diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_vbd.c --- a/tools/libxen/src/xen_vbd.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_vbd.c Wed Mar 21 18:08:31 2007 -0500 @@ -54,9 +54,6 @@ static const struct_member xen_vbd_recor { .key = "device", .type = &abstract_type_string, .offset = offsetof(xen_vbd_record, device) }, - { .key = "image", - .type = &abstract_type_string, - .offset = offsetof(xen_vbd_record, image) }, { .key = "bootable", .type = &abstract_type_bool, .offset = offsetof(xen_vbd_record, bootable) }, @@ -552,6 +549,34 @@ xen_vbd_media_change(xen_session *sessio bool +xen_vbd_plug(xen_session *session, xen_vbd self) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = self } + }; + + xen_call_(session, "VBD.plug", param_values, 1, NULL, NULL); + return session->ok; +} + + +bool +xen_vbd_unplug(xen_session *session, xen_vbd self) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = self } + }; + + xen_call_(session, "VBD.unplug", param_values, 1, NULL, NULL); + return session->ok; +} + + +bool xen_vbd_get_all(xen_session *session, struct xen_vbd_set **result) { diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_vdi.c --- a/tools/libxen/src/xen_vdi.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_vdi.c Wed Mar 21 18:08:31 2007 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, XenSource Inc. + * Copyright (c) 2006-2007, XenSource Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ #include "xen_crashdump.h" #include "xen_internal.h" #include "xen_sr.h" +#include "xen_string_string_map.h" #include "xen_vbd.h" #include "xen_vdi.h" #include "xen_vdi_type_internal.h" @@ -64,12 +65,6 @@ static const struct_member xen_vdi_recor { .key = "physical_utilisation", .type = &abstract_type_int, .offset = offsetof(xen_vdi_record, physical_utilisation) }, - { .key = "sector_size", - .type = &abstract_type_int, - .offset = offsetof(xen_vdi_record, sector_size) }, - { .key = "location", - .type = &abstract_type_string, - .offset = offsetof(xen_vdi_record, location) }, { .key = "type", .type = &xen_vdi_type_abstract_type_, .offset = offsetof(xen_vdi_record, type) }, @@ -78,7 +73,10 @@ static const struct_member xen_vdi_recor .offset = offsetof(xen_vdi_record, sharable) }, { .key = "read_only", .type = &abstract_type_bool, - .offset = offsetof(xen_vdi_record, read_only) } + .offset = offsetof(xen_vdi_record, read_only) }, + { .key = "other_config", + .type = &abstract_type_string_string_map, + .offset = offsetof(xen_vdi_record, other_config) } }; const abstract_type xen_vdi_record_abstract_type_ = @@ -105,6 +103,7 @@ xen_vdi_record_free(xen_vdi_record *reco xen_sr_record_opt_free(record->sr); xen_vbd_record_opt_set_free(record->vbds); xen_crashdump_record_opt_set_free(record->crash_dumps); + xen_string_string_map_free(record->other_config); free(record); } @@ -315,22 +314,6 @@ xen_vdi_get_physical_utilisation(xen_ses bool -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vdi } - }; - - abstract_type result_type = abstract_type_int; - - XEN_CALL_("VDI.get_sector_size"); - return session->ok; -} - - -bool xen_vdi_get_type(xen_session *session, enum xen_vdi_type *result, xen_vdi vdi) { abstract_value param_values[] = @@ -378,6 +361,23 @@ xen_vdi_get_read_only(xen_session *sessi bool +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi } + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("VDI.get_other_config"); + return session->ok; +} + + +bool xen_vdi_set_name_label(xen_session *session, xen_vdi vdi, char *label) { abstract_value param_values[] = @@ -405,22 +405,6 @@ xen_vdi_set_name_description(xen_session }; xen_call_(session, "VDI.set_name_description", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool -xen_vdi_set_sr(xen_session *session, xen_vdi vdi, xen_sr sr) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vdi }, - { .type = &abstract_type_string, - .u.string_val = sr } - }; - - xen_call_(session, "VDI.set_SR", param_values, 2, NULL, NULL); return session->ok; } @@ -474,6 +458,56 @@ xen_vdi_set_read_only(xen_session *sessi bool +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi }, + { .type = &abstract_type_string_string_map, + .u.set_val = (arbitrary_set *)other_config } + }; + + xen_call_(session, "VDI.set_other_config", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi }, + { .type = &abstract_type_string, + .u.string_val = key }, + { .type = &abstract_type_string, + .u.string_val = value } + }; + + xen_call_(session, "VDI.add_to_other_config", param_values, 3, NULL, NULL); + return session->ok; +} + + +bool +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi }, + { .type = &abstract_type_string, + .u.string_val = key } + }; + + xen_call_(session, "VDI.remove_from_other_config", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool xen_vdi_snapshot(xen_session *session, xen_vdi *result, xen_vdi vdi) { abstract_value param_values[] = diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_vif.c --- a/tools/libxen/src/xen_vif.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_vif.c Wed Mar 21 18:08:31 2007 -0500 @@ -500,6 +500,34 @@ xen_vif_remove_from_qos_algorithm_params bool +xen_vif_plug(xen_session *session, xen_vif self) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = self } + }; + + xen_call_(session, "VIF.plug", param_values, 1, NULL, NULL); + return session->ok; +} + + +bool +xen_vif_unplug(xen_session *session, xen_vif self) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = self } + }; + + xen_call_(session, "VIF.unplug", param_values, 1, NULL, NULL); + return session->ok; +} + + +bool xen_vif_get_all(xen_session *session, struct xen_vif_set **result) { diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/src/xen_vm.c --- a/tools/libxen/src/xen_vm.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/src/xen_vm.c Wed Mar 21 18:08:31 2007 -0500 @@ -88,9 +88,6 @@ static const struct_member xen_vm_record { .key = "memory_static_min", .type = &abstract_type_int, .offset = offsetof(xen_vm_record, memory_static_min) }, - { .key = "VCPUs_policy", - .type = &abstract_type_string, - .offset = offsetof(xen_vm_record, vcpus_policy) }, { .key = "VCPUs_params", .type = &abstract_type_string_string_map, .offset = offsetof(xen_vm_record, vcpus_params) }, @@ -145,21 +142,9 @@ static const struct_member xen_vm_record { .key = "HVM_boot_params", .type = &abstract_type_string_string_map, .offset = offsetof(xen_vm_record, hvm_boot_params) }, - { .key = "platform_std_VGA", - .type = &abstract_type_bool, - .offset = offsetof(xen_vm_record, platform_std_vga) }, - { .key = "platform_serial", - .type = &abstract_type_string, - .offset = offsetof(xen_vm_record, platform_serial) }, - { .key = "platform_localtime", - .type = &abstract_type_bool, - .offset = offsetof(xen_vm_record, platform_localtime) }, - { .key = "platform_clock_offset", - .type = &abstract_type_bool, - .offset = offsetof(xen_vm_record, platform_clock_offset) }, - { .key = "platform_enable_audio", - .type = &abstract_type_bool, - .offset = offsetof(xen_vm_record, platform_enable_audio) }, + { .key = "platform", + .type = &abstract_type_string_string_map, + .offset = offsetof(xen_vm_record, platform) }, { .key = "PCI_bus", .type = &abstract_type_string, .offset = offsetof(xen_vm_record, pci_bus) }, @@ -203,7 +188,6 @@ xen_vm_record_free(xen_vm_record *record free(record->name_description); xen_vdi_record_opt_free(record->suspend_vdi); xen_host_record_opt_free(record->resident_on); - free(record->vcpus_policy); xen_string_string_map_free(record->vcpus_params); xen_console_record_opt_set_free(record->consoles); xen_vif_record_opt_set_free(record->vifs); @@ -217,7 +201,7 @@ xen_vm_record_free(xen_vm_record *record free(record->pv_bootloader_args); free(record->hvm_boot_policy); xen_string_string_map_free(record->hvm_boot_params); - free(record->platform_serial); + xen_string_string_map_free(record->platform); free(record->pci_bus); xen_string_string_map_free(record->other_config); xen_vm_metrics_record_opt_free(record->metrics); @@ -510,23 +494,6 @@ xen_vm_get_memory_static_min(xen_session bool -xen_vm_get_vcpus_policy(xen_session *session, char **result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_string; - - *result = NULL; - XEN_CALL_("VM.get_VCPUs_policy"); - return session->ok; -} - - -bool xen_vm_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm vm) { abstract_value param_values[] = @@ -825,82 +792,18 @@ xen_vm_get_hvm_boot_params(xen_session * bool -xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_bool; - - XEN_CALL_("VM.get_platform_std_VGA"); - return session->ok; -} - - -bool -xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_string; - - *result = NULL; - XEN_CALL_("VM.get_platform_serial"); - return session->ok; -} - - -bool -xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_bool; - - XEN_CALL_("VM.get_platform_localtime"); - return session->ok; -} - - -bool -xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_bool; - - XEN_CALL_("VM.get_platform_clock_offset"); - return session->ok; -} - - -bool -xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm } - }; - - abstract_type result_type = abstract_type_bool; - - XEN_CALL_("VM.get_platform_enable_audio"); +xen_vm_get_platform(xen_session *session, xen_string_string_map **result, xen_vm vm) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm } + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("VM.get_platform"); return session->ok; } @@ -1150,22 +1053,6 @@ xen_vm_set_memory_static_min(xen_session bool -xen_vm_set_vcpus_policy(xen_session *session, xen_vm vm, char *policy) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_string, - .u.string_val = policy } - }; - - xen_call_(session, "VM.set_VCPUs_policy", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool xen_vm_set_vcpus_params(xen_session *session, xen_vm vm, xen_string_string_map *params) { abstract_value param_values[] = @@ -1442,81 +1329,67 @@ xen_vm_remove_from_hvm_boot_params(xen_s bool -xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_bool, - .u.bool_val = std_vga } - }; - - xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool -xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_string, - .u.string_val = serial } - }; - - xen_call_(session, "VM.set_platform_serial", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool -xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_bool, - .u.bool_val = localtime } - }; - - xen_call_(session, "VM.set_platform_localtime", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool -xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_bool, - .u.bool_val = clock_offset } - }; - - xen_call_(session, "VM.set_platform_clock_offset", param_values, 2, NULL, NULL); - return session->ok; -} - - -bool -xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_bool, - .u.bool_val = enable_audio } - }; - - xen_call_(session, "VM.set_platform_enable_audio", param_values, 2, NULL, NULL); +xen_vm_set_platform(xen_session *session, xen_vm vm, xen_string_string_map *platform) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string_string_map, + .u.set_val = (arbitrary_set *)platform } + }; + + xen_call_(session, "VM.set_platform", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_add_to_platform(xen_session *session, xen_vm vm, char *key, char *value) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = key }, + { .type = &abstract_type_string, + .u.string_val = value } + }; + + xen_call_(session, "VM.add_to_platform", param_values, 3, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_remove_from_platform(xen_session *session, xen_vm vm, char *key) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = key } + }; + + xen_call_(session, "VM.remove_from_platform", param_values, 2, NULL, NULL); + return session->ok; +} + + +bool +xen_vm_set_pci_bus(xen_session *session, xen_vm vm, char *pci_bus) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = pci_bus } + }; + + xen_call_(session, "VM.set_PCI_bus", param_values, 2, NULL, NULL); return session->ok; } diff -r 2c087916aaba -r 49ec3725d0c0 tools/libxen/test/test_bindings.c --- a/tools/libxen/test/test_bindings.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/libxen/test/test_bindings.c Wed Mar 21 18:08:31 2007 -0500 @@ -373,8 +373,9 @@ static xen_vm create_new_vm(xen_session .memory_dynamic_max = 256, .memory_dynamic_min = 128, .memory_static_min = 128, - .vcpus_policy = "credit", .vcpus_params = vcpus_params, + .vcpus_max = 4, + .vcpus_at_startup = 2, .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY, .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART, .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE, @@ -420,8 +421,7 @@ static xen_vm create_new_vm(xen_session .name_label = "MyRootFS", .name_description = "MyRootFS description", .sr = &sr_record, - .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector - .sector_size = 512, + .virtual_size = (INT64_C(1) << 30), // 1GiB .type = XEN_VDI_TYPE_SYSTEM, .sharable = false, .read_only = false diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/scripts/test_hvm_create.py --- a/tools/python/scripts/test_hvm_create.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/scripts/test_hvm_create.py Wed Mar 21 18:08:31 2007 -0500 @@ -39,14 +39,13 @@ local_vdi_cfg = { local_vdi_cfg = { 'name_label': 'gentoo.hvm', 'name_description': '', - 'location': 'file:/root/gentoo.amd64.hvm.img', 'virtual_size': 0, - 'sector_size': 0, 'type': 'system', 'parent': '', 'SR_name': 'Local', 'sharable': False, 'read_only': False, + 'other_config': {'location': 'file:/root/gentoo.amd64.hvm.img'}, } local_vbd_cfg = { diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/scripts/test_vm_create.py --- a/tools/python/scripts/test_vm_create.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/scripts/test_vm_create.py Wed Mar 21 18:08:31 2007 -0500 @@ -39,8 +39,7 @@ vdi_cfg = { vdi_cfg = { 'name_label': 'API_VDI', 'name_description': '', - 'virtual_size': 100 * 1024 * 1024, - 'sector_size': 1024, + 'virtual_size': 100 * 1024 * 1024 * 1024, 'type': 'system', 'parent': '', 'SR_name': 'QCoW', @@ -60,14 +59,13 @@ local_vdi_cfg = { local_vdi_cfg = { 'name_label': 'gentoo.amd64.img', 'name_description': '', - 'location': 'file:/root/gentoo.amd64.img', 'virtual_size': 0, - 'sector_size': 0, 'type': 'system', 'parent': '', 'SR_name': 'Local', 'sharable': False, 'read_only': False, + 'other_config': {'location': 'file:/root/gentoo.amd64.img'}, } local_vbd_cfg = { diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/scripts/xapi.py --- a/tools/python/scripts/xapi.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/scripts/xapi.py Wed Mar 21 18:08:31 2007 -0500 @@ -40,8 +40,7 @@ VM_LIST_FORMAT = '%(name_label)-18s %(me ' %(power_state)-10s %(uuid)-36s' SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \ '%(type)-10s' -VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\ - '%(sector_size)-8s' +VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s' VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s' TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s' VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s' @@ -96,12 +95,9 @@ OPTIONS = { 'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}), (('--name-description',), {'help': 'Description for VDI'}), - (('--sector-size',), {'type': 'int', - 'help': 'Sector size', - 'default': 0}), (('--virtual-size',), {'type': 'int', 'default': 0, - 'help': 'Size of VDI in sectors'}), + 'help': 'Size of VDI in bytes'}), (('--type',), {'choices': ['system', 'user', 'ephemeral'], 'default': 'system', 'help': 'VDI type'}), @@ -569,8 +565,7 @@ def xapi_vdi_list(args, async = False): if not is_long: print VDI_LIST_FORMAT % {'name_label': 'VDI Label', 'uuid' : 'UUID', - 'virtual_size': 'Bytes', - 'sector_size': 'Sector Size'} + 'virtual_size': 'Bytes'} for vdi in vdis: vdi_struct = execute(server, 'VDI.get_record', (session, vdi)) diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/scripts/xapi.vdicfg.py --- a/tools/python/scripts/xapi.vdicfg.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/scripts/xapi.vdicfg.py Wed Mar 21 18:08:31 2007 -0500 @@ -1,7 +1,6 @@ name_label = 'VDI 1' name_label = 'VDI 1' name_description = '' -virtual_size = 10 * 1024 * 1024 -sector_size = 1024 +virtual_size = 10 * 1024 * 1024 * 1024 type = 'system' sharable = False read_only = False diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/lowlevel/xc/xc.c Wed Mar 21 18:08:31 2007 -0500 @@ -47,20 +47,24 @@ static PyObject *pyxc_error_to_exception static PyObject *pyxc_error_to_exception(void) { PyObject *pyerr; - const xc_error const *err = xc_get_last_error(); + const xc_error *err = xc_get_last_error(); const char *desc = xc_error_code_to_desc(err->code); - if (err->code == XC_ERROR_NONE) + if ( err->code == XC_ERROR_NONE ) return PyErr_SetFromErrno(xc_error_obj); - if (err->message[0] != '\0') + if ( err->message[0] != '\0' ) pyerr = Py_BuildValue("(iss)", err->code, desc, err->message); else pyerr = Py_BuildValue("(is)", err->code, desc); xc_clear_last_error(); - PyErr_SetObject(xc_error_obj, pyerr); + if ( pyerr != NULL ) + { + PyErr_SetObject(xc_error_obj, pyerr); + Py_DECREF(pyerr); + } return NULL; } @@ -70,13 +74,13 @@ static PyObject *pyxc_domain_dumpcore(Xc uint32_t dom; char *corefile; - if (!PyArg_ParseTuple(args, "is", &dom, &corefile)) + if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) ) return NULL; if ( (corefile == NULL) || (corefile[0] == '\0') ) return NULL; - if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0) + if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 ) return pyxc_error_to_exception(); Py_INCREF(zero); @@ -168,10 +172,10 @@ static PyObject *pyxc_domain_shutdown(Xc { uint32_t dom, reason; - if (!PyArg_ParseTuple(args, "ii", &dom, &reason)) + if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) ) return NULL; - if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0) + if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 ) return pyxc_error_to_exception(); Py_INCREF(zero); @@ -183,10 +187,10 @@ static PyObject *pyxc_domain_resume(XcOb uint32_t dom; int fast; - if (!PyArg_ParseTuple(args, "ii", &dom, &fast)) - return NULL; - - if (xc_domain_resume(self->xc_handle, dom, fast) != 0) + if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) ) + return NULL; + + if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 ) return pyxc_error_to_exception(); Py_INCREF(zero); @@ -282,7 +286,7 @@ static PyObject *pyxc_domain_getinfo(XcO PyObject *args, PyObject *kwds) { - PyObject *list, *info_dict; + PyObject *list, *info_dict, *pyhandle; uint32_t first_dom = 0; int max_doms = 1024, nr_doms, i, j; @@ -308,26 +312,34 @@ static PyObject *pyxc_domain_getinfo(XcO list = PyList_New(nr_doms); for ( i = 0 ; i < nr_doms; i++ ) { - PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t)); + info_dict = Py_BuildValue( + "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" + ",s:L,s:L,s:L,s:i,s:i}", + "domid", (int)info[i].domid, + "online_vcpus", info[i].nr_online_vcpus, + "max_vcpu_id", info[i].max_vcpu_id, + "hvm", info[i].hvm, + "dying", info[i].dying, + "crashed", info[i].crashed, + "shutdown", info[i].shutdown, + "paused", info[i].paused, + "blocked", info[i].blocked, + "running", info[i].running, + "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024), + "cpu_time", (long long)info[i].cpu_time, + "maxmem_kb", (long long)info[i].max_memkb, + "ssidref", (int)info[i].ssidref, + "shutdown_reason", info[i].shutdown_reason); + pyhandle = PyList_New(sizeof(xen_domain_handle_t)); + if ( (pyhandle == NULL) || (info_dict == NULL) ) + { + Py_DECREF(list); + if ( pyhandle != NULL ) { Py_DECREF(pyhandle); } + if ( info_dict != NULL ) { Py_DECREF(info_dict); } + return NULL; + } for ( j = 0; j < sizeof(xen_domain_handle_t); j++ ) PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j])); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" - ",s:l,s:L,s:l,s:i,s:i}", - "domid", info[i].domid, - "online_vcpus", info[i].nr_online_vcpus, - "max_vcpu_id", info[i].max_vcpu_id, - "hvm", info[i].hvm, - "dying", info[i].dying, - "crashed", info[i].crashed, - "shutdown", info[i].shutdown, - "paused", info[i].paused, - "blocked", info[i].blocked, - "running", info[i].running, - "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024), - "cpu_time", info[i].cpu_time, - "maxmem_kb", info[i].max_memkb, - "ssidref", info[i].ssidref, - "shutdown_reason", info[i].shutdown_reason); PyDict_SetItemString(info_dict, "handle", pyhandle); Py_DECREF(pyhandle); PyList_SetItem(list, i, info_dict); @@ -1001,6 +1013,24 @@ static PyObject *pyxc_domain_send_trigge return NULL; if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} + +static PyObject *pyxc_send_debug_keys(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + char *keys; + + static char *kwd_list[] = { "keys", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) ) + return NULL; + + if ( xc_send_debug_keys(self->xc_handle, keys) != 0 ) return pyxc_error_to_exception(); Py_INCREF(zero); @@ -1379,6 +1409,12 @@ static PyMethodDef pyxc_methods[] = { " trigger [int]: Trigger type number.\n" " vcpu [int]: VCPU to be sent trigger.\n" "Returns: [int] 0 on success; -1 on error.\n" }, + + { "send_debug_keys", + (PyCFunction)pyxc_send_debug_keys, + METH_VARARGS | METH_KEYWORDS, "\n" + "Inject debug keys into Xen.\n" + " keys [str]: String of keys to inject.\n" }, #ifdef __powerpc__ { "arch_alloc_real_mode_area", diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/util/blkif.py --- a/tools/python/xen/util/blkif.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/util/blkif.py Wed Mar 21 18:08:31 2007 -0500 @@ -66,16 +66,23 @@ def blkdev_segment(name): 'type' : 'Disk' } return val -def blkdev_uname_to_file(uname): - """Take a blkdev uname and return the corresponding filename.""" - fn = None +def _parse_uname(uname): + fn = taptype = None if uname.find(":") != -1: (typ, fn) = uname.split(":", 1) if typ == "phy" and not fn.startswith("/"): fn = "/dev/%s" %(fn,) if typ == "tap": - (typ, fn) = fn.split(":", 1) - return fn + (taptype, fn) = fn.split(":", 1) + return (fn, taptype) + +def blkdev_uname_to_file(uname): + """Take a blkdev uname and return the corresponding filename.""" + return _parse_uname(uname)[0] + +def blkdev_uname_to_taptype(uname): + """Take a blkdev uname and return the blktap type.""" + return _parse_uname(uname)[1] def mount_mode(name): mode = None diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/util/xmlrpclib2.py --- a/tools/python/xen/util/xmlrpclib2.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/util/xmlrpclib2.py Wed Mar 21 18:08:31 2007 -0500 @@ -200,6 +200,18 @@ class TCPXMLRPCServer(SocketServer.Threa else: response = self._dispatch(method, params) + if self.xenapi and \ + (response is None or + not isinstance(response, dict) or + 'Status' not in response): + log.exception('Internal error handling %s: Invalid result %s', + method, response) + response = { "Status": "Failure", + "ErrorDescription": + ['INTERNAL_ERROR', + 'Invalid result %s handling %s' % + (response, method)]} + # With either Unicode or normal strings, we can only transmit # \t, \n, \r, \u0020-\ud7ff, \ue000-\ufffd, and \u10000-\u10ffff # in an XML document. xmlrpclib does not escape these values @@ -215,24 +227,30 @@ class TCPXMLRPCServer(SocketServer.Threa response = xmlrpclib.dumps(response, methodresponse=1, allow_none=1) - except xmlrpclib.Fault, fault: - response = xmlrpclib.dumps(fault) except Exception, exn: - if self.xenapi: - if _is_not_supported(exn): - errdesc = ['MESSAGE_METHOD_UNKNOWN', method] + try: + if self.xenapi: + if _is_not_supported(exn): + errdesc = ['MESSAGE_METHOD_UNKNOWN', method] + else: + log.exception('Internal error handling %s', method) + errdesc = ['INTERNAL_ERROR', str(exn)] + + response = xmlrpclib.dumps( + ({ "Status": "Failure", + "ErrorDescription": errdesc },), + methodresponse = 1) else: - log.exception('Internal error handling %s', method) - errdesc = ['INTERNAL_ERROR', str(exn)] - response = xmlrpclib.dumps( - ({ "Status": "Failure", - "ErrorDescription": errdesc },), - methodresponse = 1) - else: - log.exception('Internal error handling %s', method) - import xen.xend.XendClient - response = xmlrpclib.dumps( - xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn))) + import xen.xend.XendClient + if isinstance(exn, xmlrpclib.Fault): + response = xmlrpclib.dumps(exn) + else: + log.exception('Internal error handling %s', method) + response = xmlrpclib.dumps( + xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn))) + except: + log.exception('Internal error handling error') + return response @@ -241,7 +259,7 @@ def _is_not_supported(exn): try: m = notSupportedRE.search(exn[0]) return m is not None - except TypeError, e: + except: return False diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/xend/XendAPI.py Wed Mar 21 18:08:31 2007 -0500 @@ -31,9 +31,13 @@ from xen.xend.XendClient import ERROR_IN from xen.xend.XendClient import ERROR_INVALID_DOMAIN from xen.xend.XendLogging import log from xen.xend.XendTask import XendTask +from xen.xend.XendVMMetrics import XendVMMetrics from xen.xend.XendAPIConstants import * from xen.util.xmlrpclib2 import stringify + +from xen.util.blkif import blkdev_name_to_number + AUTH_NONE = 'none' AUTH_PAM = 'pam' @@ -192,6 +196,16 @@ def valid_vm(func): _check_ref(XendDomain.instance().is_valid_vm, 'VM', func, *args, **kwargs) +def valid_vm_metrics(func): + """Decorator to verify if vm_metrics_ref is valid before calling method. + + @param func: function with params: (self, session, vm_metrics_ref, ...) + @rtype: callable object + """ + return lambda *args, **kwargs: \ + _check_ref(XendVMMetrics.is_valid_vm_metrics, + 'VM_metrics', func, *args, **kwargs) + def valid_network(func): """Decorator to verify if network_ref is valid before calling method. @@ -400,6 +414,7 @@ class XendAPI(object): 'host_metrics' : valid_host_metrics, 'network' : valid_network, 'VM' : valid_vm, + 'VM_metrics' : valid_vm_metrics, 'VBD' : valid_vbd, 'VBD_metrics' : valid_vbd_metrics, 'VIF' : valid_vif, @@ -629,6 +644,7 @@ class XendAPI(object): host_attr_ro = ['software_version', 'resident_VMs', 'host_CPUs', + 'cpu_configuration', 'metrics', 'capabilities', 'supported_bootloaders', @@ -638,6 +654,7 @@ class XendAPI(object): 'API_version_vendor_implementation'] host_attr_rw = ['name_label', + 'sched_policy', 'name_description', 'other_config'] @@ -647,7 +664,9 @@ class XendAPI(object): ('shutdown', None), ('add_to_other_config', None), ('remove_from_other_config', None), - ('dmesg', 'String')] + ('dmesg', 'String'), + ('get_log', 'String'), + ('send_debug_keys', None)] host_funcs = [('get_by_name_label', 'Set(host)')] @@ -676,8 +695,9 @@ class XendAPI(object): return xen_api_success_void() def host_remove_from_other_config(self, session, host_ref, key): node = XendNode.instance() - del node.other_config[key] - node.save() + if key in node.other_config: + del node.other_config[key] + node.save() return xen_api_success_void() def host_get_API_version_major(self, _, ref): return xen_api_success(XEN_API_VERSION_MAJOR) @@ -699,7 +719,13 @@ class XendAPI(object): return xen_api_success(XendNode.instance().get_capabilities()) def host_get_supported_bootloaders(self, session, host_ref): return xen_api_success(['pygrub']) - + def host_get_sched_policy(self, _, host_ref): + return xen_api_success(XendNode.instance().get_vcpus_policy()) + def host_set_sched_policy(self, _, host_ref, policy): + return xen_api_todo() + def host_get_cpu_configuration(self, _, host_ref): + return xen_api_success(XendNode.instance().get_cpu_configuration()) + # object methods def host_disable(self, session, host_ref): XendDomain.instance().set_allow_new_domains(False) @@ -716,8 +742,21 @@ class XendAPI(object): return xen_api_error(XEND_ERROR_HOST_RUNNING) return xen_api_error(XEND_ERROR_UNSUPPORTED) - def host_dmesg(self, session, host_ref): - return xen_api_success(XendDmesg.instance().info()) + def host_dmesg(self, session, host_ref, clear): + if clear: + return xen_api_success(XendDmesg.instance().clear()) + else: + return xen_api_success(XendDmesg.instance().info()) + + def host_get_log(self, session, host_ref): + log_file = open(XendLogging.getLogFilename()) + log_buffer = log_file.read() + return xen_api_success(log_buffer) + + def host_send_debug_keys(self, _, host_ref, keys): + node = XendNode.instance() + node.send_debug_keys(keys) + return xen_api_success_void() def host_get_record(self, session, host_ref): node = XendNode.instance() @@ -734,9 +773,11 @@ class XendAPI(object): 'other_config': node.other_config, 'resident_VMs': dom.get_domain_refs(), 'host_CPUs': node.get_host_cpu_refs(), + 'cpu_configuration': node.get_cpu_configuration(), 'metrics': node.host_metrics_uuid, 'capabilities': node.get_capabilities(), - 'supported_bootloaders': 'pygrub'} + 'supported_bootloaders': 'pygrub', + 'sched_policy': node.get_vcpus_policy()} return xen_api_success(record) # class methods @@ -758,7 +799,8 @@ class XendAPI(object): 'modelname', 'stepping', 'flags', - 'utilisation'] + 'utilisation', + 'features'] # attributes def _host_cpu_get(self, ref, field): @@ -767,6 +809,8 @@ class XendAPI(object): def host_cpu_get_host(self, _, ref): return xen_api_success(XendNode.instance().uuid) + def host_cpu_get_features(self, _, ref): + return self._host_cpu_get(ref, 'features') def host_cpu_get_number(self, _, ref): return self._host_cpu_get(ref, 'number') def host_cpu_get_vendor(self, _, ref): @@ -989,19 +1033,17 @@ class XendAPI(object): VM_attr_ro = ['power_state', 'resident_on', - 'memory_actual', 'memory_static_max', 'memory_static_min', 'VCPUs_number', - 'VCPUs_utilisation', 'consoles', 'VIFs', 'VBDs', 'VTPMs', - 'PCI_bus', 'tools_version', 'domid', 'is_control_domain', + 'metrics' ] VM_attr_rw = ['name_label', @@ -1011,7 +1053,6 @@ class XendAPI(object): 'auto_power_on', 'memory_dynamic_max', 'memory_dynamic_min', - 'VCPUs_policy', 'VCPUs_params', 'actions_after_shutdown', 'actions_after_reboot', @@ -1024,12 +1065,8 @@ class XendAPI(object): 'PV_bootloader_args', 'HVM_boot_policy', 'HVM_boot_params', - 'platform_std_VGA', - 'platform_serial', - 'platform_localtime', - 'platform_clock_offset', - 'platform_enable_audio', - 'platform_keymap', + 'platform', + 'PCI_bus', 'other_config'] VM_methods = [('clone', 'VM'), @@ -1042,8 +1079,16 @@ class XendAPI(object): ('hard_reboot', None), ('suspend', None), ('resume', None), + ('send_sysrq', None), + ('add_to_HVM_boot_params', None), + ('remove_from_HVM_boot_params', None), + ('add_to_VCPUs_params', None), + ('remove_from_VCPUs_params', None), + ('add_to_platform', None), + ('remove_from_platform', None), ('add_to_other_config', None), - ('remove_from_other_config', None)] + ('remove_from_other_config', None), + ('send_trigger', None)] VM_funcs = [('create', 'VM'), ('get_by_name_label', 'Set(VM)')] @@ -1058,7 +1103,6 @@ class XendAPI(object): 'memory_dynamic_max', 'memory_dynamic_min', 'memory_static_min', - 'VCPUs_policy', 'VCPUs_params', 'actions_after_shutdown', 'actions_after_reboot', @@ -1071,13 +1115,7 @@ class XendAPI(object): 'PV_bootloader_args', 'HVM_boot_policy', 'HVM_boot_params', - 'platform_std_VGA', - 'platform_serial', - 'platform_localtime', - 'platform_clock_offset', - 'platform_enable_audio', - 'platform_keymap', - 'grub_cmdline', + 'platform', 'PCI_bus', 'other_config'] @@ -1089,7 +1127,10 @@ class XendAPI(object): xd = XendDomain.instance() dominfo = xd.get_vm_by_uuid(vm_ref) dominfo.info[name] = value - xd.managed_config_save(dominfo) + return self._VM_save(dominfo) + + def _VM_save(self, dominfo): + XendDomain.instance().managed_config_save(dominfo) return xen_api_success_void() # attributes (ro) @@ -1099,11 +1140,7 @@ class XendAPI(object): def VM_get_resident_on(self, session, vm_ref): return xen_api_success(XendNode.instance().uuid) - - def VM_get_memory_actual(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() # unsupported by xc - + def VM_get_memory_static_max(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_memory_static_max()) @@ -1116,10 +1153,6 @@ class XendAPI(object): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.getVCpuCount()) - def VM_get_VCPUs_utilisation(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_vcpus_util()) - def VM_get_VIFs(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_vifs()) @@ -1136,13 +1169,13 @@ class XendAPI(object): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_consoles()) - def VM_get_PCI_bus(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return dom.get_pci_bus() - def VM_get_tools_version(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return dom.get_tools_version() + + def VM_get_metrics(self, _, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return xen_api_success(dom.get_metrics()) # attributes (rw) def VM_get_name_label(self, session, vm_ref): @@ -1167,11 +1200,7 @@ class XendAPI(object): def VM_get_memory_dynamic_min(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_memory_dynamic_min()) - - def VM_get_VCPUs_policy(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_vcpus_policy()) + return xen_api_success(dom.get_memory_dynamic_min()) def VM_get_VCPUs_params(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -1214,29 +1243,16 @@ class XendAPI(object): def VM_get_HVM_boot_params(self, session, vm_ref): return self.VM_get('HVM_boot_params', session, vm_ref) - def VM_get_platform_std_VGA(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_std_vga()) - - def VM_get_platform_serial(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_serial()) - - def VM_get_platform_localtime(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_localtime()) - - def VM_get_platform_clock_offset(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_clock_offset()) - - def VM_get_platform_enable_audio(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_enable_audio()) - - def VM_get_platform_keymap(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_platform_keymap()) + def VM_get_platform(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return xen_api_success(dom.get_platform()) + + def VM_get_PCI_bus(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return dom.get_pci_bus() + + def VM_set_PCI_bus(self, session, vm_ref, val): + return self.VM_set('PCI_bus', session, vm_ref, val) def VM_get_other_config(self, session, vm_ref): return self.VM_get('other_config', session, vm_ref) @@ -1253,7 +1269,7 @@ class XendAPI(object): def VM_set_name_label(self, session, vm_ref, label): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) dom.setName(label) - return xen_api_success_void() + return self._VM_save(dom) def VM_set_name_description(self, session, vm_ref, desc): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -1275,21 +1291,32 @@ class XendAPI(object): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_todo() - def VM_set_VCPUs_policy(self, session, vm_ref, policy): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() - - def VM_set_VCPUs_params(self, session, vm_ref, params): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + def VM_set_VCPUs_params(self, session, vm_ref, value): + return self.VM_set('vcpus_params', session, vm_ref, value) + + def VM_add_to_VCPUs_params(self, session, vm_ref, key, value): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + if 'vcpus_params' not in dom.info: + dom.info['vcpus_params'] = {} + dom.info['vcpus_params'][key] = value + return self._VM_save(dom) + + def VM_remove_from_VCPUs_params(self, session, vm_ref, key): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + if 'vcpus_params' in dom.info \ + and key in dom.info['vcpus_params']: + del dom.info['vcpus_params'][key] + return self._VM_save(dom) + else: + return xen_api_success_void() def VM_set_actions_after_shutdown(self, session, vm_ref, action): - if action not in XEN_API_ON_NORMAL_EXIST: + if action not in XEN_API_ON_NORMAL_EXIT: return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) return self.VM_set('actions_after_shutdown', session, vm_ref, action) def VM_set_actions_after_reboot(self, session, vm_ref, action): - if action not in XEN_API_ON_NORMAL_EXIST: + if action not in XEN_API_ON_NORMAL_EXIT: return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) return self.VM_set('actions_after_reboot', session, vm_ref, action) @@ -1319,14 +1346,16 @@ class XendAPI(object): if 'HVM_boot_params' not in dom.info: dom.info['HVM_boot_params'] = {} dom.info['HVM_boot_params'][key] = value - return xen_api_success_void() + return self._VM_save(dom) def VM_remove_from_HVM_boot_params(self, session, vm_ref, key): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) if 'HVM_boot_params' in dom.info \ and key in dom.info['HVM_boot_params']: del dom.info['HVM_boot_params'][key] - return xen_api_success_void() + return self._VM_save(dom) + else: + return xen_api_success_void() def VM_set_PV_bootloader(self, session, vm_ref, value): return self.VM_set('PV_bootloader', session, vm_ref, value) @@ -1343,40 +1372,42 @@ class XendAPI(object): def VM_set_PV_bootloader_args(self, session, vm_ref, value): return self.VM_set('PV_bootloader_args', session, vm_ref, value) - def VM_set_platform_std_VGA(self, session, vm_ref, value): - return self.VM_set('platform_std_vga', session, vm_ref, value) - - def VM_set_platform_serial(self, session, vm_ref, value): - return self.VM_set('platform_serial', session, vm_ref, value) - - def VM_set_platform_keymap(self, session, vm_ref, value): - return self.VM_set('platform_keymap', session, vm_ref, value) - - def VM_set_platform_localtime(self, session, vm_ref, value): - return self.VM_set('platform_localtime', session, vm_ref, value) - - def VM_set_platform_clock_offset(self, session, vm_ref, value): - return self.VM_set('platform_clock_offset', session, vm_ref, value) - - def VM_set_platform_enable_audio(self, session, vm_ref, value): - return self.VM_set('platform_enable_audio', session, vm_ref, value) - + def VM_set_platform(self, session, vm_ref, value): + return self.VM_set('platform', session, vm_ref, value) + + def VM_add_to_platform(self, session, vm_ref, key, value): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + plat = dom.get_platform() + plat[key] = value + return self.VM_set_platform(session, vm_ref, plat) + + def VM_remove_from_platform(self, session, vm_ref, key): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + plat = dom.get_platform() + if key in plat: + del plat[key] + return self.VM_set_platform(session, vm_ref, plat) + else: + return xen_api_success_void() + def VM_set_other_config(self, session, vm_ref, value): - return self.VM_set('otherconfig', session, vm_ref, value) + return self.VM_set('other_config', session, vm_ref, value) def VM_add_to_other_config(self, session, vm_ref, key, value): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - if dom and 'otherconfig' in dom.info: - dom.info['otherconfig'][key] = value - return xen_api_success_void() + if dom and 'other_config' in dom.info: + dom.info['other_config'][key] = value + return self._VM_save(dom) def VM_remove_from_other_config(self, session, vm_ref, key): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - if dom and 'otherconfig' in dom.info \ - and key in dom.info['otherconfig']: - del dom.info['otherconfig'][key] - return xen_api_success_void() - + if dom and 'other_config' in dom.info \ + and key in dom.info['other_config']: + del dom.info['other_config'][key] + return self._VM_save(dom) + else: + return xen_api_success_void() + # class methods def VM_get_all(self, session): refs = [d.get_uuid() for d in XendDomain.instance().list('all')] @@ -1417,11 +1448,8 @@ class XendAPI(object): 'memory_static_max': xeninfo.get_memory_static_max(), 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(), 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(), - 'memory_actual': xeninfo.get_memory_static_min(), - 'VCPUs_policy': xeninfo.get_vcpus_policy(), 'VCPUs_params': xeninfo.get_vcpus_params(), 'VCPUs_number': xeninfo.getVCpuCount(), - 'VCPUs_utilisation': xeninfo.get_vcpus_util(), 'actions_after_shutdown': xeninfo.get_on_shutdown(), 'actions_after_reboot': xeninfo.get_on_reboot(), 'actions_after_suspend': xeninfo.get_on_suspend(), @@ -1437,12 +1465,7 @@ class XendAPI(object): 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'), 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'), 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'), - 'platform_std_VGA': xeninfo.get_platform_std_vga(), - 'platform_serial': xeninfo.get_platform_serial(), - 'platform_localtime': xeninfo.get_platform_localtime(), - 'platform_clock_offset': xeninfo.get_platform_clock_offset(), - 'platform_enable_audio': xeninfo.get_platform_enable_audio(), - 'platform_keymap': xeninfo.get_platform_keymap(), + 'platform': xeninfo.get_platform(), 'PCI_bus': xeninfo.get_pci_bus(), 'tools_version': xeninfo.get_tools_version(), 'other_config': xeninfo.info.get('other_config', {}), @@ -1486,10 +1509,13 @@ class XendAPI(object): start_paused = start_paused) def VM_start(self, session, vm_ref, start_paused): - return XendTask.log_progress(0, 100, do_vm_func, - "domain_start", vm_ref, - start_paused = start_paused) - + try: + return XendTask.log_progress(0, 100, do_vm_func, + "domain_start", vm_ref, + start_paused = start_paused) + except HVMRequired, exn: + return xen_api_error(['VM_HVM_REQUIRED', vm_ref]) + def VM_suspend(self, session, vm_ref): return XendTask.log_progress(0, 100, do_vm_func, "domain_suspend", vm_ref) @@ -1498,10 +1524,56 @@ class XendAPI(object): return XendTask.log_progress(0, 100, do_vm_func, "domain_unpause", vm_ref) + def VM_send_sysrq(self, _, vm_ref, req): + xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref) + if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING: + return xen_api_error( + ['VM_BAD_POWER_STATE', vm_ref, + XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING], + XendDomain.POWER_STATE_NAMES[xeninfo.state]]) + xeninfo.send_sysrq(req) + return xen_api_success_void() + + + def VM_send_trigger(self, _, vm_ref, trigger, vcpu): + xendom = XendDomain.instance() + xeninfo = xendom.get_vm_by_uuid(vm_ref) + xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu) + return xen_api_success_void() + + + # Xen API: Class VM_metrics + # ---------------------------------------------------------------- + + VM_metrics_attr_ro = ['memory_actual', + 'vcpus_number', + 'vcpus_utilisation'] + VM_metrics_attr_rw = [] + VM_metrics_methods = [] + + def _VM_metrics_get(self, ref): + return XendVMMetrics.get_by_uuid(ref) + + def VM_metrics_get_all(self, _): + return xen_api_success(XendVMMetrics.get_all()) + + def VM_metrics_get_record(self, _, ref): + return xen_api_success(self._VM_metrics_get(ref).get_record()) + + def VM_metrics_get_memory_actual(self, _, ref): + return xen_api_success(self._VM_metrics_get(ref).get_memory_actual()) + + def VM_metrics_get_vcpus_number(self, _, ref): + return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number()) + + def VM_metrics_get_vcpus_utilisation(self, _, ref): + return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation()) + # Xen API: Class VBD # ---------------------------------------------------------------- - VBD_attr_ro = ['metrics'] + VBD_attr_ro = ['metrics', + 'runtime_properties'] VBD_attr_rw = ['VM', 'VDI', 'device', @@ -1542,23 +1614,28 @@ class XendAPI(object): # class methods def VBD_create(self, session, vbd_struct): xendom = XendDomain.instance() + xennode = XendNode.instance() + if not xendom.is_valid_vm(vbd_struct['VM']): return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']]) dom = xendom.get_vm_by_uuid(vbd_struct['VM']) - vbd_ref = '' + vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI']) + if not vdi: + return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref]) + + # new VBD via VDI/SR + vdi_image = vdi.get_location() + try: - # new VBD via VDI/SR - vdi_ref = vbd_struct.get('VDI') - vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref) - if not vdi: - return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref]) - vdi_image = vdi.get_location() vbd_ref = XendTask.log_progress(0, 100, dom.create_vbd, vbd_struct, vdi_image) - except XendError: - return xen_api_todo() + except XendError, e: + log.exception("Error in VBD_create") + return xen_api_error(['INTERNAL_ERROR', str(e)]) + + vdi.addVBD(vbd_ref) xendom.managed_config_save(dom) return xen_api_success(vbd_ref) @@ -1570,7 +1647,14 @@ class XendAPI(object): if not vm: return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref]) + vdi_ref = XendDomain.instance()\ + .get_dev_property_by_uuid('vbd', vbd_ref, "VDI") + vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref) + XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref) + + vdi.removeVBD(vbd_ref) + return xen_api_success_void() def _VBD_get(self, vbd_ref, prop): @@ -1581,6 +1665,24 @@ class XendAPI(object): # attributes (ro) def VBD_get_metrics(self, _, vbd_ref): return xen_api_success(vbd_ref) + + def VBD_get_runtime_properties(self, _, vbd_ref): + xendom = XendDomain.instance() + dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref) + device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref) + + try: + devid = int(device['id']) + device_sxps = dominfo.getDeviceSxprs('vbd') + device_dicts = [dict(device_sxp[1][1:]) for device_sxp in device_sxps] + device_dict = [device_dict + for device_dict in device_dicts + if int(device_dict['virtual-device']) == devid][0] + + return xen_api_success(device_dict) + except Exception, exn: + log.exception(exn) + return xen_api_success({}) # attributes (rw) def VBD_get_VM(self, session, vbd_ref): @@ -1642,7 +1744,8 @@ class XendAPI(object): # Xen API: Class VIF # ---------------------------------------------------------------- - VIF_attr_ro = ['metrics'] + VIF_attr_ro = ['metrics', + 'runtime_properties'] VIF_attr_rw = ['device', 'network', 'VM', @@ -1679,18 +1782,17 @@ class XendAPI(object): # class methods def VIF_create(self, session, vif_struct): xendom = XendDomain.instance() - if xendom.is_valid_vm(vif_struct['VM']): - dom = xendom.get_vm_by_uuid(vif_struct['VM']) - try: - vif_ref = dom.create_vif(vif_struct) - xendom.managed_config_save(dom) - return xen_api_success(vif_ref) - except XendError: - return xen_api_error(XEND_ERROR_TODO) - else: + if not xendom.is_valid_vm(vif_struct['VM']): return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']]) - + dom = xendom.get_vm_by_uuid(vif_struct['VM']) + try: + vif_ref = dom.create_vif(vif_struct) + xendom.managed_config_save(dom) + return xen_api_success(vif_ref) + except XendError: + return xen_api_error(XEND_ERROR_TODO) + def VIF_destroy(self, session, vif_ref): xendom = XendDomain.instance() vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) @@ -1728,6 +1830,27 @@ class XendAPI(object): vifs = reduce(lambda x, y: x + y, vifs) return xen_api_success(vifs) + def VIF_get_runtime_properties(self, _, vif_ref): + xendom = XendDomain.instance() + dominfo = xendom.get_vm_with_dev_uuid('vif', vif_ref) + device = dominfo.get_dev_config_by_uuid('vif', vif_ref) + + try: + devid = int(device['id']) + + device_sxps = dominfo.getDeviceSxprs('vif') + device_dicts = [dict(device_sxp[1][1:]) + for device_sxp in device_sxps] + + device_dict = [device_dict + for device_dict in device_dicts + if int(device_dict['handle']) == devid][0] + + return xen_api_success(device_dict) + + except Exception, exn: + log.exception(exn) + return xen_api_success({}) # Xen API: Class VIF_metrics # ---------------------------------------------------------------- @@ -1754,16 +1877,16 @@ class XendAPI(object): # Xen API: Class VDI # ---------------------------------------------------------------- - VDI_attr_ro = ['VBDs', + VDI_attr_ro = ['SR', + 'VBDs', 'physical_utilisation', - 'sector_size', 'type'] VDI_attr_rw = ['name_label', 'name_description', - 'SR', 'virtual_size', 'sharable', - 'read_only'] + 'read_only', + 'other_config'] VDI_attr_inst = VDI_attr_ro + VDI_attr_rw VDI_methods = [('snapshot', 'VDI')] @@ -1774,14 +1897,12 @@ class XendAPI(object): return XendNode.instance().get_vdi_by_uuid(ref) def VDI_get_VBDs(self, session, vdi_ref): - return xen_api_todo() + vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref) + return xen_api_success(vdi.getVBDs()) def VDI_get_physical_utilisation(self, session, vdi_ref): return xen_api_success(self._get_VDI(vdi_ref). - get_physical_utilisation()) - - def VDI_get_sector_size(self, session, vdi_ref): - return xen_api_success(self._get_VDI(vdi_ref).sector_size) + get_physical_utilisation()) def VDI_get_type(self, session, vdi_ref): return xen_api_success(self._get_VDI(vdi_ref).type) @@ -1812,9 +1933,6 @@ class XendAPI(object): self._get_VDI(vdi_ref).name_description = value return xen_api_success_void() - def VDI_set_SR(self, session, vdi_ref, value): - return xen_api_error(XEND_ERROR_UNSUPPORTED) - def VDI_set_virtual_size(self, session, vdi_ref, value): return xen_api_error(XEND_ERROR_UNSUPPORTED) @@ -1824,6 +1942,14 @@ class XendAPI(object): def VDI_set_read_only(self, session, vdi_ref, value): self._get_VDI(vdi_ref).read_only = bool(value) + return xen_api_success_void() + + def VDI_get_other_config(self, session, vdi_ref): + return xen_api_success( + self._get_VDI(vdi_ref).other_config) + + def VDI_set_other_config(self, session, vdi_ref, other_config): + self._get_VDI(vdi_ref).other_config = other_config return xen_api_success_void() # Object Methods @@ -1842,13 +1968,13 @@ class XendAPI(object): 'name_label': image.name_label, 'name_description': image.name_description, 'SR': image.sr_uuid, - 'VBDs': [], # TODO + 'VBDs': image.getVBDs(), 'virtual_size': image.virtual_size, 'physical_utilisation': image.physical_utilisation, - 'sector_size': image.sector_size, 'type': image.type, 'sharable': image.sharable, 'read_only': image.read_only, + 'other_config': image.other_config }) # Class Functions @@ -1929,7 +2055,7 @@ class XendAPI(object): XendDomain.POWER_STATE_NAMES[dom.state]]) from xen.xend.server import tpmif tpmif.destroy_vtpmstate(dom.getName()) - return xen_api_success(True) + return xen_api_success_void() else: return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']]) diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Mar 21 18:08:31 2007 -0500 @@ -9,6 +9,7 @@ import re import re import string import threading +import fcntl from struct import pack, unpack, calcsize from xen.util.xpopen import xPopen3 @@ -73,10 +74,15 @@ def save(fd, dominfo, network, live, dst write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {}) - hvm = image_cfg.has_key('hvm') + hvm = dominfo.info.is_hvm() + stdvga = 0 if hvm: log.info("save hvm domain") + if dominfo.info['platform'].has_key('stdvga'): + if dominfo.info['platform']['stdvga'] == 1: + stdvga = 1 + # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is @@ -84,7 +90,8 @@ def save(fd, dominfo, network, live, dst # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), - str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] + str(dominfo.getDomid()), "0", "0", + str(int(live) | (int(hvm) << 2) | (int(stdvga) << 3)) ] log.debug("[xc_save]: %s", string.join(cmd)) def saveInputHandler(line, tochild): @@ -183,11 +190,11 @@ def restore(xd, fd, dominfo = None, paus # if hvm, pass mem size to calculate the store_mfn image_cfg = dominfo.info.get('image', {}) - is_hvm = image_cfg.has_key('hvm') + is_hvm = dominfo.info.is_hvm() if is_hvm: hvm = dominfo.info['memory_static_min'] - apic = dominfo.info['image']['hvm'].get('apic', 0) - pae = dominfo.info['image']['hvm'].get('pae', 0) + apic = int(dominfo.info['platform'].get('apic', 0)) + pae = int(dominfo.info['platform'].get('pae', 0)) log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d", dominfo.domid, hvm, apic, pae) else: @@ -223,6 +230,15 @@ def restore(xd, fd, dominfo = None, paus handler = RestoreInputHandler() forkHelper(cmd, fd, handler.handler, True) + + # We don't want to pass this fd to any other children -- we + # might need to recover ths disk space that backs it. + try: + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(fd, fcntl.F_SETFD, flags) + except: + pass if handler.store_mfn is None: raise XendError('Could not read store MFN') diff -r 2c087916aaba -r 49ec3725d0c0 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Mar 21 17:03:00 2007 -0500 +++ b/tools/python/xen/xend/XendConfig.py Wed Mar 21 18:08:31 2007 -0500 @@ -12,7 +12,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ -# Copyright (C) 2006 XenSource Ltd +# Copyright (C) 2006-2007 XenSource Ltd #============================================================================ import logging @@ -28,7 +28,7 @@ from xen.xend.XendConstants import DOM_S from xen.xend.XendConstants import DOM_STATE_HALTED log = logging.getLogger("xend.XendConfig") -log.setLevel(logging.DEBUG) +log.setLevel(logging.WARN) """ @@ -105,28 +105,23 @@ XENAPI_CFG_TO_LEGACY_CFG = { 'uuid': 'uuid', 'vcpus_number': 'vcpus', 'cpus': 'cpus', - 'memory_static_min': 'memory', - 'memory_static_max': 'maxmem', 'name_label': 'name', 'actions_after_shutdown': 'on_poweroff', 'actions_after_reboot': 'on_reboot', 'actions_after_crash': 'on_crash', - 'platform_localtime': 'localtime', 'PV_bootloader': 'bootloader', 'PV_bootloader_args': 'bootloader_args', } LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG) -# Mapping from XendConfig configuration keys to the old -# legacy configuration keys that are found in the 'image' -# SXP object. -XENAPI_HVM_CFG = { - 'platform_std_vga': 'stdvga', - 'platform_serial' : 'serial', - 'platform_localtime': 'localtime', - 'platform_keymap' : 'keymap' -} +# Platform configuration keys. +XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'boot', 'device_model', 'display', + 'fda', 'fdb', 'keymap', 'isa', 'localtime', + 'nographic', 'pae', 'serial', 'sdl', + 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', + 'vncconsole', 'vncdisplay', 'vnclisten', + 'vncpasswd', 'vncunused', 'xauthority'] # List of XendConfig configuration keys that have no direct equivalent # in the old world. @@ -139,11 +134,10 @@ XENAPI_CFG_TYPES = { 'user_version': str, 'is_a_template': bool0, 'resident_on': str, - 'memory_static_min': int, + 'memory_static_min': int, # note these are stored in bytes, not KB! 'memory_static_max': int, 'memory_dynamic_min': int, 'memory_dynamic_max': int, - 'memory_actual': int, 'cpus': list, 'vcpus_policy': str, 'vcpus_params': dict, @@ -151,7 +145,6 @@ XENAPI_CFG_TYPES = { 'actions_after_shutdown': str, 'actions_after_reboot': str, 'actions_after_crash': str, - 'tpm_backend': int, 'PV_bootloader': str, 'PV_kernel': str, 'PV_ramdisk': str, @@ -159,15 +152,10 @@ XENAPI_CFG_TYPES = { 'PV_bootloader_args': str, 'HVM_boot_policy': str, 'HVM_boot_params': dict, - 'platform_std_vga': bool0, - 'platform_serial': str, - 'platform_localtime': bool0, - 'platform_clock_offset': bool0, - 'platform_enable_audio': bool0, - 'platform_keymap': str, - 'pci_bus': str, + 'PCI_bus': str, + 'platform': dict, 'tools_version': dict, - 'otherconfig': dict, + 'other_config': dict, } # List of legacy configuration keys that have no equivalent in the @@ -237,44 +225,7 @@ LEGACY_XENSTORE_VM_PARAMS = [ 'on_xend_stop', ] -LEGACY_IMAGE_CFG = [ - ('root', str), - ('ip', str), - ('nographic', int), - ('vnc', int), - ('sdl', int), - ('vncdisplay', int), - ('vncunused', int), - ('vncpasswd', str), - ('vnclisten', str), -] - -LEGACY_IMAGE_HVM_CFG = [ - ('device_model', str), - ('display', str), - ('xauthority', str), - ('vncconsole', int), - ('pae', int), - ('apic', int), -] - -LEGACY_IMAGE_HVM_DEVICES_CFG = [ - ('acpi', int), - ('boot', str), - ('fda', str), - ('fdb', str), - ('isa', int), - ('keymap', str), - ('localtime', int), - ('serial', str), - ('stdvga', int), - ('soundhw', str), - ('usb', int), - ('usbdevice', str), - ('vcpus', int), -] - -LEGACY_DM = '/usr/lib/xen/bin/qemu-dm' +DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm' ## ## Config Choices @@ -316,7 +267,6 @@ class XendConfig(dict): self._sxp_to_xapi_unsupported(sxp_obj) elif xapi: self.update_with_xenapi_config(xapi) - self._add_xapi_unsupported(xapi) elif dominfo: # output from xc.domain_getinfo self._dominfo_to_xapi(dominfo) @@ -361,9 +311,7 @@ class XendConfig(dict): 'shadow_memory': 0, 'memory_static_max': 0, 'memory_dynamic_max': 0, - 'memory_actual': 0, 'devices': {}, - 'image': {}, 'security': None, 'on_xend_start': 'ignore', 'on_xend_stop': 'ignore', @@ -377,24 +325,44 @@ class XendConfig(dict): 'vbd_refs': [], 'vtpm_refs': [], 'other_config': {}, + 'platform': {} } return defaults + # + # Here we assume these values exist in the dict. + # If they don't we have a bigger problem, lets not + # try and 'fix it up' but acutually fix the cause ;-) + # def _memory_sanity_check(self): - if self['memory_static_min'] == 0: - self['memory_static_min'] = self['memory_dynamic_min'] - - # If the static max is not set, let's set it to dynamic max. - # If the static max is smaller than static min, then fix it! - self['memory_static_max'] = max(self['memory_static_max'], - self['memory_dynamic_max'], - self['memory_static_min']) - - for mem_type in ('memory_static_min', 'memory_static_max'): - if self[mem_type] <= 0: - raise XendConfigError('Memory value too low for %s: %d' % - (mem_type, self[mem_type])) + log.debug("_memory_sanity_check memory_static_min: %s, " + "memory_static_max: %i, " + "memory_dynamic_min: %i, " + "memory_dynamic_max: %i", + self["memory_static_min"], + self["memory_static_max"], + self["memory_dynamic_min"], + self["memory_dynamic_max"]) + + if not self["memory_static_min"] <= self["memory_static_max"]: + raise XendConfigError("memory_static_min must be less " \ + "than or equal to memory_static_max") + if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]: + raise XendConfigError("memory_dynamic_min must be less " \ + "than or equal to memory_dynamic_max") + if not self["memory_static_min"] <= self["memory_dynamic_min"]: + raise XendConfigError("memory_static_min must be less " \ + "than or equal to memory_dynamic_min") + if not self["memory_dynamic_max"] <= self["memory_static_max"]: + raise XendConfigError("memory_dynamic_max must be less " \ + "than or equal to memory_static_max") + if not self["memory_dynamic_max"] > 0: + raise XendConfigError("memory_dynamic_max must be greater " \ + "than zero") + if not self["memory_static_max"] > 0: + raise XendConfigError("memory_static_max must be greater " \ + "than zero") def _actions_sanity_check(self): for event in ['shutdown', 'reboot', 'crash']: @@ -417,19 +385,34 @@ class XendConfig(dict): if 'name_label' not in self: self['name_label'] = 'Domain-' + self['uuid'] + def _platform_sanity_check(self): + if self.is_hvm(): + if 'device_model' not in self['platform']: + self['platform']['device_model'] = DEFAULT_DM + + # Compatibility hack, can go away soon. + if 'soundhw' not in self['platform'] and \ + self['platform'].get('enable_audio'): + self['platform']['soundhw'] = 'sb16' + def validate(self): self._uuid_sanity_check() self._name_sanity_check() self._memory_sanity_check() self._actions_sanity_check() self._vcpus_sanity_check() + self._platform_sanity_check() def _dominfo_to_xapi(self, dominfo): self['domid'] = dominfo['domid'] self['online_vcpus'] = dominfo['online_vcpus'] self['vcpus_number'] = dominfo['max_vcpu_id'] + 1 - self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024 - self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024 + + self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024 + self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024 + self['memory_static_min'] = 0 + self['memory_static_max'] = dominfo['maxmem_kb'] * 1024 + self['cpu_time'] = dominfo['cpu_time']/1e9 # TODO: i don't know what the security stuff expects here if dominfo.get('ssidref'): @@ -483,6 +466,13 @@ class XendConfig(dict): log.warn('Ignoring unrecognised value for deprecated option:' 'restart = \'%s\'', restart) + # Handle memory, passed in as MiB + + if sxp.child_value(sxp_cfg, "memory") != None: + cfg["memory"] = int(sxp.child_value(sxp_cfg, "memory")) + if sxp.child_value(sxp_cfg, "maxmem") != None: + cfg["maxmem"] = int(sxp.child_value(sxp_cfg, "maxmem")) + # Only extract options we know about. extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values() @@ -497,6 +487,18 @@ class XendConfig(dict): except (TypeError, ValueError), e: log.warn("Unable to parse key %s: %s: %s" % (key, str(val), e)) + + if 'platform' not in cfg: + cfg['platform'] = {} + localtime = sxp.child_value(sxp_cfg, 'localtime') + if localtime is not None: + cfg['platform']['localtime'] = localtime + + # Compatibility hack -- can go soon. + for key in XENAPI_PLATFORM_CFG: + val = sxp.child_value(sxp_cfg, "platform_" + key, None) + if val is not None: + self['platform'][key] = val # Compatibility hack -- can go soon. boot_order = sxp.child_value(sxp_cfg, 'HVM_boot') @@ -640,6 +642,21 @@ class XendConfig(dict): except KeyError: pass + # Lets try and handle memory correctly + + MiB = 1024 * 1024 + + if "memory" in cfg: + self["memory_static_min"] = 0 + self["memory_static_max"] = int(cfg["memory"]) * MiB + self["memory_dynamic_min"] = int(cfg["memory"]) * MiB + self["memory_dynamic_max"] = int(cfg["memory"]) * MiB + + if "maxmem" in cfg: + self["memory_static_max"] = int(cfg["maxmem"]) * MiB + + self._memory_sanity_check() + def update_with(n, o): if not self.get(n): self[n] = cfg.get(o, '') @@ -652,17 +669,9 @@ class XendConfig(dict): self.update_with_image_sxp(image_sxp) # Convert Legacy HVM parameters to Xen API configuration - self['platform_std_vga'] = bool0(cfg.get('stdvga', 0)) - self['platform_serial'] = str(cfg.get('serial', '')) - self['platform_localtime'] = bool0(cfg.get('localtime', 0)) - self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0)) - - # make sure a sane maximum is set - if self['memory_static_max'] <= 0: - self['memory_static_max'] = self['memory_static_min'] - - self['memory_dynamic_max'] = self['memory_static_max'] - self['memory_dynamic_min'] = self['memory_static_min'] + for key in XENAPI_PLATFORM_CFG: + if key in cfg: + self['platform'][key] = cfg[key] # set device references in the configuration self['devices'] = cfg.get('devices', {}) @@ -672,7 +681,7 @@ class XendConfig(dict): self['vtpm_refs'] = cfg.get('vtpm_refs', []) # coalesce hvm vnc frame buffer with vfb config - if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0): + if self.is_hvm() and self['platform'].get('vnc', 0): # add vfb device if it isn't there already has_rfb = False _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |