Mailing List Archive

merge with xen-unstable.hg
# HG changeset patch
# User awilliam@xenbuild.aw
# Node ID 5d9eb92e63e2203c607c5349ed89bd5d6fd61e0d
# Parent 707737b66f587df491bdc82991c18d816e3d0f2f
# Parent 1e3977e029fddc1e53995a3502d590f8a07e5c62
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile | 2
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c | 767 ------
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h | 40
linux-2.6-xen-sparse/include/xen/tpmfe.h | 40
patches/linux-2.6.16/device_bind.patch | 13
patches/linux-2.6.16/i386-mach-io-check-nmi.patch | 35
patches/linux-2.6.16/net-csum.patch | 58
patches/linux-2.6.16/pmd-shared.patch | 100
patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 27
patches/linux-2.6.16/smp-alts.patch | 540 ----
patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch | 90
patches/linux-2.6.16/xenoprof-generic.patch | 345 --
tools/xenstat/libxenstat/src/xen-interface.c | 201 -
tools/xenstat/libxenstat/src/xen-interface.h | 46
tools/xm-test/lib/XmTestLib/Network.py | 110
.hgignore | 2
buildconfigs/linux-defconfig_xen_x86_32 | 1
buildconfigs/mk.linux-2.6-xen | 3
docs/misc/vtpm.txt | 10
extras/mini-os/Makefile | 8
extras/mini-os/console/console.c | 2
extras/mini-os/events.c | 18
extras/mini-os/hypervisor.c | 2
extras/mini-os/include/lib.h | 1
extras/mini-os/include/mm.h | 2
extras/mini-os/include/os.h | 10
extras/mini-os/include/sched.h | 8
extras/mini-os/include/types.h | 2
extras/mini-os/kernel.c | 26
extras/mini-os/minios-x86_64.lds | 2
extras/mini-os/sched.c | 95
extras/mini-os/traps.c | 10
extras/mini-os/x86_32.S | 61
extras/mini-os/x86_64.S | 530 ++--
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c | 39
linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c | 9
linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c | 2
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c | 26
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 9
linux-2.6-xen-sparse/arch/i386/kernel/vm86.c | 12
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c | 4
linux-2.6-xen-sparse/arch/ia64/Kconfig | 11
linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c | 35
linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre | 22
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c | 25
linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile | 6
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c | 2
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S | 28
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c | 39
linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c | 9
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 30
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 13
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig | 3
linux-2.6-xen-sparse/drivers/char/tpm/Makefile | 2
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c | 546 ++++
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h | 38
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 1247 +++++-----
linux-2.6-xen-sparse/drivers/char/tty_io.c | 8
linux-2.6-xen-sparse/drivers/xen/Kconfig | 14
linux-2.6-xen-sparse/drivers/xen/Makefile | 1
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 47
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 4
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 15
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 13
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 112
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 2
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 47
linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 13
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 9
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 98
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 11
linux-2.6-xen-sparse/drivers/xen/pciback/Makefile | 5
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c | 116
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h | 38
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.c | 71
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.h | 23
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c | 113
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_vpd.c | 42
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c | 60
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c | 49
linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h | 8
linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c | 2
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c | 1
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 16
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 2
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 18
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 83
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c | 1
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 46
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 19
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 2
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h | 28
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h | 10
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h | 3
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h | 14
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h | 13
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h | 7
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h | 28
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 8
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h | 28
linux-2.6-xen-sparse/include/linux/mm.h | 8
linux-2.6-xen-sparse/include/xen/evtchn.h | 6
linux-2.6-xen-sparse/include/xen/public/privcmd.h | 7
linux-2.6-xen-sparse/lib/Makefile | 2
linux-2.6-xen-sparse/mm/Kconfig | 6
linux-2.6-xen-sparse/mm/memory.c | 11
linux-2.6-xen-sparse/mm/page_alloc.c | 33
linux-2.6-xen-sparse/net/core/dev.c | 2
linux-2.6-xen-sparse/scripts/Makefile.xen | 6
patches/linux-2.6.16.13/device_bind.patch | 9
patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch | 30
patches/linux-2.6.16.13/net-csum.patch | 43
patches/linux-2.6.16.13/pmd-shared.patch | 57
patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch | 26
patches/linux-2.6.16.13/smp-alts.patch | 330 ++
patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch | 73
patches/linux-2.6.16.13/xenoprof-generic.patch | 230 +
tools/Rules.mk | 22
tools/debugger/pdb/pdb_caml_process.c | 1
tools/debugger/pdb/pdb_caml_xcs.c | 1
tools/examples/network-bridge | 3
tools/ioemu/configure | 2
tools/ioemu/hw/pc.c | 12
tools/libxc/Makefile | 5
tools/libxc/xc_acm.c | 54
tools/libxc/xc_domain.c | 21
tools/libxc/xc_evtchn.c | 37
tools/libxc/xc_hvm_build.c | 2
tools/libxc/xc_ia64_stubs.c | 4
tools/libxc/xc_linux.c | 114
tools/libxc/xc_linux_build.c | 2
tools/libxc/xc_linux_restore.c | 4
tools/libxc/xc_linux_save.c | 19
tools/libxc/xc_misc.c | 20
tools/libxc/xc_private.c | 98
tools/libxc/xc_private.h | 37
tools/libxc/xc_tbuf.c | 46
tools/libxc/xenctrl.h | 15
tools/libxc/xg_private.h | 2
tools/misc/xend | 24
tools/python/xen/lowlevel/acm/acm.c | 55
tools/python/xen/util/auxbin.py | 19
tools/python/xen/xend/XendBootloader.py | 20
tools/python/xen/xend/XendDomainInfo.py | 31
tools/python/xen/xend/image.py | 6
tools/python/xen/xend/server/SrvDaemon.py | 9
tools/python/xen/xend/server/pciif.py | 2
tools/python/xen/xm/create.py | 31
tools/python/xen/xm/tests/test_create.py | 2
tools/security/secpol_tool.c | 73
tools/xenmon/xenbaked.c | 8
tools/xenstat/libxenstat/Makefile | 14
tools/xenstat/libxenstat/src/xenstat.c | 35
tools/xenstore/xenstored_core.c | 18
tools/xentrace/xentrace.c | 81
tools/xm-test/Writing_Tests_HOWTO | 134 +
tools/xm-test/configure.ac | 34
tools/xm-test/lib/XmTestLib/Console.py | 17
tools/xm-test/lib/XmTestLib/NetConfig.py | 264 ++
tools/xm-test/lib/XmTestLib/Test.py | 3
tools/xm-test/lib/XmTestLib/XenDevice.py | 271 ++
tools/xm-test/lib/XmTestLib/XenDomain.py | 137 +
tools/xm-test/lib/XmTestLib/__init__.py | 29
tools/xm-test/lib/XmTestLib/block_utils.py | 53
tools/xm-test/lib/XmTestLib/config.py.in | 4
tools/xm-test/ramdisk/Makefile.am | 2
tools/xm-test/ramdisk/configs/buildroot | 24
tools/xm-test/tests/_sanity/01_domu_proc.py | 4
tools/xm-test/tests/block-create/01_block_attach_device_pos.py | 19
tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py | 21
tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py | 15
tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py | 26
tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py | 15
tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py | 15
tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py | 26
tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py | 34
tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py | 14
tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py | 24
tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py | 2
tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py | 13
tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py | 31
tools/xm-test/tests/block-list/01_block-list_pos.py | 10
tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py | 19
tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py | 10
tools/xm-test/tests/block-list/04_block-list_nodb_pos.py | 2
tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py | 28
tools/xm-test/tests/create/01_create_basic_pos.py | 18
tools/xm-test/tests/create/04_create_conflictname_neg.py | 4
tools/xm-test/tests/create/06_create_mem_neg.py | 4
tools/xm-test/tests/create/07_create_mem64_pos.py | 2
tools/xm-test/tests/create/08_create_mem128_pos.py | 2
tools/xm-test/tests/create/09_create_mem256_pos.py | 2
tools/xm-test/tests/create/10_create_fastdestroy.py | 2
tools/xm-test/tests/create/11_create_concurrent_pos.py | 4
tools/xm-test/tests/create/12_create_concurrent_stress_pos.py | 9
tools/xm-test/tests/create/13_create_multinic_pos.py | 11
tools/xm-test/tests/create/14_create_blockroot_pos.py | 8
tools/xm-test/tests/create/15_create_smallmem_pos.py | 4
tools/xm-test/tests/create/16_create_smallmem_neg.py | 8
tools/xm-test/tests/destroy/01_destroy_basic_pos.py | 12
tools/xm-test/tests/destroy/05_destroy_byid_pos.py | 5
tools/xm-test/tests/destroy/07_destroy_stale_pos.py | 5
tools/xm-test/tests/list/04_list_goodparm_pos.py | 10
tools/xm-test/tests/memset/01_memset_basic_pos.py | 29
tools/xm-test/tests/memset/03_memset_random_pos.py | 16
tools/xm-test/tests/memset/04_memset_smallmem_pos.py | 4
tools/xm-test/tests/migrate/01_migrate_localhost_pos.py | 17
tools/xm-test/tests/network-attach/01_network_attach_pos.py | 12
tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py | 12
tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py | 15
tools/xm-test/tests/network/02_network_local_ping_pos.py | 39
tools/xm-test/tests/network/03_network_local_tcp_pos.py | 46
tools/xm-test/tests/network/04_network_local_udp_pos.py | 44
tools/xm-test/tests/network/05_network_dom0_ping_pos.py | 51
tools/xm-test/tests/network/06_network_dom0_tcp_pos.py | 52
tools/xm-test/tests/network/07_network_dom0_udp_pos.py | 51
tools/xm-test/tests/network/11_network_domU_ping_pos.py | 58
tools/xm-test/tests/network/12_network_domU_tcp_pos.py | 58
tools/xm-test/tests/network/13_network_domU_udp_pos.py | 58
tools/xm-test/tests/pause/01_pause_basic_pos.py | 17
tools/xm-test/tests/pause/02_pause_badopt_neg.py | 2
tools/xm-test/tests/reboot/01_reboot_basic_pos.py | 13
tools/xm-test/tests/reboot/02_reboot_badopt_neg.py | 2
tools/xm-test/tests/restore/01_restore_basic_pos.py | 10
tools/xm-test/tests/restore/04_restore_withdevices_pos.py | 9
tools/xm-test/tests/save/01_save_basic_pos.py | 10
tools/xm-test/tests/save/03_save_bogusfile_neg.py | 10
tools/xm-test/tests/sedf/01_sedf_period_slice_pos.py | 2
tools/xm-test/tests/sedf/02_sedf_period_lower_neg.py | 2
tools/xm-test/tests/sedf/03_sedf_slice_lower_neg.py | 2
tools/xm-test/tests/sedf/04_sedf_slice_upper_neg.py | 2
tools/xm-test/tests/sedf/05_sedf_extratime_pos.py | 2
tools/xm-test/tests/sedf/06_sedf_extratime_disable_neg.py | 2
tools/xm-test/tests/shutdown/01_shutdown_basic_pos.py | 12
tools/xm-test/tests/shutdown/02_shutdown_badparm_neg.py | 2
tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py | 13
tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py | 8
tools/xm-test/tests/unpause/01_unpause_basic_pos.py | 16
tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py | 2
tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py | 2
tools/xm-test/tests/vtpm/01_vtpm-list_pos.py | 2
tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py | 10
tools/xm-test/tests/vtpm/03_vtpm-susp_res.py | 25
tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py | 20
xen/Makefile | 9
xen/arch/ia64/vmx/vmx_hypercall.c | 4
xen/arch/ia64/vmx/vmx_ivt.S | 2
xen/arch/ia64/xen/dom0_ops.c | 2
xen/arch/ia64/xen/domain.c | 2
xen/arch/ia64/xen/hypercall.c | 181 -
xen/arch/ia64/xen/irq.c | 36
xen/arch/x86/Makefile | 1
xen/arch/x86/compat.c | 32
xen/arch/x86/dom0_ops.c | 2
xen/arch/x86/domain.c | 5
xen/arch/x86/domain_build.c | 2
xen/arch/x86/hvm/svm/svm.c | 92
xen/arch/x86/hvm/svm/vmcb.c | 63
xen/arch/x86/hvm/vmx/io.c | 23
xen/arch/x86/hvm/vmx/vmx.c | 191 -
xen/arch/x86/i387.c | 60
xen/arch/x86/i8259.c | 1
xen/arch/x86/irq.c | 113
xen/arch/x86/mm.c | 28
xen/arch/x86/oprofile/xenoprof.c | 4
xen/arch/x86/physdev.c | 118
xen/arch/x86/setup.c | 16
xen/arch/x86/shutdown.c | 8
xen/arch/x86/smp.c | 8
xen/arch/x86/traps.c | 4
xen/arch/x86/x86_32/entry.S | 12
xen/arch/x86/x86_32/mm.c | 17
xen/arch/x86/x86_32/traps.c | 3
xen/arch/x86/x86_64/entry.S | 12
xen/arch/x86/x86_64/mm.c | 20
xen/arch/x86/x86_64/traps.c | 2
xen/common/acm_ops.c | 4
xen/common/dom0_ops.c | 6
xen/common/domain.c | 2
xen/common/event_channel.c | 153 -
xen/common/grant_table.c | 16
xen/common/kernel.c | 4
xen/common/memory.c | 10
xen/common/multicall.c | 2
xen/common/perfc.c | 34
xen/common/schedule.c | 2
xen/drivers/char/console.c | 6
xen/include/acm/acm_hooks.h | 24
xen/include/asm-ia64/config.h | 3
xen/include/asm-ia64/guest_access.h | 4
xen/include/asm-ia64/hypercall.h | 4
xen/include/asm-x86/config.h | 4
xen/include/asm-x86/guest_access.h | 2
xen/include/asm-x86/hvm/support.h | 3
xen/include/asm-x86/hvm/vmx/vmcs.h | 1
xen/include/asm-x86/hvm/vmx/vmx.h | 1
xen/include/asm-x86/hypercall.h | 24
xen/include/asm-x86/irq.h | 1
xen/include/asm-x86/mm.h | 10
xen/include/asm-x86/uaccess.h | 2
xen/include/public/acm_ops.h | 2
xen/include/public/arch-ia64.h | 34
xen/include/public/arch-x86_32.h | 35
xen/include/public/arch-x86_64.h | 37
xen/include/public/callback.h | 4
xen/include/public/dom0_ops.h | 102
xen/include/public/event_channel.h | 15
xen/include/public/grant_table.h | 12
xen/include/public/memory.h | 16
xen/include/public/nmi.h | 2
xen/include/public/physdev.h | 122
xen/include/public/sched.h | 8
xen/include/public/xen-compat.h | 20
xen/include/public/xen.h | 37
xen/include/public/xenoprof.h | 6
xen/include/xen/compiler.h | 28
xen/include/xen/config.h | 3
xen/include/xen/console.h | 2
xen/include/xen/hypercall.h | 23
xen/include/xen/irq.h | 7
xen/include/xen/lib.h | 3
xen/include/xen/sched.h | 8
322 files changed, 6703 insertions(+), 5827 deletions(-)

diff -r 707737b66f58 -r 5d9eb92e63e2 .hgignore
--- a/.hgignore Mon May 08 13:41:18 2006 -0600
+++ b/.hgignore Mon May 08 14:46:11 2006 -0600
@@ -14,6 +14,7 @@
.*\.orig$
.*\.rej$
.*/a\.out$
+.*/cscope\.*$
^[^/]*\.bz2$
^TAGS$
^dist/.*$
@@ -184,7 +185,6 @@
^tools/xm-test/ramdisk/buildroot
^xen/BLOG$
^xen/TAGS$
-^xen/cscope\.*$
^xen/arch/x86/asm-offsets\.s$
^xen/arch/x86/boot/mkelf32$
^xen/arch/x86/xen\.lds$
diff -r 707737b66f58 -r 5d9eb92e63e2 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32 Mon May 08 13:41:18 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32 Mon May 08 14:46:11 2006 -0600
@@ -1235,6 +1235,7 @@ CONFIG_I2O=m
CONFIG_I2O=m
CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
CONFIG_I2O_CONFIG=m
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=m
diff -r 707737b66f58 -r 5d9eb92e63e2 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen Mon May 08 13:41:18 2006 -0600
+++ b/buildconfigs/mk.linux-2.6-xen Mon May 08 14:46:11 2006 -0600
@@ -1,6 +1,5 @@ LINUX_SERIES = 2.6
LINUX_SERIES = 2.6
-LINUX_VER = 2.6.16
-LINUX_SRCS = linux-2.6.16.tar.bz2
+LINUX_VER = 2.6.16.13

EXTRAVERSION ?= xen

diff -r 707737b66f58 -r 5d9eb92e63e2 docs/misc/vtpm.txt
--- a/docs/misc/vtpm.txt Mon May 08 13:41:18 2006 -0600
+++ b/docs/misc/vtpm.txt Mon May 08 14:46:11 2006 -0600
@@ -21,17 +21,23 @@ linux-2.6.??-xen/.config file:
linux-2.6.??-xen/.config file:

CONFIG_XEN_TPMDEV_BACKEND=y
-CONFIG_XEN_TPMDEV_GRANT=y

-CONFIG_TCG_TPM=m
+CONFIG_TCG_TPM=y
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
+CONFIG_TCG_XEN=y

You must also enable the virtual TPM to be built:

In Config.mk in the Xen root directory set the line

VTPM_TOOLS ?= y
+
+and in
+
+tools/vtpm/Rules.mk set the line
+
+BUILD_EMULATOR = y

Now build the Xen sources from Xen's root directory:

diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/Makefile Mon May 08 14:46:11 2006 -0600
@@ -60,4 +60,12 @@ clean:
%.o: %.S $(HDRS) Makefile
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@

+define all_sources
+ ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
+endef

+.PHONY: cscope
+cscope:
+ $(all_sources) > cscope.files
+ cscope -k -b -q
+
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/console/console.c Mon May 08 14:46:11 2006 -0600
@@ -128,7 +128,7 @@ void printk(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- print(0, fmt, args);
+ print(1, fmt, args);
va_end(args);
}

diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/events.c
--- a/extras/mini-os/events.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/events.c Mon May 08 14:46:11 2006 -0600
@@ -106,6 +106,17 @@ void unbind_virq( u32 port )
unbind_evtchn(port);
}

+#if defined(__x86_64__)
+/* Allocate 4 pages for the irqstack */
+#define STACK_PAGES 4
+char irqstack[1024 * 4 * STACK_PAGES];
+
+static struct pda
+{
+ int irqcount; /* offset 0 (used in x86_64.S) */
+ char *irqstackptr; /* 8 */
+} cpu0_pda;
+#endif

/*
* Initially all events are without a handler and disabled
@@ -113,7 +124,12 @@ void init_events(void)
void init_events(void)
{
int i;
-
+#if defined(__x86_64__)
+ asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
+ wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
+ cpu0_pda.irqcount = -1;
+ cpu0_pda.irqstackptr = irqstack + 1024 * 4 * STACK_PAGES;
+#endif
/* inintialise event handler */
for ( i = 0; i < NR_EVS; i++ )
{
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/hypervisor.c
--- a/extras/mini-os/hypervisor.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/hypervisor.c Mon May 08 14:46:11 2006 -0600
@@ -41,8 +41,8 @@ void do_hypervisor_callback(struct pt_re
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];

+
vcpu_info->evtchn_upcall_pending = 0;
-
/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
while ( l1 != 0 )
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/include/lib.h Mon May 08 14:46:11 2006 -0600
@@ -56,6 +56,7 @@
#define _LIB_H_

#include <stdarg.h>
+#include <stddef.h>
#include <console.h>

/* printing */
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/include/mm.h Mon May 08 14:46:11 2006 -0600
@@ -148,7 +148,7 @@ static __inline__ unsigned long machine_
}

#if defined(__x86_64__)
-#define VIRT_START 0xFFFFFFFF00000000UL
+#define VIRT_START 0xFFFFFFFF80000000UL
#elif defined(__i386__)
#define VIRT_START 0xC0000000UL
#endif
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/include/os.h Mon May 08 14:46:11 2006 -0600
@@ -6,9 +6,6 @@

#ifndef _OS_H_
#define _OS_H_
-
-#define NULL 0
-

#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
@@ -434,6 +431,13 @@ static __inline__ unsigned long __ffs(un
(val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
} while(0)

+#define wrmsr(msr,val1,val2) \
+ __asm__ __volatile__("wrmsr" \
+ : /* no outputs */ \
+ : "c" (msr), "a" (val1), "d" (val2))
+
+#define wrmsrl(msr,val) wrmsr(msr,(u32)((u64)(val)),((u64)(val))>>32)
+

#else /* ifdef __x86_64__ */
#error "Unsupported architecture"
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/include/sched.h
--- a/extras/mini-os/include/sched.h Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/include/sched.h Mon May 08 14:46:11 2006 -0600
@@ -7,8 +7,8 @@ struct thread
{
char *name;
char *stack;
- unsigned long eps;
- unsigned long eip;
+ unsigned long sp; /* Stack pointer */
+ unsigned long ip; /* Instruction pointer */
struct list_head thread_list;
u32 flags;
};
@@ -25,7 +25,9 @@ static inline struct thread* get_current
struct thread **current;
#ifdef __i386__
__asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
-#endif
+#else
+ __asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
+#endif
return *current;
}

diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/include/types.h
--- a/extras/mini-os/include/types.h Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/include/types.h Mon May 08 14:46:11 2006 -0600
@@ -34,8 +34,6 @@ typedef unsigned long u64;
typedef unsigned long u64;
#endif

-typedef unsigned int size_t;
-
/* FreeBSD compat types */
typedef unsigned char u_char;
typedef unsigned int u_int;
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/kernel.c Mon May 08 14:46:11 2006 -0600
@@ -35,6 +35,8 @@
#include <lib.h>
#include <sched.h>
#include <xenbus.h>
+#include <xen/features.h>
+#include <xen/version.h>

/*
* Shared page for communicating with the hypervisor.
@@ -84,6 +86,26 @@ static void init_xs(void *ign)

test_xenbus();
}
+
+
+u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
+
+void setup_xen_features(void)
+{
+ xen_feature_info_t fi;
+ int i, j;
+
+ for (i = 0; i < XENFEAT_NR_SUBMAPS; i++)
+ {
+ fi.submap_idx = i;
+ if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
+ break;
+
+ for (j=0; j<32; j++)
+ xen_features[i*32+j] = !!(fi.submap & 1<<j);
+ }
+}
+

/*
* INITIAL C ENTRY POINT.
@@ -127,7 +149,9 @@ void start_kernel(start_info_t *si)
printk(" flags: 0x%x\n", (unsigned int)si->flags);
printk(" cmd_line: %s\n",
si->cmd_line ? (const char *)si->cmd_line : "NULL");
+ printk(" stack: %p-%p\n", stack, stack + 8192);

+ setup_xen_features();

/* Init memory management. */
init_mm();
@@ -146,7 +170,7 @@ void start_kernel(start_info_t *si)

/* Init XenBus from a separate thread */
create_thread("init_xs", init_xs, NULL);
-
+
/* Everything initialised, start idle thread */
run_idle_thread();
}
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/minios-x86_64.lds Mon May 08 14:46:11 2006 -0600
@@ -3,7 +3,7 @@ ENTRY(_start)
ENTRY(_start)
SECTIONS
{
- . = 0xFFFFFFFF00000000;
+ . = 0xFFFFFFFF80000000;
_text = .; /* Text and read-only data */
.text : {
*(.text)
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/sched.c
--- a/extras/mini-os/sched.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/sched.c Mon May 08 14:46:11 2006 -0600
@@ -69,17 +69,27 @@ void idle_thread_fn(void *unused);

void dump_stack(struct thread *thread)
{
- unsigned long *bottom = (unsigned long *)thread->stack + 2048;
- unsigned long *pointer = (unsigned long *)thread->eps;
+ unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024);
+ unsigned long *pointer = (unsigned long *)thread->sp;
int count;
+ if(thread == current)
+ {
+#ifdef __i386__
+ asm("movl %%esp,%0"
+ : "=r"(pointer));
+#else
+ asm("movq %%rsp,%0"
+ : "=r"(pointer));
+#endif
+ }
printk("The stack for \"%s\"\n", thread->name);
- for(count = 0; count < 15 && pointer < bottom; count ++)
+ for(count = 0; count < 25 && pointer < bottom; count ++)
{
printk("[0x%lx] 0x%lx\n", pointer, *pointer);
pointer++;
}

- if(pointer < bottom) printk("Not the whole stack printed\n");
+ if(pointer < bottom) printk(" ... continues.\n");
}

#ifdef __i386__
@@ -95,13 +105,29 @@ void dump_stack(struct thread *thread)
"1:\t" \
"popl %%ebp\n\t" \
"popfl" \
- :"=m" (prev->eps),"=m" (prev->eip), \
+ :"=m" (prev->sp),"=m" (prev->ip), \
"=S" (esi),"=D" (edi) \
- :"m" (next->eps),"m" (next->eip), \
+ :"m" (next->sp),"m" (next->ip), \
"2" (prev), "d" (next)); \
} while (0)
#elif __x86_64__
-/* FIXME */
+#define switch_threads(prev, next) do { \
+ unsigned long rsi,rdi; \
+ __asm__ __volatile__("pushfq\n\t" \
+ "pushq %%rbp\n\t" \
+ "movq %%rsp,%0\n\t" /* save RSP */ \
+ "movq %4,%%rsp\n\t" /* restore RSP */ \
+ "movq $1f,%1\n\t" /* save RIP */ \
+ "pushq %5\n\t" /* restore RIP */ \
+ "ret\n\t" \
+ "1:\t" \
+ "popq %%rbp\n\t" \
+ "popfq" \
+ :"=m" (prev->sp),"=m" (prev->ip), \
+ "=S" (rsi),"=D" (rdi) \
+ :"m" (next->sp),"m" (next->ip), \
+ "2" (prev), "d" (next)); \
+} while (0)
#endif

void inline print_runqueue(void)
@@ -151,17 +177,19 @@ void schedule(void)
local_irq_restore(flags);
/* Interrupting the switch is equivalent to having the next thread
inturrupted at the return instruction. And therefore at safe point. */
-/* The thread switching only works for i386 at the moment */
-#ifdef __i386__
if(prev != next) switch_threads(prev, next);
-#endif
-}
-
-
-
-void exit_thread(struct thread *thread)
+}
+
+
+/* Gets run when a new thread is scheduled the first time ever,
+ defined in x86_[32/64].S */
+extern void thread_starter(void);
+
+
+void exit_thread(void)
{
unsigned long flags;
+ struct thread *thread = current;
printk("Thread \"%s\" exited.\n", thread->name);
local_irq_save(flags);
/* Remove from the thread list */
@@ -174,6 +202,12 @@ void exit_thread(struct thread *thread)
schedule();
}

+/* Pushes the specified value onto the stack of the specified thread */
+static void stack_push(struct thread *thread, unsigned long value)
+{
+ thread->sp -= sizeof(unsigned long);
+ *((unsigned long *)thread->sp) = value;
+}

struct thread* create_thread(char *name, void (*function)(void *), void *data)
{
@@ -187,23 +221,17 @@ struct thread* create_thread(char *name,
printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
thread->stack);

- thread->eps = (unsigned long)thread->stack + 4096 * 2 - 4;
+ thread->sp = (unsigned long)thread->stack + 4096 * 2;
/* Save pointer to the thread on the stack, used by current macro */
*((unsigned long *)thread->stack) = (unsigned long)thread;
- *((unsigned long *)thread->eps) = (unsigned long)thread;
- thread->eps -= 4;
- *((unsigned long *)thread->eps) = (unsigned long)data;
-
- /* No return address */
- thread->eps -= 4;
- *((unsigned long *)thread->eps) = (unsigned long)exit_thread;
-
- thread->eip = (unsigned long)function;
+
+ stack_push(thread, (unsigned long) function);
+ stack_push(thread, (unsigned long) data);
+ thread->ip = (unsigned long) thread_starter;

/* Not runable, not exited */
thread->flags = 0;
set_runnable(thread);
-
local_irq_save(flags);
if(idle_thread != NULL) {
list_add_tail(&thread->thread_list, &idle_thread->thread_list);
@@ -213,7 +241,6 @@ struct thread* create_thread(char *name,
BUG();
}
local_irq_restore(flags);
-
return thread;
}

@@ -240,11 +267,19 @@ void run_idle_thread(void)
void run_idle_thread(void)
{
/* Switch stacks and run the thread */
+#if defined(__i386__)
__asm__ __volatile__("mov %0,%%esp\n\t"
"push %1\n\t"
"ret"
- :"=m" (idle_thread->eps)
- :"m" (idle_thread->eip));
+ :"=m" (idle_thread->sp)
+ :"m" (idle_thread->ip));
+#elif defined(__x86_64__)
+ __asm__ __volatile__("mov %0,%%rsp\n\t"
+ "push %1\n\t"
+ "ret"
+ :"=m" (idle_thread->sp)
+ :"m" (idle_thread->ip));
+#endif
}


@@ -289,7 +324,7 @@ void th_f2(void *data)

void init_sched(void)
{
- printk("Initialising scheduler, idle_thread %p\n", idle_thread);
+ printk("Initialising scheduler\n");

idle_thread = create_thread("Idle", idle_thread_fn, NULL);
INIT_LIST_HEAD(&idle_thread->thread_list);
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/traps.c
--- a/extras/mini-os/traps.c Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/traps.c Mon May 08 14:46:11 2006 -0600
@@ -123,8 +123,13 @@ void do_page_fault(struct pt_regs *regs,
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
unsigned long addr = read_cr2();
- printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
- error_code);
+#if defined(__x86_64__)
+ printk("Page fault at linear address %p, rip %p, code %lx\n",
+ addr, regs->rip, error_code);
+#else
+ printk("Page fault at linear address %p, eip %p, code %lx\n",
+ addr, regs->eip, error_code);
+#endif
dump_regs(regs);
page_walk(addr);
do_exit();
@@ -195,7 +200,6 @@ static trap_info_t trap_table[] = {
{ 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
{ 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
{ 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
- { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
{ 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
{ 0, 0, 0, 0 }
};
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/x86_32.S Mon May 08 14:46:11 2006 -0600
@@ -30,10 +30,10 @@ hypercall_page:
hypercall_page:
.org 0x3000

-ES = 0x1c
-ORIG_EAX = 0x20
-EIP = 0x24
-CS = 0x28
+ES = 0x20
+ORIG_EAX = 0x24
+EIP = 0x28
+CS = 0x2C

#define ENTRY(X) .globl X ; X :

@@ -69,7 +69,7 @@ ENTRY(divide_error)
pushl $0 # no error code
pushl $do_divide_error
do_exception:
- pushl %ds
+ pushl %ds
pushl %eax
xorl %eax, %eax
pushl %ebp
@@ -92,7 +92,7 @@ do_exception:
pushl %edx
pushl %eax
call *%edi
- addl $8,%esp
+ jmp ret_from_exception

ret_from_exception:
movb CS(%esp),%cl
@@ -223,66 +223,59 @@ ENTRY(invalid_op)
pushl $do_invalid_op
jmp do_exception

+
ENTRY(coprocessor_segment_overrun)
pushl $0
pushl $do_coprocessor_segment_overrun
jmp do_exception
+

ENTRY(invalid_TSS)
pushl $do_invalid_TSS
jmp do_exception

+
ENTRY(segment_not_present)
pushl $do_segment_not_present
jmp do_exception

+
ENTRY(stack_segment)
pushl $do_stack_segment
jmp do_exception

+
ENTRY(general_protection)
pushl $do_general_protection
jmp do_exception

+
ENTRY(alignment_check)
pushl $do_alignment_check
jmp do_exception

-# This handler is special, because it gets an extra value on its stack,
-# which is the linear faulting address.
-# fastcall register usage: %eax = pt_regs, %edx = error code,
-# %ecx = fault address
+
ENTRY(page_fault)
- pushl %ds
- pushl %eax
- xorl %eax, %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- decl %eax /* eax = -1 */
- pushl %ecx
- pushl %ebx
- cld
- movl ORIG_EAX(%esp), %edi
- movl %eax, ORIG_EAX(%esp)
- movl %es, %ecx
- movl %ecx, ES(%esp)
- movl $(__KERNEL_DS),%eax
- movl %eax, %ds
- movl %eax, %es
- pushl %edi
- movl %esp, %eax
- pushl %eax
- call do_page_fault
- jmp ret_from_exception
-
+ pushl $do_page_fault
+ jmp do_exception
+
ENTRY(machine_check)
pushl $0
pushl $do_machine_check
jmp do_exception

+
ENTRY(spurious_interrupt_bug)
pushl $0
pushl $do_spurious_interrupt_bug
jmp do_exception
+
+
+
+ENTRY(thread_starter)
+ popl %eax
+ popl %ebx
+ pushl %eax
+ call *%ebx
+ call exit_thread
+
diff -r 707737b66f58 -r 5d9eb92e63e2 extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S Mon May 08 13:41:18 2006 -0600
+++ b/extras/mini-os/x86_64.S Mon May 08 14:46:11 2006 -0600
@@ -1,4 +1,5 @@
#include <os.h>
+#include <xen/features.h>

.section __xen_guest
.ascii "GUEST_OS=Mini-OS"
@@ -12,40 +13,6 @@
#define ENTRY(X) .globl X ; X :
.globl _start, shared_info, hypercall_page

-#define SAVE_ALL \
- cld; \
- pushq %rdi; \
- pushq %rsi; \
- pushq %rdx; \
- pushq %rcx; \
- pushq %rax; \
- pushq %r8; \
- pushq %r9; \
- pushq %r10; \
- pushq %r11; \
- pushq %rbx; \
- pushq %rbp; \
- pushq %r12; \
- pushq %r13; \
- pushq %r14; \
- pushq %r15;
-
-#define RESTORE_ALL \
- popq %r15; \
- popq %r14; \
- popq %r13; \
- popq %r12; \
- popq %rbp; \
- popq %rbx; \
- popq %r11; \
- popq %r10; \
- popq %r9; \
- popq %r8; \
- popq %rax; \
- popq %rcx; \
- popq %rdx; \
- popq %rsi; \
- popq %rdi

_start:
cld
@@ -65,166 +32,353 @@ hypercall_page:
hypercall_page:
.org 0x3000

+
+/* Offsets into shared_info_t. */
+#define evtchn_upcall_pending /* 0 */
+#define evtchn_upcall_mask 1
+
+NMI_MASK = 0x80000000
+
+#define RDI 112
+#define ORIG_RAX 120 /* + error_code */
+#define EFLAGS 144
+
+#define REST_SKIP 6*8
+.macro SAVE_REST
+ subq $REST_SKIP,%rsp
+# CFI_ADJUST_CFA_OFFSET REST_SKIP
+ movq %rbx,5*8(%rsp)
+# CFI_REL_OFFSET rbx,5*8
+ movq %rbp,4*8(%rsp)
+# CFI_REL_OFFSET rbp,4*8
+ movq %r12,3*8(%rsp)
+# CFI_REL_OFFSET r12,3*8
+ movq %r13,2*8(%rsp)
+# CFI_REL_OFFSET r13,2*8
+ movq %r14,1*8(%rsp)
+# CFI_REL_OFFSET r14,1*8
+ movq %r15,(%rsp)
+# CFI_REL_OFFSET r15,0*8
+.endm
+
+
+.macro RESTORE_REST
+ movq (%rsp),%r15
+# CFI_RESTORE r15
+ movq 1*8(%rsp),%r14
+# CFI_RESTORE r14
+ movq 2*8(%rsp),%r13
+# CFI_RESTORE r13
+ movq 3*8(%rsp),%r12
+# CFI_RESTORE r12
+ movq 4*8(%rsp),%rbp
+# CFI_RESTORE rbp
+ movq 5*8(%rsp),%rbx
+# CFI_RESTORE rbx
+ addq $REST_SKIP,%rsp
+# CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
+.endm
+
+
+#define ARG_SKIP 9*8
+.macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0
+ .if \skipr11
+ .else
+ movq (%rsp),%r11
+# CFI_RESTORE r11
+ .endif
+ .if \skipr8910
+ .else
+ movq 1*8(%rsp),%r10
+# CFI_RESTORE r10
+ movq 2*8(%rsp),%r9
+# CFI_RESTORE r9
+ movq 3*8(%rsp),%r8
+# CFI_RESTORE r8
+ .endif
+ .if \skiprax
+ .else
+ movq 4*8(%rsp),%rax
+# CFI_RESTORE rax
+ .endif
+ .if \skiprcx
+ .else
+ movq 5*8(%rsp),%rcx
+# CFI_RESTORE rcx
+ .endif
+ .if \skiprdx
+ .else
+ movq 6*8(%rsp),%rdx
+# CFI_RESTORE rdx
+ .endif
+ movq 7*8(%rsp),%rsi
+# CFI_RESTORE rsi
+ movq 8*8(%rsp),%rdi
+# CFI_RESTORE rdi
+ .if ARG_SKIP+\addskip > 0
+ addq $ARG_SKIP+\addskip,%rsp
+# CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
+ .endif
+.endm
+
+
+.macro HYPERVISOR_IRET flag
+# testb $3,1*8(%rsp) /* Don't need to do that in Mini-os, as */
+# jnz 2f /* there is no userspace? */
+ testl $NMI_MASK,2*8(%rsp)
+ jnz 2f
+
+ testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
+ jnz 1f
+
+ /* Direct iret to kernel space. Correct CS and SS. */
+ orb $3,1*8(%rsp)
+ orb $3,4*8(%rsp)
+1: iretq
+
+2: /* Slow iret via hypervisor. */
+ andl $~NMI_MASK, 16(%rsp)
+ pushq $\flag
+ jmp hypercall_page + (__HYPERVISOR_iret * 32)
+.endm
+
+/*
+ * Exception entry point. This expects an error code/orig_rax on the stack
+ * and the exception handler in %rax.
+ */
+ENTRY(error_entry)
+# _frame RDI
+ /* rdi slot contains rax, oldrax contains error code */
+ cld
+ subq $14*8,%rsp
+# CFI_ADJUST_CFA_OFFSET (14*8)
+ movq %rsi,13*8(%rsp)
+# CFI_REL_OFFSET rsi,RSI
+ movq 14*8(%rsp),%rsi /* load rax from rdi slot */
+ movq %rdx,12*8(%rsp)
+# CFI_REL_OFFSET rdx,RDX
+ movq %rcx,11*8(%rsp)
+# CFI_REL_OFFSET rcx,RCX
+ movq %rsi,10*8(%rsp) /* store rax */
+# CFI_REL_OFFSET rax,RAX
+ movq %r8, 9*8(%rsp)
+# CFI_REL_OFFSET r8,R8
+ movq %r9, 8*8(%rsp)
+# CFI_REL_OFFSET r9,R9
+ movq %r10,7*8(%rsp)
+# CFI_REL_OFFSET r10,R10
+ movq %r11,6*8(%rsp)
+# CFI_REL_OFFSET r11,R11
+ movq %rbx,5*8(%rsp)
+# CFI_REL_OFFSET rbx,RBX
+ movq %rbp,4*8(%rsp)
+# CFI_REL_OFFSET rbp,RBP
+ movq %r12,3*8(%rsp)
+# CFI_REL_OFFSET r12,R12
+ movq %r13,2*8(%rsp)
+# CFI_REL_OFFSET r13,R13
+ movq %r14,1*8(%rsp)
+# CFI_REL_OFFSET r14,R14
+ movq %r15,(%rsp)
+# CFI_REL_OFFSET r15,R15
+#if 0
+ cmpl $__KERNEL_CS,CS(%rsp)
+ je error_kernelspace
+#endif
+error_call_handler:
+ movq %rdi, RDI(%rsp)
+ movq %rsp,%rdi
+ movq ORIG_RAX(%rsp),%rsi # get error code
+ movq $-1,ORIG_RAX(%rsp)
+ call *%rax
+
+.macro zeroentry sym
+# INTR_FRAME
+ movq (%rsp),%rcx
+ movq 8(%rsp),%r11
+ addq $0x10,%rsp /* skip rcx and r11 */
+ pushq $0 /* push error code/oldrax */
+# CFI_ADJUST_CFA_OFFSET 8
+ pushq %rax /* push real oldrax to the rdi slot */
+# CFI_ADJUST_CFA_OFFSET 8
+ leaq \sym(%rip),%rax
+ jmp error_entry
+# CFI_ENDPROC
+.endm
+
+.macro errorentry sym
+# XCPT_FRAME
+ movq (%rsp),%rcx
+ movq 8(%rsp),%r11
+ addq $0x10,%rsp /* rsp points to the error code */
+ pushq %rax
+# CFI_ADJUST_CFA_OFFSET 8
+ leaq \sym(%rip),%rax
+ jmp error_entry
+# CFI_ENDPROC
+.endm
+
+#define XEN_GET_VCPU_INFO(reg) movq HYPERVISOR_shared_info,reg
+#define XEN_PUT_VCPU_INFO(reg)
+#define XEN_PUT_VCPU_INFO_fixup
+#define XEN_LOCKED_BLOCK_EVENTS(reg) movb $1,evtchn_upcall_mask(reg)
+#define XEN_LOCKED_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg)
+#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
+
+#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
+ XEN_LOCKED_BLOCK_EVENTS(reg) ; \
+ XEN_PUT_VCPU_INFO(reg)
+
+#define XEN_UNBLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
+ XEN_LOCKED_UNBLOCK_EVENTS(reg) ; \
+ XEN_PUT_VCPU_INFO(reg)
+
+
+
ENTRY(hypervisor_callback)
- popq %rcx
- popq %r11
- iretq
+ zeroentry hypervisor_callback2
+
+ENTRY(hypervisor_callback2)
+ movq %rdi, %rsp
+11: movq %gs:8,%rax
+ incl %gs:0
+ cmovzq %rax,%rsp
+ pushq %rdi
+ call do_hypervisor_callback
+ popq %rsp
+ decl %gs:0
+ jmp error_exit
+
+# ALIGN
+restore_all_enable_events:
+ XEN_UNBLOCK_EVENTS(%rsi) # %rsi is already set up...
+
+scrit: /**** START OF CRITICAL REGION ****/
+ XEN_TEST_PENDING(%rsi)
+ jnz 14f # process more events if necessary...
+ XEN_PUT_VCPU_INFO(%rsi)
+ RESTORE_ARGS 0,8,0
+ HYPERVISOR_IRET 0
+
+14: XEN_LOCKED_BLOCK_EVENTS(%rsi)
+ XEN_PUT_VCPU_INFO(%rsi)
+ SAVE_REST
+ movq %rsp,%rdi # set the argument again
+ jmp 11b
+ecrit: /**** END OF CRITICAL REGION ****/
+
+
+retint_kernel:
+retint_restore_args:
+ movl EFLAGS-REST_SKIP(%rsp), %eax
+ shr $9, %eax # EAX[0] == IRET_EFLAGS.IF
+ XEN_GET_VCPU_INFO(%rsi)
+ andb evtchn_upcall_mask(%rsi),%al
+ andb $1,%al # EAX[0] == IRET_EFLAGS.IF & event_mask
+ jnz restore_all_enable_events # != 0 => enable event delivery
+ XEN_PUT_VCPU_INFO(%rsi)
+
+ RESTORE_ARGS 0,8,0
+ HYPERVISOR_IRET 0
+
+
+error_exit:
+ RESTORE_REST
+/* cli */
+ XEN_BLOCK_EVENTS(%rsi)
+ jmp retint_kernel
+
+

ENTRY(failsafe_callback)
popq %rcx
popq %r11
iretq

-error_code:
- SAVE_ALL
- movq %rsp,%rdi
- movl 15*8+4(%rsp),%eax
- leaq exception_table(%rip),%rdx
- callq *(%rdx,%rax,8)
- RESTORE_ALL
- addq $8,%rsp
- iretq
-
+
+ENTRY(coprocessor_error)
+ zeroentry do_coprocessor_error
+
+
+ENTRY(simd_coprocessor_error)
+ zeroentry do_simd_coprocessor_error
+
+
+ENTRY(device_not_available)
+ zeroentry do_device_not_available
+
+
+ENTRY(debug)
+# INTR_FRAME
+# CFI_ADJUST_CFA_OFFSET 8 */
+ zeroentry do_debug
+# CFI_ENDPROC
+
+
+ENTRY(int3)
+# INTR_FRAME
+# CFI_ADJUST_CFA_OFFSET 8 */
+ zeroentry do_int3
+# CFI_ENDPROC
+
+ENTRY(overflow)
+ zeroentry do_overflow
+
+
+ENTRY(bounds)
+ zeroentry do_bounds
+
+
+ENTRY(invalid_op)
+ zeroentry do_invalid_op
+
+
+ENTRY(coprocessor_segment_overrun)
+ zeroentry do_coprocessor_segment_overrun
+
+
+ENTRY(invalid_TSS)
+ errorentry do_invalid_TSS
+
+
+ENTRY(segment_not_present)
+ errorentry do_segment_not_present
+
+
+/* runs on exception stack */
+ENTRY(stack_segment)
+# XCPT_FRAME
+ errorentry do_stack_segment
+# CFI_ENDPROC
+
+
+ENTRY(general_protection)
+ errorentry do_general_protection
+
+
+ENTRY(alignment_check)
+ errorentry do_alignment_check
+
+
ENTRY(divide_error)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_divide_error,4(%rsp)
- jmp error_code
+ zeroentry do_divide_error
+
+
+ENTRY(spurious_interrupt_bug)
+ zeroentry do_spurious_interrupt_bug
+
+
+ENTRY(page_fault)
+ errorentry do_page_fault
+
+
+
+
+
+ENTRY(thread_starter)
+ popq %rdi
+ popq %rbx
+ call *%rbx
+ call exit_thread

-ENTRY(coprocessor_error)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_copro_error,4(%rsp)
- jmp error_code
-
-ENTRY(simd_coprocessor_error)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_simd_error,4(%rsp)
- jmp error_code
-
-ENTRY(device_not_available)
- popq %rcx
- popq %r11
- movl $TRAP_no_device,4(%rsp)
- jmp error_code
-
-ENTRY(debug)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_debug,4(%rsp)
- jmp error_code
-
-ENTRY(int3)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_int3,4(%rsp)
- jmp error_code
-
-ENTRY(overflow)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_overflow,4(%rsp)
- jmp error_code
-
-ENTRY(bounds)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_bounds,4(%rsp)
- jmp error_code
-
-ENTRY(invalid_op)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_invalid_op,4(%rsp)
- jmp error_code
-
-ENTRY(coprocessor_segment_overrun)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_copro_seg,4(%rsp)
- jmp error_code
-
-ENTRY(invalid_TSS)
- popq %rcx
- popq %r11
- movl $TRAP_invalid_tss,4(%rsp)
- jmp error_code
-
-ENTRY(segment_not_present)
- popq %rcx
- popq %r11
- movl $TRAP_no_segment,4(%rsp)
- jmp error_code
-
-ENTRY(stack_segment)
- popq %rcx
- popq %r11
- movl $TRAP_stack_error,4(%rsp)
- jmp error_code
-
-ENTRY(general_protection)
- popq %rcx
- popq %r11
- movl $TRAP_gp_fault,4(%rsp)
- jmp error_code
-
-ENTRY(alignment_check)
- popq %rcx
- popq %r11
- movl $TRAP_alignment_check,4(%rsp)
- jmp error_code
-
-ENTRY(virt_cr2)
- .quad 0
-ENTRY(page_fault)
- popq %rcx
- popq %r11
- popq virt_cr2(%rip)
- movl $TRAP_page_fault,4(%rsp)
- jmp error_code
-
-ENTRY(machine_check)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_machine_check,4(%rsp)
- jmp error_code
-
-ENTRY(spurious_interrupt_bug)
- popq %rcx
- popq %r11
- pushq $0
- movl $TRAP_spurious_int,4(%rsp)
- jmp error_code
-
-ENTRY(exception_table)
- .quad do_divide_error
- .quad do_debug
- .quad 0 # nmi
- .quad do_int3
- .quad do_overflow
- .quad do_bounds
- .quad do_invalid_op
- .quad 0
- .quad 0
- .quad do_coprocessor_segment_overrun
- .quad do_invalid_TSS
- .quad do_segment_not_present
- .quad do_stack_segment
- .quad do_general_protection
- .quad do_page_fault
- .quad do_spurious_interrupt_bug
- .quad do_coprocessor_error
- .quad do_alignment_check
- .quad do_machine_check
- .quad do_simd_coprocessor_error
+
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Mon May 08 14:46:11 2006 -0600
@@ -57,27 +57,25 @@ unsigned long io_apic_irqs;

static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;

- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}

static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
- physdev_op_t op;
-
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = value;
- HYPERVISOR_physdev_op(&op);
+ struct physdev_apic apic_op;
+
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}

#define io_apic_read(a,r) xen_io_apic_read(a,r)
@@ -1205,22 +1203,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos

int assign_irq_vector(int irq)
{
- physdev_op_t op;
+ struct physdev_irq irq_op;

BUG_ON(irq >= NR_IRQ_VECTORS);
if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
return IO_APIC_VECTOR(irq);

- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;

- vector_irq[op.u.irq_op.vector] = irq;
+ vector_irq[irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
-
- return op.u.irq_op.vector;
+ IO_APIC_VECTOR(irq) = irq_op.vector;
+
+ return irq_op.vector;
}

#ifndef CONFIG_XEN
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c Mon May 08 14:46:11 2006 -0600
@@ -60,7 +60,7 @@ asmlinkage long sys_ioperm(unsigned long
{
struct thread_struct * t = &current->thread;
unsigned long *bitmap;
- physdev_op_t op;
+ struct physdev_set_iobitmap set_iobitmap;

if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
@@ -80,10 +80,9 @@ asmlinkage long sys_ioperm(unsigned long
memset(bitmap, 0xff, IO_BITMAP_BYTES);
t->io_bitmap_ptr = bitmap;

- op.cmd = PHYSDEVOP_SET_IOBITMAP;
- op.u.set_iobitmap.bitmap = (char *)bitmap;
- op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS;
- HYPERVISOR_physdev_op(&op);
+ set_iobitmap.bitmap = (char *)bitmap;
+ set_iobitmap.nr_ports = IO_BITMAP_BITS;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
}

set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c Mon May 08 14:46:11 2006 -0600
@@ -70,7 +70,7 @@ static int do_microcode_update (void)
return err;

op.cmd = DOM0_MICROCODE;
- op.u.microcode.data = user_buffer;
+ set_xen_guest_handle(op.u.microcode.data, user_buffer);
op.u.microcode.length = user_buffer_size;
err = HYPERVISOR_dom0_op(&op);

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Mon May 08 14:46:11 2006 -0600
@@ -297,9 +297,8 @@ void exit_thread(void)

/* The process may have allocated an io port bitmap... nuke it. */
if (unlikely(NULL != t->io_bitmap_ptr)) {
- physdev_op_t op = { 0 };
- op.cmd = PHYSDEVOP_SET_IOBITMAP;
- HYPERVISOR_physdev_op(&op);
+ struct physdev_set_iobitmap set_iobitmap = { 0 };
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
kfree(t->io_bitmap_ptr);
t->io_bitmap_ptr = NULL;
}
@@ -521,7 +520,8 @@ struct task_struct fastcall * __switch_t
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
- physdev_op_t iopl_op, iobmp_op;
+ struct physdev_set_iopl iopl_op;
+ struct physdev_set_iobitmap iobmp_op;
multicall_entry_t _mcl[8], *mcl = _mcl;

/* XEN NOTE: FS/GS saved in switch_mm(), not here. */
@@ -568,23 +568,19 @@ struct task_struct fastcall * __switch_t
#undef C

if (unlikely(prev->iopl != next->iopl)) {
- iopl_op.cmd = PHYSDEVOP_SET_IOPL;
- iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 :
- (next->iopl >> 12) & 3;
+ iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iopl_op;
+ mcl->args[0] = PHYSDEVOP_set_iopl;
+ mcl->args[1] = (unsigned long)&iopl_op;
mcl++;
}

if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
- iobmp_op.cmd =
- PHYSDEVOP_SET_IOBITMAP;
- iobmp_op.u.set_iobitmap.bitmap =
- (char *)next->io_bitmap_ptr;
- iobmp_op.u.set_iobitmap.nr_ports =
- next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+ 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] = (unsigned long)&iobmp_op;
+ mcl->args[0] = PHYSDEVOP_set_iobitmap;
+ mcl->args[1] = (unsigned long)&iobmp_op;
mcl++;
}

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 08 14:46:11 2006 -0600
@@ -1368,7 +1368,7 @@ legacy_init_iomem_resources(struct resou
#ifdef CONFIG_XEN
map = alloc_bootmem_low_pages(PAGE_SIZE);
op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
- op.u.physical_memory_map.memory_map = map;
+ set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
op.u.physical_memory_map.max_map_entries =
PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
BUG_ON(HYPERVISOR_dom0_op(&op));
@@ -1630,7 +1630,7 @@ void __init setup_arch(char **cmdline_p)
void __init setup_arch(char **cmdline_p)
{
int i, j, k, fpp;
- physdev_op_t op;
+ struct physdev_set_iopl set_iopl;
unsigned long max_low_pfn;

/* Force a quick death if the kernel panics (not domain 0). */
@@ -1815,9 +1815,8 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled)
efi_map_memmap();

- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = 1;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = 1;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);

#ifdef CONFIG_X86_IO_APIC
check_acpi_pci(); /* Checks more than just ACPI actually */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/kernel/vm86.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Mon May 08 14:46:11 2006 -0600
@@ -43,6 +43,7 @@
#include <linux/smp_lock.h>
#include <linux/highmem.h>
#include <linux/ptrace.h>
+#include <linux/audit.h>

#include <asm/uaccess.h>
#include <asm/io.h>
@@ -258,6 +259,7 @@ static void do_sys_vm86(struct kernel_vm
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss;
#endif
+ long eax;
/*
* make sure the vm86() system call doesn't try to do anything silly
*/
@@ -313,13 +315,19 @@ static void do_sys_vm86(struct kernel_vm
tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP)
mark_screen_rdonly(tsk->mm);
+ __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t");
+ __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax));
+
+ /*call audit_syscall_exit since we do not exit via the normal paths */
+ if (unlikely(current->audit_context))
+ audit_syscall_exit(current, AUDITSC_RESULT(eax), eax);
+
__asm__ __volatile__(
- "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
"movl %0,%%esp\n\t"
"movl %1,%%ebp\n\t"
"jmp resume_userspace"
: /* no outputs */
- :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax");
+ :"r" (&info->regs), "r" (task_thread_info(tsk)));
/* we never return here */
}

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon May 08 14:46:11 2006 -0600
@@ -271,11 +271,11 @@ int xen_create_contiguous_region(
pte_t *pte;
unsigned long frame, i, flags;
struct xen_memory_reservation reservation = {
- .extent_start = &frame,
.nr_extents = 1,
.extent_order = 0,
.domid = DOMID_SELF
};
+ set_xen_guest_handle(reservation.extent_start, &frame);

/*
* Currently an auto-translated guest will not perform I/O, nor will
@@ -357,11 +357,11 @@ void xen_destroy_contiguous_region(unsig
pte_t *pte;
unsigned long frame, i, flags;
struct xen_memory_reservation reservation = {
- .extent_start = &frame,
.nr_extents = 1,
.extent_order = 0,
.domid = DOMID_SELF
};
+ set_xen_guest_handle(reservation.extent_start, &frame);

if (xen_feature(XENFEAT_auto_translated_physmap))
return;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Mon May 08 14:46:11 2006 -0600
@@ -90,11 +90,18 @@ config XEN_BLKDEV_BACKEND
default y

config XEN_IA64_DOM0_VP
+ bool "dom0 vp model"
depends on XEN
- bool
default n
help
dom0 vp model
+
+config XEN_IA64_DOM0_NON_VP
+ bool
+ depends on !(XEN && XEN_IA64_DOM0_VP)
+ default y
+ help
+ dom0 P=M model

config XEN_SYSFS
bool "Export Xen attributes in sysfs"
@@ -106,7 +113,7 @@ config XEN_INTERFACE_VERSION
config XEN_INTERFACE_VERSION
hex
depends on XEN
- default 0x00030101
+ default 0x00030202

config SCHED_NO_NO_OMIT_FRAME_POINTER
bool
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c Mon May 08 14:46:11 2006 -0600
@@ -146,29 +146,27 @@ static LIST_HEAD(free_rte_list);
#include <asm/hypervisor.h>
static inline unsigned int xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;

- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = (unsigned long)iosapic -
+ apic_op.apic_physbase = (unsigned long)iosapic -
__IA64_UNCACHED_OFFSET;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}

static inline void xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{
- physdev_op_t op;
-
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = (unsigned long)iosapic -
+ struct physdev_apic apic_op;
+
+ apic_op.apic_physbase = (unsigned long)iosapic -
__IA64_UNCACHED_OFFSET;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = val;
- HYPERVISOR_physdev_op(&op);
+ apic_op.reg = reg;
+ apic_op.value = val;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}

static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
@@ -191,14 +189,13 @@ static inline void iosapic_write(char __

int xen_assign_irq_vector(int irq)
{
- physdev_op_t op;
-
- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ struct physdev_irq irq_op;
+
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;

- return op.u.irq_op.vector;
+ return irq_op.vector;
}
#endif /* XEN */

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre
--- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre Mon May 08 14:46:11 2006 -0600
@@ -14,28 +14,12 @@ function try_to_mv() {
fi
}

-function try_to_mkdir() {
- if [ ! -e $2 ]
- then
- mv $1 $2
- mkdir $1
- fi
-}
-
-try_to_mkdir mm mm.xen-x86
-try_to_mv net net.xen-x86
-try_to_mv kernel kernel.xen-x86
-try_to_mv drivers/acpi/tables.c drivers/acpi/tables.c.xen-x86
-#try_to_mv arch/xen/kernel drivers/xen/core
-#try_to_mkdir arch/xen arch/xen.xen-x86
-#try_to_mv arch/xen.xen-x86/configs arch/xen
-#try_to_mv include/asm-generic include/asm-generic.xen-x86
-try_to_mkdir include/linux include/linux.xen-x86
+try_to_mv mm/Kconfig mm/Kconfig.xen-x86

# need to grab a couple of xen-modified files for generic_page_range and
# typedef pte_fn_t which are used by driver/xen blkif
-ln -sf ../mm.xen-x86/memory.c mm/
-ln -sf ../linux.xen-x86/mm.h include/linux/
+#ln -sf ../mm.xen-x86/memory.c mm/
+#ln -sf ../linux.xen-x86/mm.h include/linux/

#eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h
ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Mon May 08 14:46:11 2006 -0600
@@ -61,9 +61,8 @@ void unmask_evtchn(int port)
#if 0 // FIXME: diverged from x86 evtchn.c
/* Slow path (hypercall) if this is a non-local port. */
if (unlikely(cpu != cpu_from_evtchn(port))) {
- evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
- .u.unmask.port = port };
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_unmask op = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &op);
return;
}
#endif
@@ -95,16 +94,16 @@ int bind_virq_to_irqhandler(
const char *devname,
void *dev_id)
{
- evtchn_op_t op;
+ struct evtchn_bind_virq bind_virq;
int evtchn;

spin_lock(&irq_mapping_update_lock);

- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;

if (!unbound_irq(evtchn)) {
evtchn = -EINVAL;
@@ -158,7 +157,7 @@ int bind_ipi_to_irqhandler(

void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
- evtchn_op_t op;
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);

spin_lock(&irq_mapping_update_lock);
@@ -166,9 +165,9 @@ void unbind_from_irqhandler(unsigned int
if (unbound_irq(irq))
goto out;

- op.cmd = EVTCHNOP_close;
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();

switch (type_from_irq(irq)) {
case IRQT_VIRQ:
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile
--- a/linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile Mon May 08 14:46:11 2006 -0600
@@ -28,11 +28,11 @@ quiet_cmd_syscall = SYSCALL $@
$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)

-AFLAGS_vsyscall-sysenter.o = -m32 -Iarch/i386/kernel
-AFLAGS_vsyscall-syscall.o = -m32 -Iarch/i386/kernel
+AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
+AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel

ifdef CONFIG_XEN
-AFLAGS_vsyscall-int80.o = -m32 -Iarch/i386/kernel
+AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
CFLAGS_syscall32-xen.o += -DUSE_INT80
AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon May 08 14:46:11 2006 -0600
@@ -600,7 +600,7 @@ void __init e820_reserve_resources(void)

map = alloc_bootmem_low_pages(PAGE_SIZE);
op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
- op.u.physical_memory_map.memory_map = map;
+ set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
op.u.physical_memory_map.max_map_entries =
PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
BUG_ON(HYPERVISOR_dom0_op(&op));
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Mon May 08 14:46:11 2006 -0600
@@ -221,6 +221,10 @@ rff_trace:
*
* XXX if we had a free scratch register we could save the RSP into the stack frame
* and report it properly in ps. Unfortunately we haven't.
+ *
+ * When user can change the frames always force IRET. That is because
+ * it deals with uncanonical addresses better. SYSRET has trouble
+ * with them due to bugs in both AMD and Intel CPUs.
*/

ENTRY(system_call)
@@ -289,7 +293,10 @@ sysret_signal:
xorl %esi,%esi # oldset -> arg2
call ptregscall_common
1: movl $_TIF_NEED_RESCHED,%edi
- jmp sysret_check
+ /* Use IRET because user could have changed frame. This
+ works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
+ cli
+ jmp int_with_check

badsys:
movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
@@ -315,7 +322,8 @@ 1: SAVE_REST
call syscall_trace_leave
RESTORE_TOP_OF_STACK %rbx
RESTORE_REST
- jmp ret_from_sys_call
+ /* Use IRET because user could have changed frame */
+ jmp int_ret_from_sys_call
CFI_ENDPROC

/*
@@ -449,25 +457,9 @@ ENTRY(stub_execve)
CFI_ADJUST_CFA_OFFSET -8
CFI_REGISTER rip, r11
SAVE_REST
- movq %r11, %r15
- CFI_REGISTER rip, r15
FIXUP_TOP_OF_STACK %r11
call sys_execve
- GET_THREAD_INFO(%rcx)
- bt $TIF_IA32,threadinfo_flags(%rcx)
- CFI_REMEMBER_STATE
- jc exec_32bit
RESTORE_TOP_OF_STACK %r11
- movq %r15, %r11
- CFI_REGISTER rip, r11
- RESTORE_REST
- pushq %r11
- CFI_ADJUST_CFA_OFFSET 8
- CFI_REL_OFFSET rip, 0
- ret
-
-exec_32bit:
- CFI_RESTORE_STATE
movq %rax,RAX(%rsp)
RESTORE_REST
jmp int_ret_from_sys_call
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Mon May 08 14:46:11 2006 -0600
@@ -104,27 +104,25 @@ unsigned long io_apic_irqs;

static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
{
- physdev_op_t op;
+ struct physdev_apic apic_op;
int ret;

- op.cmd = PHYSDEVOP_APIC_READ;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- ret = HYPERVISOR_physdev_op(&op);
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
if (ret)
return ret;
- return op.u.apic_op.value;
+ return apic_op.value;
}

static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
- physdev_op_t op;
-
- op.cmd = PHYSDEVOP_APIC_WRITE;
- op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
- op.u.apic_op.reg = reg;
- op.u.apic_op.value = value;
- HYPERVISOR_physdev_op(&op);
+ struct physdev_apic apic_op;
+
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}

#define io_apic_read(a,r) xen_io_apic_read(a,r)
@@ -869,22 +867,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos

int assign_irq_vector(int irq)
{
- physdev_op_t op;
+ struct physdev_irq irq_op;

BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
return IO_APIC_VECTOR(irq);

- op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
- op.u.irq_op.irq = irq;
- if (HYPERVISOR_physdev_op(&op))
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;

- vector_irq[op.u.irq_op.vector] = irq;
+ vector_irq[irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
-
- return op.u.irq_op.vector;
+ IO_APIC_VECTOR(irq) = irq_op.vector;
+
+ return irq_op.vector;
}

extern void (*interrupt[NR_IRQS])(void);
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c Mon May 08 14:46:11 2006 -0600
@@ -28,8 +28,8 @@

asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
{
- unsigned int old_iopl = current->thread.iopl;
- physdev_op_t op;
+ unsigned int old_iopl = current->thread.iopl;
+ struct physdev_set_iopl set_iopl;

if (new_iopl > 3)
return -EINVAL;
@@ -42,9 +42,8 @@ asmlinkage long sys_iopl(unsigned int ne
current->thread.iopl = new_iopl;

/* Force the change at ring 0. */
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);

return 0;
}
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Mon May 08 14:46:11 2006 -0600
@@ -293,9 +293,7 @@ void exit_thread(void)
struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
#endif
#ifdef CONFIG_XEN
- static physdev_op_t iobmp_op = {
- .cmd = PHYSDEVOP_SET_IOBITMAP
- };
+ struct physdev_set_iobitmap iobmp_op = { 0 };
#endif

kfree(t->io_bitmap_ptr);
@@ -308,7 +306,7 @@ void exit_thread(void)
put_cpu();
#endif
#ifdef CONFIG_XEN
- HYPERVISOR_physdev_op(&iobmp_op);
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
#endif
t->io_bitmap_max = 0;
}
@@ -478,13 +476,18 @@ __switch_to(struct task_struct *prev_p,
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
- physdev_op_t iopl_op, iobmp_op;
+ struct physdev_set_iopl iopl_op;
+ struct physdev_set_iobitmap iobmp_op;
multicall_entry_t _mcl[8], *mcl = _mcl;

/*
* This is basically '__unlazy_fpu', except that we queue a
* multicall to indicate FPU task switch, rather than
* synchronously trapping to Xen.
+ * This must be here to ensure both math_state_restore() and
+ * kernel_fpu_begin() work consistently.
+ * The AMD workaround requires it to be after DS reload, or
+ * after DS has been cleared, which we do in __prepare_arch_switch.
*/
if (prev_p->thread_info->status & TS_USEDFPU) {
__save_init_fpu(prev_p); /* _not_ save_init_fpu() */
@@ -518,22 +521,19 @@ __switch_to(struct task_struct *prev_p,
#undef C

if (unlikely(prev->iopl != next->iopl)) {
- iopl_op.cmd = PHYSDEVOP_SET_IOPL;
- iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 : next->iopl;
+ iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
mcl->op = __HYPERVISOR_physdev_op;
- mcl->args[0] = (unsigned long)&iopl_op;
+ mcl->args[0] = PHYSDEVOP_set_iopl;
+ mcl->args[1] = (unsigned long)&iopl_op;
mcl++;
}

if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
- iobmp_op.cmd =
- PHYSDEVOP_SET_IOBITMAP;
- iobmp_op.u.set_iobitmap.bitmap =
- (char *)next->io_bitmap_ptr;
- iobmp_op.u.set_iobitmap.nr_ports =
- next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+ 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] = (unsigned long)&iobmp_op;
+ mcl->args[0] = PHYSDEVOP_set_iobitmap;
+ mcl->args[1] = (unsigned long)&iobmp_op;
mcl++;
}

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon May 08 14:46:11 2006 -0600
@@ -959,11 +959,10 @@ void __init setup_arch(char **cmdline_p)

#ifdef CONFIG_XEN
{
- physdev_op_t op;
-
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = 1;
- HYPERVISOR_physdev_op(&op);
+ struct physdev_set_iopl set_iopl;
+
+ set_iopl.iopl = 1;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);

if (xen_start_info->flags & SIF_INITDOMAIN) {
if (!(xen_start_info->flags & SIF_PRIVILEGED))
@@ -1158,6 +1157,10 @@ static int __init init_amd(struct cpuinf
if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);

+ /* Enable workaround for FXSAVE leak */
+ if (c->x86 >= 6)
+ set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
+
r = get_model_name(c);
if (!r) {
switch (c->x86) {
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Mon May 08 14:46:11 2006 -0600
@@ -51,7 +51,7 @@ config TCG_INFINEON

config TCG_XEN
tristate "XEN TPM Interface"
- depends on TCG_TPM && XEN && XEN_TPMDEV_FRONTEND
+ depends on TCG_TPM && XEN
---help---
If you want to make TPM support available to a Xen
user domain, say Yes and it will
@@ -60,4 +60,3 @@ config TCG_XEN
tpm_xen.

endmenu
-
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile Mon May 08 14:46:11 2006 -0600
@@ -8,4 +8,4 @@ obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
-obj-$(CONFIG_TCG_XEN) += tpm_xen.o
+obj-$(CONFIG_TCG_XEN) += tpm_xen.o tpm_vtpm.o
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Mon May 08 14:46:11 2006 -0600
@@ -1,536 +1,767 @@
/*
- * Copyright (C) 2004 IBM Corporation
+ * Copyright (c) 2005, IBM Corporation
*
- * Authors:
- * Leendert van Doorn <leendert@watson.ibm.com>
- * Dave Safford <safford@watson.ibm.com>
- * Reiner Sailer <sailer@watson.ibm.com>
- * Kylene Hall <kjhall@us.ibm.com>
- * Stefan Berger <stefanb@us.ibm.com>
+ * Author: Stefan Berger, stefanb@us.ibm.com
+ * Grant table support: Mahadevan Gomathisankaran
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * This code has been derived from drivers/xen/netfront/netfront.c
*
- * Device driver for TCG/TCPA TPM (trusted platform module) for XEN.
- * Specifications at www.trustedcomputinggroup.org
+ * Copyright (c) 2002-2004, K A Fraser
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
*/

+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
-#include <linux/list.h>
-#include <xen/tpmfe.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include "tpm.h"
-
-/* read status bits */
-enum {
- STATUS_BUSY = 0x01,
- STATUS_DATA_AVAIL = 0x02,
- STATUS_READY = 0x04
+#include <xen/evtchn.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/io/tpmif.h>
+#include <xen/xenbus.h>
+#include "tpm_vtpm.h"
+
+#undef DEBUG
+
+/* local structures */
+struct tpm_private {
+ tpmif_tx_interface_t *tx;
+ atomic_t refcnt;
+ unsigned int evtchn;
+ unsigned int irq;
+ u8 is_connected;
+ u8 is_suspended;
+
+ spinlock_t tx_lock;
+
+ struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
+
+ atomic_t tx_busy;
+ void *tx_remember;
+ domid_t backend_id;
+ wait_queue_head_t wait_q;
+
+ struct xenbus_device *dev;
+ int ring_ref;
};

-#define MIN(x,y) ((x) < (y)) ? (x) : (y)
-
-struct transmission {
- struct list_head next;
- unsigned char *request;
- unsigned int request_len;
- unsigned char *rcv_buffer;
- unsigned int buffersize;
- unsigned int flags;
+struct tx_buffer {
+ unsigned int size; // available space in data
+ unsigned int len; // used space in data
+ unsigned char *data; // pointer to a page
};

-enum {
- TRANSMISSION_FLAG_WAS_QUEUED = 0x1
+
+/* locally visible variables */
+static grant_ref_t gref_head;
+static struct tpm_private *my_priv;
+
+/* local function prototypes */
+static irqreturn_t tpmif_int(int irq,
+ void *tpm_priv,
+ struct pt_regs *ptregs);
+static void tpmif_rx_action(unsigned long unused);
+static int tpmif_connect(struct xenbus_device *dev,
+ struct tpm_private *tp,
+ domid_t domid);
+static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
+static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
+static void tpmif_free_tx_buffers(struct tpm_private *tp);
+static void tpmif_set_connected_state(struct tpm_private *tp,
+ u8 newstate);
+static int tpm_xmit(struct tpm_private *tp,
+ const u8 * buf, size_t count, int userbuffer,
+ void *remember);
+static void destroy_tpmring(struct tpm_private *tp);
+
+#define DPRINTK(fmt, args...) \
+ pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
+#define IPRINTK(fmt, args...) \
+ printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+ printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
+
+#define GRANT_INVALID_REF 0
+
+
+static inline int
+tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
+ int isuserbuffer)
+{
+ int copied = len;
+
+ if (len > txb->size) {
+ copied = txb->size;
+ }
+ if (isuserbuffer) {
+ if (copy_from_user(txb->data, src, copied))
+ return -EFAULT;
+ } else {
+ memcpy(txb->data, src, copied);
+ }
+ txb->len = len;
+ return copied;
+}
+
+static inline struct tx_buffer *tx_buffer_alloc(void)
+{
+ struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
+ GFP_KERNEL);
+
+ if (txb) {
+ txb->len = 0;
+ txb->size = PAGE_SIZE;
+ txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
+ if (txb->data == NULL) {
+ kfree(txb);
+ txb = NULL;
+ }
+ }
+ return txb;
+}
+
+
+static inline void tx_buffer_free(struct tx_buffer *txb)
+{
+ if (txb) {
+ free_page((long)txb->data);
+ kfree(txb);
+ }
+}
+
+/**************************************************************
+ Utility function for the tpm_private structure
+**************************************************************/
+static inline void tpm_private_init(struct tpm_private *tp)
+{
+ spin_lock_init(&tp->tx_lock);
+ init_waitqueue_head(&tp->wait_q);
+ atomic_set(&tp->refcnt, 1);
+}
+
+static inline void tpm_private_put(void)
+{
+ if ( atomic_dec_and_test(&my_priv->refcnt)) {
+ tpmif_free_tx_buffers(my_priv);
+ kfree(my_priv);
+ my_priv = NULL;
+ }
+}
+
+static struct tpm_private *tpm_private_get(void)
+{
+ int err;
+ if (!my_priv) {
+ my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
+ if (my_priv) {
+ tpm_private_init(my_priv);
+ err = tpmif_allocate_tx_buffers(my_priv);
+ if (err < 0) {
+ tpm_private_put();
+ }
+ }
+ } else {
+ atomic_inc(&my_priv->refcnt);
+ }
+ return my_priv;
+}
+
+/**************************************************************
+
+ The interface to let the tpm plugin register its callback
+ function and send data to another partition using this module
+
+**************************************************************/
+
+static DEFINE_MUTEX(suspend_lock);
+/*
+ * Send data via this module by calling this function
+ */
+int vtpm_vd_send(struct tpm_chip *chip,
+ struct tpm_private *tp,
+ const u8 * buf, size_t count, void *ptr)
+{
+ int sent;
+
+ mutex_lock(&suspend_lock);
+ sent = tpm_xmit(tp, buf, count, 0, ptr);
+ mutex_unlock(&suspend_lock);
+
+ return sent;
+}
+
+/**************************************************************
+ XENBUS support code
+**************************************************************/
+
+static int setup_tpmring(struct xenbus_device *dev,
+ struct tpm_private *tp)
+{
+ tpmif_tx_interface_t *sring;
+ int err;
+
+ tp->ring_ref = GRANT_INVALID_REF;
+
+ sring = (void *)__get_free_page(GFP_KERNEL);
+ if (!sring) {
+ xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
+ return -ENOMEM;
+ }
+ tp->tx = sring;
+
+ err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
+ if (err < 0) {
+ free_page((unsigned long)sring);
+ tp->tx = NULL;
+ xenbus_dev_fatal(dev, err, "allocating grant reference");
+ goto fail;
+ }
+ tp->ring_ref = err;
+
+ err = tpmif_connect(dev, tp, dev->otherend_id);
+ if (err)
+ goto fail;
+
+ return 0;
+fail:
+ destroy_tpmring(tp);
+ return err;
+}
+
+
+static void destroy_tpmring(struct tpm_private *tp)
+{
+ tpmif_set_connected_state(tp, 0);
+
+ if (tp->ring_ref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(tp->ring_ref, 0,
+ (unsigned long)tp->tx);
+ tp->ring_ref = GRANT_INVALID_REF;
+ tp->tx = NULL;
+ }
+
+ if (tp->irq)
+ unbind_from_irqhandler(tp->irq, tp);
+
+ tp->evtchn = tp->irq = 0;
+}
+
+
+static int talk_to_backend(struct xenbus_device *dev,
+ struct tpm_private *tp)
+{
+ const char *message = NULL;
+ int err;
+ xenbus_transaction_t xbt;
+
+ err = setup_tpmring(dev, tp);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "setting up ring");
+ goto out;
+ }
+
+again:
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "starting transaction");
+ goto destroy_tpmring;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename,
+ "ring-ref","%u", tp->ring_ref);
+ if (err) {
+ message = "writing ring-ref";
+ goto abort_transaction;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename,
+ "event-channel", "%u", tp->evtchn);
+ if (err) {
+ message = "writing event-channel";
+ goto abort_transaction;
+ }
+
+ err = xenbus_transaction_end(xbt, 0);
+ if (err == -EAGAIN)
+ goto again;
+ if (err) {
+ xenbus_dev_fatal(dev, err, "completing transaction");
+ goto destroy_tpmring;
+ }
+
+ xenbus_switch_state(dev, XenbusStateConnected);
+
+ return 0;
+
+abort_transaction:
+ xenbus_transaction_end(xbt, 1);
+ if (message)
+ xenbus_dev_error(dev, err, "%s", message);
+destroy_tpmring:
+ destroy_tpmring(tp);
+out:
+ return err;
+}
+
+/**
+ * Callback received when the backend's state changes.
+ */
+static void backend_changed(struct xenbus_device *dev,
+ XenbusState backend_state)
+{
+ struct tpm_private *tp = dev->data;
+ DPRINTK("\n");
+
+ switch (backend_state) {
+ case XenbusStateInitialising:
+ case XenbusStateInitWait:
+ case XenbusStateInitialised:
+ case XenbusStateUnknown:
+ break;
+
+ case XenbusStateConnected:
+ tpmif_set_connected_state(tp, 1);
+ break;
+
+ case XenbusStateClosing:
+ tpmif_set_connected_state(tp, 0);
+ break;
+
+ case XenbusStateClosed:
+ if (tp->is_suspended == 0) {
+ device_unregister(&dev->dev);
+ }
+ xenbus_switch_state(dev, XenbusStateClosed);
+ break;
+ }
+}
+
+
+static int tpmfront_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+ int err;
+ int handle;
+ struct tpm_private *tp = tpm_private_get();
+
+ if (!tp)
+ return -ENOMEM;
+
+ err = xenbus_scanf(XBT_NULL, dev->nodename,
+ "handle", "%i", &handle);
+ if (XENBUS_EXIST_ERR(err))
+ return err;
+
+ if (err < 0) {
+ xenbus_dev_fatal(dev,err,"reading virtual-device");
+ return err;
+ }
+
+ tp->dev = dev;
+ dev->data = tp;
+
+ err = talk_to_backend(dev, tp);
+ if (err) {
+ tpm_private_put();
+ dev->data = NULL;
+ return err;
+ }
+ return 0;
+}
+
+
+static int tpmfront_remove(struct xenbus_device *dev)
+{
+ struct tpm_private *tp = (struct tpm_private *)dev->data;
+ destroy_tpmring(tp);
+ return 0;
+}
+
+static int tpmfront_suspend(struct xenbus_device *dev)
+{
+ struct tpm_private *tp = (struct tpm_private *)dev->data;
+ u32 ctr;
+
+ /* lock, so no app can send */
+ mutex_lock(&suspend_lock);
+ tp->is_suspended = 1;
+
+ for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
+ if ((ctr % 10) == 0)
+ printk("TPM-FE [INFO]: Waiting for outstanding request.\n");
+ /*
+ * Wait for a request to be responded to.
+ */
+ interruptible_sleep_on_timeout(&tp->wait_q, 100);
+ }
+ xenbus_switch_state(dev, XenbusStateClosed);
+
+ if (atomic_read(&tp->tx_busy)) {
+ /*
+ * A temporary work-around.
+ */
+ printk("TPM-FE [WARNING]: Resetting busy flag.");
+ atomic_set(&tp->tx_busy, 0);
+ }
+
+ return 0;
+}
+
+static int tpmfront_resume(struct xenbus_device *dev)
+{
+ struct tpm_private *tp = (struct tpm_private *)dev->data;
+ destroy_tpmring(tp);
+ return talk_to_backend(dev, tp);
+}
+
+static int tpmif_connect(struct xenbus_device *dev,
+ struct tpm_private *tp,
+ domid_t domid)
+{
+ int err;
+
+ tp->backend_id = domid;
+
+ err = xenbus_alloc_evtchn(dev, &tp->evtchn);
+ if (err)
+ return err;
+
+ err = bind_evtchn_to_irqhandler(tp->evtchn,
+ tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
+ tp);
+ if (err <= 0) {
+ WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
+ return err;
+ }
+
+ tp->irq = err;
+ return 0;
+}
+
+static struct xenbus_device_id tpmfront_ids[] = {
+ { "vtpm" },
+ { "" }
};

-struct data_exchange {
- struct transmission *current_request;
- spinlock_t req_list_lock;
- wait_queue_head_t req_wait_queue;
-
- struct list_head queued_requests;
-
- struct transmission *current_response;
- spinlock_t resp_list_lock;
- wait_queue_head_t resp_wait_queue; // processes waiting for responses
-
- struct transmission *req_cancelled; // if a cancellation was encounterd
-
- unsigned int fe_status;
- unsigned int flags;
+static struct xenbus_driver tpmfront = {
+ .name = "vtpm",
+ .owner = THIS_MODULE,
+ .ids = tpmfront_ids,
+ .probe = tpmfront_probe,
+ .remove = tpmfront_remove,
+ .resume = tpmfront_resume,
+ .otherend_changed = backend_changed,
+ .suspend = tpmfront_suspend,
};

-enum {
- DATAEX_FLAG_QUEUED_ONLY = 0x1
+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;
+
+ for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
+ tp->tx_buffers[i] = tx_buffer_alloc();
+ if (!tp->tx_buffers[i]) {
+ tpmif_free_tx_buffers(tp);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static void tpmif_free_tx_buffers(struct tpm_private *tp)
+{
+ unsigned int i;
+
+ for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
+ tx_buffer_free(tp->tx_buffers[i]);
+ }
+}
+
+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;
+
+ atomic_set(&tp->tx_busy, 0);
+ wake_up_interruptible(&tp->wait_q);
+
+ received = tx->size;
+
+ buffer = kmalloc(received, GFP_ATOMIC);
+ if (NULL == buffer) {
+ goto exit;
+ }
+
+ for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
+ struct tx_buffer *txb = tp->tx_buffers[i];
+ tpmif_tx_request_t *tx;
+ unsigned int tocopy;
+
+ tx = &tp->tx->ring[i].req;
+ tocopy = tx->size;
+ if (tocopy > PAGE_SIZE) {
+ tocopy = PAGE_SIZE;
+ }
+
+ memcpy(&buffer[offset], txb->data, tocopy);
+
+ gnttab_release_grant_reference(&gref_head, tx->ref);
+
+ offset += tocopy;
+ }
+
+ vtpm_vd_recv(buffer, received, tp->tx_remember);
+ kfree(buffer);
+
+exit:
+
+ return;
+}
+
+
+static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
+{
+ struct tpm_private *tp = tpm_priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tp->tx_lock, flags);
+ tpmif_rx_tasklet.data = (unsigned long)tp;
+ tasklet_schedule(&tpmif_rx_tasklet);
+ spin_unlock_irqrestore(&tp->tx_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+
+static int tpm_xmit(struct tpm_private *tp,
+ const u8 * buf, size_t count, int isuserbuffer,
+ void *remember)
+{
+ tpmif_tx_request_t *tx;
+ TPMIF_RING_IDX i;
+ unsigned int offset = 0;
+
+ spin_lock_irq(&tp->tx_lock);
+
+ if (unlikely(atomic_read(&tp->tx_busy))) {
+ printk("tpm_xmit: There's an outstanding request/response "
+ "on the way!\n");
+ spin_unlock_irq(&tp->tx_lock);
+ return -EBUSY;
+ }
+
+ if (tp->is_connected != 1) {
+ spin_unlock_irq(&tp->tx_lock);
+ return -EIO;
+ }
+
+ for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
+ struct tx_buffer *txb = tp->tx_buffers[i];
+ int copied;
+
+ if (NULL == txb) {
+ DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
+ "Not transmitting anything!\n", i);
+ spin_unlock_irq(&tp->tx_lock);
+ return -EFAULT;
+ }
+ copied = tx_buffer_copy(txb, &buf[offset], count,
+ isuserbuffer);
+ if (copied < 0) {
+ /* An error occurred */
+ spin_unlock_irq(&tp->tx_lock);
+ return copied;
+ }
+ count -= copied;
+ offset += copied;
+
+ tx = &tp->tx->ring[i].req;
+
+ tx->addr = virt_to_machine(txb->data);
+ tx->size = txb->len;
+
+ DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
+
+ /* get the granttable reference for this page */
+ tx->ref = gnttab_claim_grant_reference(&gref_head);
+
+ if (-ENOSPC == tx->ref) {
+ spin_unlock_irq(&tp->tx_lock);
+ DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
+ return -ENOSPC;
+ }
+ gnttab_grant_foreign_access_ref( tx->ref,
+ tp->backend_id,
+ (tx->addr >> PAGE_SHIFT),
+ 0 /*RW*/);
+ wmb();
+ }
+
+ atomic_set(&tp->tx_busy, 1);
+ tp->tx_remember = remember;
+ mb();
+
+ DPRINTK("Notifying backend via event channel %d\n",
+ tp->evtchn);
+
+ notify_remote_via_irq(tp->irq);
+
+ spin_unlock_irq(&tp->tx_lock);
+ return offset;
+}
+
+
+static void tpmif_notify_upperlayer(struct tpm_private *tp)
+{
+ /*
+ * Notify upper layer about the state of the connection
+ * to the BE.
+ */
+ if (tp->is_connected) {
+ vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
+ } else {
+ vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
+ }
+}
+
+
+static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
+{
+ /*
+ * Don't notify upper layer if we are in suspend mode and
+ * should disconnect - assumption is that we will resume
+ * The mutex keeps apps from sending.
+ */
+ if (is_connected == 0 && tp->is_suspended == 1) {
+ return;
+ }
+
+ /*
+ * Unlock the mutex if we are connected again
+ * after being suspended - now resuming.
+ * This also removes the suspend state.
+ */
+ if (is_connected == 1 && tp->is_suspended == 1) {
+ tp->is_suspended = 0;
+ /* unlock, so apps can resume sending */
+ mutex_unlock(&suspend_lock);
+ }
+
+ if (is_connected != tp->is_connected) {
+ tp->is_connected = is_connected;
+ tpmif_notify_upperlayer(tp);
+ }
+}
+
+
+
+/* =================================================================
+ * Initialization function.
+ * =================================================================
+ */
+
+struct tpm_virtual_device tvd = {
+ .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
};

-static struct data_exchange dataex;
-
-static unsigned long disconnect_time;
-
-static struct tpmfe_device tpmfe;
-
-/* local function prototypes */
-static void __exit cleanup_xen(void);
-
-
-/* =============================================================
- * Some utility functions
- * =============================================================
- */
-static inline struct transmission *
-transmission_alloc(void)
-{
- return kzalloc(sizeof(struct transmission), GFP_KERNEL);
-}
-
-static inline unsigned char *
-transmission_set_buffer(struct transmission *t,
- unsigned char *buffer, unsigned int len)
-{
- kfree(t->request);
- t->request = kmalloc(len, GFP_KERNEL);
- if (t->request) {
- memcpy(t->request,
- buffer,
- len);
- t->request_len = len;
- }
- return t->request;
-}
-
-static inline void
-transmission_free(struct transmission *t)
-{
- kfree(t->request);
- kfree(t->rcv_buffer);
- kfree(t);
-}
-
-/* =============================================================
- * Interface with the TPM shared memory driver for XEN
- * =============================================================
- */
-static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
-{
- int ret_size = 0;
- struct transmission *t;
-
- /*
- * The list with requests must contain one request
- * only and the element there must be the one that
- * was passed to me from the front-end.
- */
- if (dataex.current_request != ptr) {
- printk("WARNING: The request pointer is different than the "
- "pointer the shared memory driver returned to me. "
- "%p != %p\n",
- dataex.current_request, ptr);
- }
-
- /*
- * If the request has been cancelled, just quit here
- */
- if (dataex.req_cancelled == (struct transmission *)ptr) {
- if (dataex.current_request == dataex.req_cancelled) {
- dataex.current_request = NULL;
- }
- transmission_free(dataex.req_cancelled);
- dataex.req_cancelled = NULL;
- return 0;
- }
-
- if (NULL != (t = dataex.current_request)) {
- transmission_free(t);
- dataex.current_request = NULL;
- }
-
- t = transmission_alloc();
- if (t) {
- unsigned long flags;
- t->rcv_buffer = kmalloc(count, GFP_KERNEL);
- if (! t->rcv_buffer) {
- transmission_free(t);
- return -ENOMEM;
- }
- t->buffersize = count;
- memcpy(t->rcv_buffer, buffer, count);
- ret_size = count;
-
- spin_lock_irqsave(&dataex.resp_list_lock ,flags);
- dataex.current_response = t;
- spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
- wake_up_interruptible(&dataex.resp_wait_queue);
- }
- return ret_size;
-}
-
-
-static void tpm_fe_status(unsigned int flags)
-{
- dataex.fe_status = flags;
- if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
- disconnect_time = jiffies;
- }
-}
-
-/* =============================================================
- * Interface with the generic TPM driver
- * =============================================================
- */
-static int tpm_xen_recv(struct tpm_chip *chip, u8 * buf, size_t count)
-{
- unsigned long flags;
- int rc = 0;
-
- spin_lock_irqsave(&dataex.resp_list_lock, flags);
- /*
- * Check if the previous operation only queued the command
- * In this case there won't be a response, so I just
- * return from here and reset that flag. In any other
- * case I should receive a response from the back-end.
- */
- if ((dataex.flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
- dataex.flags &= ~DATAEX_FLAG_QUEUED_ONLY;
- spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
- /*
- * a little hack here. The first few measurements
- * are queued since there's no way to talk to the
- * TPM yet (due to slowness of the control channel)
- * So we just make IMA happy by giving it 30 NULL
- * bytes back where the most important part is
- * that the result code is '0'.
- */
-
- count = MIN(count, 30);
- memset(buf, 0x0, count);
- return count;
- }
- /*
- * Check whether something is in the responselist and if
- * there's nothing in the list wait for something to appear.
- */
-
- if (NULL == dataex.current_response) {
- spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
- interruptible_sleep_on_timeout(&dataex.resp_wait_queue,
- 1000);
- spin_lock_irqsave(&dataex.resp_list_lock ,flags);
- }
-
- if (NULL != dataex.current_response) {
- struct transmission *t = dataex.current_response;
- dataex.current_response = NULL;
- rc = MIN(count, t->buffersize);
- memcpy(buf, t->rcv_buffer, rc);
- transmission_free(t);
- }
-
- spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
- return rc;
-}
-
-static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
-{
- /*
- * We simply pass the packet onto the XEN shared
- * memory driver.
- */
- unsigned long flags;
+static int __init tpmif_init(void)
+{
int rc;
- struct transmission *t = transmission_alloc();
-
- spin_lock_irqsave(&dataex.req_list_lock, flags);
- /*
- * If there's a current request, it must be the
- * previous request that has timed out.
- */
- if (dataex.current_request != NULL) {
- printk("WARNING: Sending although there is a request outstanding.\n"
- " Previous request must have timed out.\n");
- transmission_free(dataex.current_request);
- dataex.current_request = NULL;
- }
-
- if (t != NULL) {
- unsigned int error = 0;
- /*
- * Queue the packet if the driver below is not
- * ready, yet, or there is any packet already
- * in the queue.
- * If the driver below is ready, unqueue all
- * packets first before sending our current
- * packet.
- * For each unqueued packet, except for the
- * last (=current) packet, call the function
- * tpm_xen_recv to wait for the response to come
- * back.
- */
- if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
- if (time_after(jiffies, disconnect_time + HZ * 10)) {
- rc = -ENOENT;
- } else {
- /*
- * copy the request into the buffer
- */
- if (transmission_set_buffer(t, buf, count)
- == NULL) {
- transmission_free(t);
- rc = -ENOMEM;
- goto exit;
- }
- dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
- list_add_tail(&t->next, &dataex.queued_requests);
- rc = 0;
- }
- } else {
- /*
- * Check whether there are any packets in the queue
- */
- while (!list_empty(&dataex.queued_requests)) {
- /*
- * Need to dequeue them.
- * Read the result into a dummy buffer.
- */
- unsigned char buffer[1];
- struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
- list_del(&qt->next);
- dataex.current_request = qt;
- spin_unlock_irqrestore(&dataex.req_list_lock,
- flags);
-
- rc = tpm_fe_send(tpmfe.tpm_private,
- qt->request,
- qt->request_len,
- qt);
-
- if (rc < 0) {
- spin_lock_irqsave(&dataex.req_list_lock, flags);
- if ((qt = dataex.current_request) != NULL) {
- /*
- * requeue it at the beginning
- * of the list
- */
- list_add(&qt->next,
- &dataex.queued_requests);
- }
- dataex.current_request = NULL;
- error = 1;
- break;
- }
- /*
- * After this point qt is not valid anymore!
- * It is freed when the front-end is delivering the data
- * by calling tpm_recv
- */
-
- /*
- * Try to receive the response now into the provided dummy
- * buffer (I don't really care about this response since
- * there is no receiver anymore for this response)
- */
- rc = tpm_xen_recv(chip, buffer, sizeof(buffer));
-
- spin_lock_irqsave(&dataex.req_list_lock, flags);
- }
-
- if (error == 0) {
- /*
- * Finally, send the current request.
- */
- dataex.current_request = t;
- /*
- * Call the shared memory driver
- * Pass to it the buffer with the request, the
- * amount of bytes in the request and
- * a void * pointer (here: transmission structure)
- */
- rc = tpm_fe_send(tpmfe.tpm_private,
- buf, count, t);
- /*
- * The generic TPM driver will call
- * the function to receive the response.
- */
- if (rc < 0) {
- dataex.current_request = NULL;
- goto queue_it;
- }
- } else {
-queue_it:
- if (transmission_set_buffer(t, buf, count) == NULL) {
- transmission_free(t);
- rc = -ENOMEM;
- goto exit;
- }
- /*
- * An error occurred. Don't event try
- * to send the current request. Just
- * queue it.
- */
- dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
- list_add_tail(&t->next,
- &dataex.queued_requests);
- rc = 0;
- }
- }
- } else {
- rc = -ENOMEM;
- }
-
-exit:
- spin_unlock_irqrestore(&dataex.req_list_lock, flags);
- return rc;
-}
-
-static void tpm_xen_cancel(struct tpm_chip *chip)
-{
- unsigned long flags;
- spin_lock_irqsave(&dataex.resp_list_lock,flags);
-
- dataex.req_cancelled = dataex.current_request;
-
- spin_unlock_irqrestore(&dataex.resp_list_lock,flags);
-}
-
-static u8 tpm_xen_status(struct tpm_chip *chip)
-{
- unsigned long flags;
- u8 rc = 0;
- spin_lock_irqsave(&dataex.resp_list_lock, flags);
- /*
- * Data are available if:
- * - there's a current response
- * - the last packet was queued only (this is fake, but necessary to
- * get the generic TPM layer to call the receive function.)
- */
- if (NULL != dataex.current_response ||
- 0 != (dataex.flags & DATAEX_FLAG_QUEUED_ONLY)) {
- rc = STATUS_DATA_AVAIL;
- }
- spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
- return rc;
-}
-
-static struct file_operations tpm_xen_ops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .open = tpm_open,
- .read = tpm_read,
- .write = tpm_write,
- .release = tpm_release,
-};
-
-static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
-static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
-static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
-
-static struct attribute* xen_attrs[] = {
- &dev_attr_pubek.attr,
- &dev_attr_pcrs.attr,
- &dev_attr_caps.attr,
- &dev_attr_cancel.attr,
- NULL,
-};
-
-static struct attribute_group xen_attr_grp = { .attrs = xen_attrs };
-
-static struct tpm_vendor_specific tpm_xen = {
- .recv = tpm_xen_recv,
- .send = tpm_xen_send,
- .cancel = tpm_xen_cancel,
- .status = tpm_xen_status,
- .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
- .req_complete_val = STATUS_DATA_AVAIL,
- .req_canceled = STATUS_READY,
- .base = 0,
- .attr_group = &xen_attr_grp,
- .miscdev.fops = &tpm_xen_ops,
- .buffersize = 64 * 1024,
-};
-
-static struct platform_device *pdev;
-
-static struct tpmfe_device tpmfe = {
- .receive = tpm_recv,
- .status = tpm_fe_status,
-};
-
-
-static int __init init_xen(void)
-{
- int rc;
+ struct tpm_private *tp;

if ((xen_start_info->flags & SIF_INITDOMAIN)) {
return -EPERM;
}
- /*
- * Register device with the low lever front-end
- * driver
- */
- if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) {
- goto err_exit;
- }
-
- /*
- * Register our device with the system.
- */
- pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
- if (IS_ERR(pdev)) {
- rc = PTR_ERR(pdev);
- goto err_unreg_fe;
- }
-
- tpm_xen.buffersize = tpmfe.max_tx_size;
-
- if ((rc = tpm_register_hardware(&pdev->dev, &tpm_xen)) < 0) {
- goto err_unreg_pdev;
- }
-
- dataex.current_request = NULL;
- spin_lock_init(&dataex.req_list_lock);
- init_waitqueue_head(&dataex.req_wait_queue);
- INIT_LIST_HEAD(&dataex.queued_requests);
-
- dataex.current_response = NULL;
- spin_lock_init(&dataex.resp_list_lock);
- init_waitqueue_head(&dataex.resp_wait_queue);
-
- disconnect_time = jiffies;
-
- return 0;
-
-
-err_unreg_pdev:
- platform_device_unregister(pdev);
-err_unreg_fe:
- tpm_fe_unregister_receiver();
-
-err_exit:
+
+ tp = tpm_private_get();
+ if (!tp) {
+ rc = -ENOMEM;
+ goto failexit;
+ }
+
+ tvd.tpm_private = tp;
+ rc = init_vtpm(&tvd);
+ if (rc)
+ goto init_vtpm_failed;
+
+ IPRINTK("Initialising the vTPM driver.\n");
+ if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
+ &gref_head ) < 0) {
+ rc = -EFAULT;
+ goto gnttab_alloc_failed;
+ }
+
+ init_tpm_xenbus();
+ return 0;
+
+gnttab_alloc_failed:
+ cleanup_vtpm();
+init_vtpm_failed:
+ tpm_private_put();
+failexit:
+
return rc;
}

-static void __exit cleanup_xen(void)
-{
- struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
- if (chip) {
- tpm_remove_hardware(chip->dev);
- platform_device_unregister(pdev);
- tpm_fe_unregister_receiver();
- }
-}
-
-module_init(init_xen);
-module_exit(cleanup_xen);
-
-MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
-MODULE_DESCRIPTION("TPM Driver for XEN (shared memory)");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
+
+static void __exit tpmif_exit(void)
+{
+ cleanup_vtpm();
+ tpm_private_put();
+ exit_tpm_xenbus();
+ gnttab_free_grant_references(gref_head);
+}
+
+module_init(tpmif_init);
+module_exit(tpmif_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tty_io.c
--- a/linux-2.6-xen-sparse/drivers/char/tty_io.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c Mon May 08 14:46:11 2006 -0600
@@ -2708,7 +2708,11 @@ static void __do_SAK(void *arg)
}
task_lock(p);
if (p->files) {
- rcu_read_lock();
+ /*
+ * We don't take a ref to the file, so we must
+ * hold ->file_lock instead.
+ */
+ spin_lock(&p->files->file_lock);
fdt = files_fdtable(p->files);
for (i=0; i < fdt->max_fds; i++) {
filp = fcheck_files(p->files, i);
@@ -2723,7 +2727,7 @@ static void __do_SAK(void *arg)
break;
}
}
- rcu_read_unlock();
+ spin_unlock(&p->files->file_lock);
}
task_unlock(p);
} while_each_task_pid(session, PIDTYPE_SID, p);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon May 08 14:46:11 2006 -0600
@@ -13,7 +13,7 @@ if XEN
if XEN
config XEN_INTERFACE_VERSION
hex
- default 0x00030101
+ default 0x00030202

menu "XEN"

@@ -99,7 +99,7 @@ config XEN_BLKDEV_TAP_BE

config XEN_NETDEV_BACKEND
tristate "Network-device backend driver"
- depends on XEN_BACKEND
+ depends on XEN_BACKEND && NET
default y
help
The network-device backend driver allows the kernel to export its
@@ -155,7 +155,7 @@ config XEN_BLKDEV_FRONTEND

config XEN_NETDEV_FRONTEND
tristate "Network-device frontend driver"
- depends on XEN
+ depends on XEN && NET
default y
help
The network-device frontend driver allows the kernel to access
@@ -172,14 +172,6 @@ config XEN_BLKDEV_TAP
to other VMs. Block messages may be passed through or redirected
to a character device, allowing device prototyping in application
space. Odds are that you want to say N here.
-
-config XEN_TPMDEV_FRONTEND
- tristate "TPM-device frontend driver"
- default n
- select TCG_TPM
- select TCG_XEN
- help
- The TPM-device frontend driver.

config XEN_SCRUB_PAGES
bool "Scrub memory before freeing it to Xen"
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Mon May 08 14:46:11 2006 -0600
@@ -16,7 +16,6 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blk
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/
obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
-obj-$(CONFIG_XEN_TPMDEV_FRONTEND) += tpmfront/
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon May 08 14:46:11 2006 -0600
@@ -94,8 +94,8 @@ static DECLARE_WORK(balloon_worker, ball
static DECLARE_WORK(balloon_worker, balloon_process, NULL);
static struct timer_list balloon_timer;

-#define PAGE_TO_LIST(p) (&(p)->ballooned)
-#define LIST_TO_PAGE(l) list_entry((l), struct page, ballooned)
+#define PAGE_TO_LIST(p) (&(p)->lru)
+#define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
#define UNLIST_PAGE(p) \
do { \
list_del(PAGE_TO_LIST(p)); \
@@ -195,14 +195,14 @@ static int increase_reservation(unsigned
page = balloon_next_page(page);
}

- reservation.extent_start = frame_list;
+ set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = nr_pages;
rc = HYPERVISOR_memory_op(
XENMEM_populate_physmap, &reservation);
if (rc < nr_pages) {
int ret;
/* We hit the Xen hard limit: reprobe. */
- reservation.extent_start = frame_list;
+ set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = rc;
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
&reservation);
@@ -216,7 +216,8 @@ static int increase_reservation(unsigned
BUG_ON(page == NULL);

pfn = page_to_pfn(page);
- BUG_ON(phys_to_machine_mapping_valid(pfn));
+ BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
+ phys_to_machine_mapping_valid(pfn));

/* Update P->M and M->P tables. */
set_phys_to_machine(pfn, frame_list[i]);
@@ -308,7 +309,7 @@ static int decrease_reservation(unsigned
balloon_append(pfn_to_page(pfn));
}

- reservation.extent_start = frame_list;
+ set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = nr_pages;
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
BUG_ON(ret != nr_pages);
@@ -522,11 +523,11 @@ static int dealloc_pte_fn(
unsigned long mfn = pte_mfn(*pte);
int ret;
struct xen_memory_reservation reservation = {
- .extent_start = &mfn,
.nr_extents = 1,
.extent_order = 0,
.domid = DOMID_SELF
};
+ set_xen_guest_handle(reservation.extent_start, &mfn);
set_pte_at(&init_mm, addr, pte, __pte_ma(0));
set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
@@ -539,6 +540,8 @@ struct page *balloon_alloc_empty_page_ra
unsigned long vstart, flags;
unsigned int order = get_order(nr_pages * PAGE_SIZE);
int ret;
+ unsigned long i;
+ struct page *page;

vstart = __get_free_pages(GFP_KERNEL, order);
if (vstart == 0)
@@ -547,9 +550,22 @@ struct page *balloon_alloc_empty_page_ra
scrub_pages(vstart, 1 << order);

balloon_lock(flags);
- ret = apply_to_page_range(&init_mm, vstart,
- PAGE_SIZE << order, dealloc_pte_fn, NULL);
- BUG_ON(ret);
+ if (xen_feature(XENFEAT_auto_translated_physmap)) {
+ unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
+ struct xen_memory_reservation reservation = {
+ .nr_extents = 1,
+ .extent_order = order,
+ .domid = DOMID_SELF
+ };
+ set_xen_guest_handle(reservation.extent_start, &gmfn);
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &reservation);
+ BUG_ON(ret != 1);
+ } else {
+ ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
+ dealloc_pte_fn, NULL);
+ BUG_ON(ret);
+ }
current_pages -= 1UL << order;
totalram_pages = current_pages;
balloon_unlock(flags);
@@ -558,7 +574,12 @@ struct page *balloon_alloc_empty_page_ra

flush_tlb_all();

- return virt_to_page(vstart);
+ page = virt_to_page(vstart);
+
+ for (i = 0; i < (1UL << order); i++)
+ set_page_count(page + i, 1);
+
+ return page;
}

void balloon_dealloc_empty_page_range(
@@ -568,8 +589,10 @@ void balloon_dealloc_empty_page_range(
unsigned int order = get_order(nr_pages * PAGE_SIZE);

balloon_lock(flags);
- for (i = 0; i < (1UL << order); i++)
+ for (i = 0; i < (1UL << order); i++) {
+ BUG_ON(page_count(page + i) != 1);
balloon_append(page + i);
+ }
balloon_unlock(flags);

schedule_work(&balloon_worker);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon May 08 14:46:11 2006 -0600
@@ -410,7 +410,7 @@ static void dispatch_rw_block_io(blkif_t
}

pending_handle(pending_req, i) = map[i].handle;
-#ifdef __ia64__
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
pending_vaddrs[vaddr_pagenr(pending_req, i)] =
(unsigned long)gnttab_map_vaddr(map[i]);
#else
@@ -546,7 +546,7 @@ static int __init blkif_init(void)

blkif_interface_init();

-#ifdef __ia64__
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
extern unsigned long alloc_empty_foreign_map_page_range(
unsigned long pages);
mmap_vstart = (unsigned long)
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Mon May 08 14:46:11 2006 -0600
@@ -74,7 +74,7 @@ static int map_frontend_page(blkif_t *bl
blkif->shmem_ref = shared_page;
blkif->shmem_handle = op.handle;

-#ifdef __ia64__
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
/* on some arch's, map_grant_ref behaves like mmap, in that the
* passed address is a hint and a different address may be returned */
blkif->blk_ring_area->addr = gnttab_map_vaddr(op);
@@ -101,10 +101,7 @@ int blkif_map(blkif_t *blkif, unsigned l
{
blkif_sring_t *sring;
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = blkif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;

/* Already connected through? */
if (blkif->irq)
@@ -119,14 +116,18 @@ int blkif_map(blkif_t *blkif, unsigned l
return err;
}

- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = blkif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
return err;
}

- blkif->evtchn = op.u.bind_interdomain.local_port;
+ blkif->evtchn = bind_interdomain.local_port;

sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Mon May 08 14:46:11 2006 -0600
@@ -70,10 +70,7 @@ int blkif_map(blkif_t *blkif, unsigned l
{
blkif_sring_t *sring;
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = blkif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;

if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -84,14 +81,18 @@ int blkif_map(blkif_t *blkif, unsigned l
return err;
}

- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = blkif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
return err;
}

- blkif->evtchn = op.u.bind_interdomain.local_port;
+ blkif->evtchn = bind_interdomain.local_port;

sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Mon May 08 14:46:11 2006 -0600
@@ -103,7 +103,7 @@ static int irq_bindcount[NR_IRQS];
static int irq_bindcount[NR_IRQS];

/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
+static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];

#ifdef CONFIG_SMP

@@ -226,7 +226,8 @@ static int find_unbound_irq(void)
{
int irq;

- for (irq = 0; irq < NR_IRQS; irq++)
+ /* Only allocate from dynirq range */
+ for (irq = DYNIRQ_BASE; irq < NR_IRQS; irq++)
if (irq_bindcount[irq] == 0)
break;

@@ -257,16 +258,18 @@ static int bind_evtchn_to_irq(unsigned i

static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
+ struct evtchn_bind_virq bind_virq;
int evtchn, irq;

spin_lock(&irq_mapping_update_lock);

if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;

irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
@@ -286,15 +289,17 @@ static int bind_virq_to_irq(unsigned int

static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
+ struct evtchn_bind_ipi bind_ipi;
int evtchn, irq;

spin_lock(&irq_mapping_update_lock);

if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
- op.u.bind_ipi.vcpu = cpu;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_ipi.port;
+ bind_ipi.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+ &bind_ipi) != 0)
+ BUG();
+ evtchn = bind_ipi.port;

irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
@@ -314,14 +319,15 @@ static int bind_ipi_to_irq(unsigned int

static void unbind_from_irq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);

spin_lock(&irq_mapping_update_lock);

if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();

switch (type_from_irq(irq)) {
case IRQT_VIRQ:
@@ -427,7 +433,7 @@ static void do_nothing_function(void *ig
/* Rebind an evtchn so that it gets delivered to a specific cpu */
static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
+ struct evtchn_bind_vcpu bind_vcpu;
int evtchn;

spin_lock(&irq_mapping_update_lock);
@@ -439,15 +445,15 @@ static void rebind_irq_to_cpu(unsigned i
}

/* Send future instances of this interrupt to other vcpu. */
- op.u.bind_vcpu.port = evtchn;
- op.u.bind_vcpu.vcpu = tcpu;
+ bind_vcpu.port = evtchn;
+ bind_vcpu.vcpu = tcpu;

/*
* If this fails, it usually just indicates that we're dealing with a
* virq or IPI channel, which don't actually need to be rebound. Ignore
* it, but don't do the xenlinux-level rebind in that case.
*/
- if (HYPERVISOR_event_channel_op(&op) >= 0)
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
bind_evtchn_to_cpu(evtchn, tcpu);

spin_unlock(&irq_mapping_update_lock);
@@ -543,22 +549,19 @@ static struct hw_interrupt_type dynirq_t

static inline void pirq_unmask_notify(int pirq)
{
- physdev_op_t op;
- if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
- op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
- (void)HYPERVISOR_physdev_op(&op);
- }
+ struct physdev_eoi eoi = { .irq = pirq };
+ if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
}

static inline void pirq_query_unmask(int pirq)
{
- physdev_op_t op;
- op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
- op.u.irq_status_query.irq = pirq;
- (void)HYPERVISOR_physdev_op(&op);
- clear_bit(pirq, &pirq_needs_unmask_notify[0]);
- if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
- set_bit(pirq, &pirq_needs_unmask_notify[0]);
+ struct physdev_irq_status_query irq_status;
+ irq_status.irq = pirq;
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
+ clear_bit(pirq, &pirq_needs_eoi[0]);
+ if (irq_status.flags & XENIRQSTAT_needs_eoi)
+ set_bit(pirq, &pirq_needs_eoi[0]);
}

/*
@@ -569,22 +572,22 @@ static inline void pirq_query_unmask(int

static unsigned int startup_pirq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
+ struct evtchn_bind_pirq bind_pirq;
int evtchn = evtchn_from_irq(irq);

if (VALID_EVTCHN(evtchn))
goto out;

- op.u.bind_pirq.pirq = irq;
+ bind_pirq.pirq = irq;
/* NB. We are happy to share unless we are probing. */
- op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
- if (HYPERVISOR_event_channel_op(&op) != 0) {
+ bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
if (!probing_irq(irq))
printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
irq);
return 0;
}
- evtchn = op.u.bind_pirq.port;
+ evtchn = bind_pirq.port;

pirq_query_unmask(irq_to_pirq(irq));

@@ -601,7 +604,7 @@ static unsigned int startup_pirq(unsigne

static void shutdown_pirq(unsigned int irq)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
+ struct evtchn_close close;
int evtchn = evtchn_from_irq(irq);

if (!VALID_EVTCHN(evtchn))
@@ -609,8 +612,9 @@ static void shutdown_pirq(unsigned int i

mask_evtchn(evtchn);

- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ close.port = evtchn;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+ BUG();

bind_evtchn_to_cpu(evtchn, 0);
evtchn_to_irq[evtchn] = -1;
@@ -702,9 +706,8 @@ void unmask_evtchn(int port)

/* Slow path (hypercall) if this is a non-local port. */
if (unlikely(cpu != cpu_from_evtchn(port))) {
- evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
- .u.unmask.port = port };
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_unmask unmask = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
return;
}

@@ -727,8 +730,9 @@ EXPORT_SYMBOL_GPL(unmask_evtchn);

void irq_resume(void)
{
- evtchn_op_t op;
- int cpu, pirq, virq, ipi, irq, evtchn;
+ struct evtchn_bind_virq bind_virq;
+ struct evtchn_bind_ipi bind_ipi;
+ int cpu, pirq, virq, ipi, irq, evtchn;

init_evtchn_cpu_bindings();

@@ -762,12 +766,12 @@ void irq_resume(void)
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));

/* Get a new binding from Xen. */
- memset(&op, 0, sizeof(op));
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- op.u.bind_virq.vcpu = 0;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_virq.port;
+ bind_virq.virq = virq;
+ bind_virq.vcpu = 0;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq) != 0)
+ BUG();
+ evtchn = bind_virq.port;

/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
@@ -785,11 +789,11 @@ void irq_resume(void)
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));

/* Get a new binding from Xen. */
- memset(&op, 0, sizeof(op));
- op.cmd = EVTCHNOP_bind_ipi;
- op.u.bind_ipi.vcpu = 0;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- evtchn = op.u.bind_ipi.port;
+ bind_ipi.vcpu = 0;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+ &bind_ipi) != 0)
+ BUG();
+ evtchn = bind_ipi.port;

/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon May 08 14:46:11 2006 -0600
@@ -399,7 +399,7 @@ gnttab_resume(void)

setup.dom = DOMID_SELF;
setup.nr_frames = NR_GRANT_FRAMES;
- setup.frame_list = frames;
+ set_xen_guest_handle(setup.frame_list, frames);

rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
if (rc == -ENOSYS)
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Mon May 08 14:46:11 2006 -0600
@@ -206,68 +206,71 @@ static int evtchn_ioctl(struct inode *in
int rc;
struct per_user_data *u = file->private_data;
void __user *uarg = (void __user *) arg;
- evtchn_op_t op = { 0 };

switch (cmd) {
case IOCTL_EVTCHN_BIND_VIRQ: {
struct ioctl_evtchn_bind_virq bind;
+ struct evtchn_bind_virq bind_virq;

rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;

- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = bind.virq;
- op.u.bind_virq.vcpu = 0;
- rc = HYPERVISOR_event_channel_op(&op);
+ bind_virq.virq = bind.virq;
+ bind_virq.vcpu = 0;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq);
if (rc != 0)
break;

- rc = op.u.bind_virq.port;
+ rc = bind_virq.port;
evtchn_bind_to_user(u, rc);
break;
}

case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
struct ioctl_evtchn_bind_interdomain bind;
+ struct evtchn_bind_interdomain bind_interdomain;

rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;

- op.cmd = EVTCHNOP_bind_interdomain;
- op.u.bind_interdomain.remote_dom = bind.remote_domain;
- op.u.bind_interdomain.remote_port = bind.remote_port;
- rc = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = bind.remote_domain;
+ bind_interdomain.remote_port = bind.remote_port;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (rc != 0)
break;

- rc = op.u.bind_interdomain.local_port;
+ rc = bind_interdomain.local_port;
evtchn_bind_to_user(u, rc);
break;
}

case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
struct ioctl_evtchn_bind_unbound_port bind;
+ struct evtchn_alloc_unbound alloc_unbound;

rc = -EFAULT;
if (copy_from_user(&bind, uarg, sizeof(bind)))
break;

- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = bind.remote_domain;
- rc = HYPERVISOR_event_channel_op(&op);
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = bind.remote_domain;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (rc != 0)
break;

- rc = op.u.alloc_unbound.port;
+ rc = alloc_unbound.port;
evtchn_bind_to_user(u, rc);
break;
}

case IOCTL_EVTCHN_UNBIND: {
struct ioctl_evtchn_unbind unbind;
+ struct evtchn_close close;
int ret;

rc = -EFAULT;
@@ -291,9 +294,8 @@ static int evtchn_ioctl(struct inode *in

spin_unlock_irq(&port_user_lock);

- op.cmd = EVTCHNOP_close;
- op.u.close.port = unbind.port;
- ret = HYPERVISOR_event_channel_op(&op);
+ close.port = unbind.port;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
BUG_ON(ret);

rc = 0;
@@ -379,7 +381,7 @@ static int evtchn_release(struct inode *
{
int i;
struct per_user_data *u = filp->private_data;
- evtchn_op_t op = { 0 };
+ struct evtchn_close close;

spin_lock_irq(&port_user_lock);

@@ -393,9 +395,8 @@ static int evtchn_release(struct inode *
port_user[i] = NULL;
mask_evtchn(i);

- op.cmd = EVTCHNOP_close;
- op.u.close.port = i;
- ret = HYPERVISOR_event_channel_op(&op);
+ close.port = i;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
BUG_ON(ret);
}

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon May 08 14:46:11 2006 -0600
@@ -213,10 +213,7 @@ int netif_map(netif_t *netif, unsigned l
int err = -ENOMEM;
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = netif->domid,
- .u.bind_interdomain.remote_port = evtchn };
+ struct evtchn_bind_interdomain bind_interdomain;

/* Already connected through? */
if (netif->irq)
@@ -233,11 +230,15 @@ int netif_map(netif_t *netif, unsigned l
if (err)
goto err_map;

- err = HYPERVISOR_event_channel_op(&op);
+ bind_interdomain.remote_dom = netif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err)
goto err_hypervisor;

- netif->evtchn = op.u.bind_interdomain.local_port;
+ netif->evtchn = bind_interdomain.local_port;

netif->irq = bind_evtchn_to_irqhandler(
netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Mon May 08 14:46:11 2006 -0600
@@ -127,6 +127,14 @@ static struct ethtool_ops network_ethtoo
.set_tx_csum = ethtool_op_set_tx_csum,
};

+/*
+ * Nothing to do here. Virtual interface is point-to-point and the
+ * physical interface is probably promiscuous anyway.
+ */
+static void loopback_set_multicast_list(struct net_device *dev)
+{
+}
+
static void loopback_construct(struct net_device *dev, struct net_device *lo)
{
struct net_private *np = netdev_priv(dev);
@@ -137,6 +145,7 @@ static void loopback_construct(struct ne
dev->stop = loopback_close;
dev->hard_start_xmit = loopback_start_xmit;
dev->get_stats = loopback_get_stats;
+ dev->set_multicast_list = loopback_set_multicast_list;

dev->tx_queue_len = 0;

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon May 08 14:46:11 2006 -0600
@@ -105,11 +105,11 @@ static unsigned long alloc_mfn(void)
{
unsigned long mfn = 0, flags;
struct xen_memory_reservation reservation = {
- .extent_start = mfn_list,
.nr_extents = MAX_MFN_ALLOC,
.extent_order = 0,
.domid = DOMID_SELF
};
+ set_xen_guest_handle(reservation.extent_start, mfn_list);
spin_lock_irqsave(&mfn_lock, flags);
if ( unlikely(alloc_index == 0) )
alloc_index = HYPERVISOR_memory_op(
@@ -235,23 +235,35 @@ static void net_rx_action(unsigned long
vdata = (unsigned long)skb->data;
old_mfn = virt_to_mfn(vdata);

- /* Memory squeeze? Back off for an arbitrary while. */
- if ((new_mfn = alloc_mfn()) == 0) {
- if ( net_ratelimit() )
- WPRINTK("Memory squeeze in netback driver.\n");
- mod_timer(&net_timer, jiffies + HZ);
- skb_queue_head(&rx_queue, skb);
- break;
- }
- /*
- * Set the new P2M table entry before reassigning the old data
- * page. Heed the comment in pgtable-2level.h:pte_page(). :-)
- */
- set_phys_to_machine(__pa(skb->data) >> PAGE_SHIFT, new_mfn);
-
- MULTI_update_va_mapping(mcl, vdata,
- pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
- mcl++;
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* Memory squeeze? Back off for an arbitrary while. */
+ if ((new_mfn = alloc_mfn()) == 0) {
+ if ( net_ratelimit() )
+ WPRINTK("Memory squeeze in netback "
+ "driver.\n");
+ mod_timer(&net_timer, jiffies + HZ);
+ skb_queue_head(&rx_queue, skb);
+ break;
+ }
+ /*
+ * Set the new P2M table entry before reassigning
+ * the old data page. Heed the comment in
+ * pgtable-2level.h:pte_page(). :-)
+ */
+ set_phys_to_machine(
+ __pa(skb->data) >> PAGE_SHIFT,
+ new_mfn);
+
+ MULTI_update_va_mapping(mcl, vdata,
+ pfn_pte_ma(new_mfn,
+ PAGE_KERNEL), 0);
+ mcl++;
+
+ mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE;
+ mmu->val = __pa(vdata) >> PAGE_SHIFT;
+ mmu++;
+ }

gop->mfn = old_mfn;
gop->domid = netif->domid;
@@ -260,13 +272,6 @@ static void net_rx_action(unsigned long
netif->rx.req_cons++;
gop++;

- if (!xen_feature(XENFEAT_auto_translated_physmap)) {
- mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
- MMU_MACHPHYS_UPDATE;
- mmu->val = __pa(vdata) >> PAGE_SHIFT;
- mmu++;
- }
-
__skb_queue_tail(&rxq, skb);

/* Filled the batch queue? */
@@ -274,22 +279,24 @@ static void net_rx_action(unsigned long
break;
}

- if (mcl == rx_mcl)
- return;
-
- mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-
- if (mmu - rx_mmu) {
- mcl->op = __HYPERVISOR_mmu_update;
- mcl->args[0] = (unsigned long)rx_mmu;
- mcl->args[1] = mmu - rx_mmu;
- mcl->args[2] = 0;
- mcl->args[3] = DOMID_SELF;
- mcl++;
- }
-
- ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
- BUG_ON(ret != 0);
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ if (mcl == rx_mcl)
+ return;
+
+ mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+
+ if (mmu - rx_mmu) {
+ mcl->op = __HYPERVISOR_mmu_update;
+ mcl->args[0] = (unsigned long)rx_mmu;
+ mcl->args[1] = mmu - rx_mmu;
+ mcl->args[2] = 0;
+ mcl->args[3] = DOMID_SELF;
+ mcl++;
+ }
+
+ ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
+ BUG_ON(ret != 0);
+ }

ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op,
gop - grant_rx_op);
@@ -308,8 +315,11 @@ static void net_rx_action(unsigned long
netif->stats.tx_bytes += size;
netif->stats.tx_packets++;

- /* The update_va_mapping() must not fail. */
- BUG_ON(mcl->result != 0);
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* The update_va_mapping() must not fail. */
+ BUG_ON(mcl->result != 0);
+ mcl++;
+ }

/* Check the reassignment error code. */
status = NETIF_RSP_OKAY;
@@ -340,7 +350,6 @@ static void net_rx_action(unsigned long

netif_put(netif);
dev_kfree_skb(skb);
- mcl++;
gop++;
}

@@ -650,6 +659,7 @@ static void net_tx_action(unsigned long

skb->data_len = txreq.size - data_len;
skb->len += skb->data_len;
+ skb->truesize += skb->data_len;

skb->dev = netif->dev;
skb->protocol = eth_type_trans(skb, skb->dev);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon May 08 14:46:11 2006 -0600
@@ -607,7 +607,7 @@ static void network_alloc_rx_buffers(str
/* Tell the ballon driver what is going on. */
balloon_update_driver_allowance(i);

- reservation.extent_start = np->rx_pfn_array;
+ set_xen_guest_handle(reservation.extent_start, np->rx_pfn_array);
reservation.nr_extents = i;
reservation.extent_order = 0;
reservation.address_bits = 0;
@@ -1094,6 +1094,14 @@ static struct ethtool_ops network_ethtoo
.set_tx_csum = ethtool_op_set_tx_csum,
};

+/*
+ * Nothing to do here. Virtual interface is point-to-point and the
+ * physical interface is probably promiscuous anyway.
+ */
+static void network_set_multicast_list(struct net_device *dev)
+{
+}
+
/** Create a network device.
* @param handle device handle
* @param val return parameter for created device
@@ -1163,6 +1171,7 @@ static int create_netdev(int handle, str
netdev->stop = network_close;
netdev->get_stats = network_get_stats;
netdev->poll = netif_poll;
+ netdev->set_multicast_list = network_set_multicast_list;
netdev->uninit = netif_uninit;
netdev->weight = 64;
netdev->features = NETIF_F_IP_CSUM;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Mon May 08 14:46:11 2006 -0600
@@ -1,7 +1,10 @@ obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pcib
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback.o

pciback-y := pci_stub.o pciback_ops.o xenbus.o
-pciback-y += conf_space.o conf_space_header.o
+pciback-y += conf_space.o conf_space_header.o \
+ conf_space_capability.o \
+ conf_space_capability_vpd.o \
+ conf_space_capability_pm.o
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c Mon May 08 14:46:11 2006 -0600
@@ -17,10 +17,10 @@ static int permissive = 0;
static int permissive = 0;
module_param(permissive, bool, 0644);

-#define DEFINE_PCI_CONFIG(op,size,type) \
-int pciback_##op##_config_##size \
+#define DEFINE_PCI_CONFIG(op,size,type) \
+int pciback_##op##_config_##size \
(struct pci_dev *dev, int offset, type value, void *data) \
-{ \
+{ \
return pci_##op##_config_##size (dev, offset, value); \
}

@@ -175,8 +175,8 @@ int pciback_config_read(struct pci_dev *

req_start = offset;
req_end = offset + size;
- field_start = field->offset;
- field_end = field->offset + field->size;
+ field_start = OFFSET(cfg_entry);
+ field_end = OFFSET(cfg_entry) + field->size;

if ((req_start >= field_start && req_start < field_end)
|| (req_end > field_start && req_end <= field_end)) {
@@ -222,8 +222,8 @@ int pciback_config_write(struct pci_dev

req_start = offset;
req_end = offset + size;
- field_start = field->offset;
- field_end = field->offset + field->size;
+ field_start = OFFSET(cfg_entry);
+ field_end = OFFSET(cfg_entry) + field->size;

if ((req_start >= field_start && req_start < field_end)
|| (req_end > field_start && req_end <= field_end)) {
@@ -239,60 +239,99 @@ int pciback_config_write(struct pci_dev

err = conf_space_write(dev, cfg_entry, field_start,
tmp_val);
+
+ /* handled is set true here, but not every byte
+ * may have been written! Properly detecting if
+ * every byte is handled is unnecessary as the
+ * flag is used to detect devices that need
+ * special helpers to work correctly.
+ */
handled = 1;
}
}

- if (!handled && !err && permissive) {
- switch (size) {
- case 1:
- err = pci_write_config_byte(dev, offset, (u8)value);
- break;
- case 2:
- err = pci_write_config_word(dev, offset, (u16)value);
- break;
- case 4:
- err = pci_write_config_dword(dev, offset, (u32)value);
- break;
+ if (!handled && !err) {
+ /* By default, anything not specificially handled above is
+ * read-only. The permissive flag changes this behavior so
+ * that anything not specifically handled above is writable.
+ * This means that some fields may still be read-only because
+ * they have entries in the config_field list that intercept
+ * the write and do nothing. */
+ if (permissive) {
+ switch (size) {
+ case 1:
+ err = pci_write_config_byte(dev, offset,
+ (u8)value);
+ break;
+ case 2:
+ err = pci_write_config_word(dev, offset,
+ (u16)value);
+ break;
+ case 4:
+ err = pci_write_config_dword(dev, offset,
+ (u32)value);
+ break;
+ }
+ } else if (!dev_data->warned_on_write) {
+ dev_data->warned_on_write = 1;
+ dev_warn(&dev->dev, "Driver wrote to a read-only "
+ "configuration space field!\n");
+ dev_warn(&dev->dev, "Write at offset 0x%x size %d\n",
+ offset, size);
+ dev_warn(&dev->dev, "This may be harmless, but if\n");
+ dev_warn(&dev->dev, "you have problems with your "
+ "device:\n");
+ dev_warn(&dev->dev, "1) see the permissive "
+ "attribute in sysfs.\n");
+ dev_warn(&dev->dev, "2) report problems to the "
+ "xen-devel mailing list along\n");
+ dev_warn(&dev->dev, " with details of your device "
+ "obtained from lspci.\n");
}
}

return pcibios_err_to_errno(err);
}

-void pciback_config_reset(struct pci_dev *dev)
+void pciback_config_reset_dev(struct pci_dev *dev)
{
struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
struct config_field_entry *cfg_entry;
struct config_field *field;

+ dev_dbg(&dev->dev, "resetting virtual configuration space\n");
+
list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
field = cfg_entry->field;

if (field->reset)
- field->reset(dev, field->offset, cfg_entry->data);
- }
-}
-
-void pciback_config_free(struct pci_dev *dev)
+ field->reset(dev, OFFSET(cfg_entry), cfg_entry->data);
+ }
+}
+
+void pciback_config_free_dev(struct pci_dev *dev)
{
struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
struct config_field_entry *cfg_entry, *t;
struct config_field *field;

+ dev_dbg(&dev->dev, "free-ing virtual configuration space fields\n");
+
list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
list_del(&cfg_entry->list);

field = cfg_entry->field;

if (field->release)
- field->release(dev, field->offset, cfg_entry->data);
+ field->release(dev, OFFSET(cfg_entry), cfg_entry->data);

kfree(cfg_entry);
}
}

-int pciback_config_add_field(struct pci_dev *dev, struct config_field *field)
+int pciback_config_add_field_offset(struct pci_dev *dev,
+ struct config_field *field,
+ unsigned int offset)
{
int err = 0;
struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
@@ -307,9 +346,10 @@ int pciback_config_add_field(struct pci_

cfg_entry->data = NULL;
cfg_entry->field = field;
+ cfg_entry->base_offset = offset;

if (field->init) {
- tmp = field->init(dev, field->offset);
+ tmp = field->init(dev, OFFSET(cfg_entry));

if (IS_ERR(tmp)) {
err = PTR_ERR(tmp);
@@ -319,6 +359,8 @@ int pciback_config_add_field(struct pci_
cfg_entry->data = tmp;
}

+ dev_dbg(&dev->dev, "added config field at offset 0x%02x\n",
+ OFFSET(cfg_entry));
list_add_tail(&cfg_entry->list, &dev_data->config_fields);

out:
@@ -332,14 +374,30 @@ int pciback_config_add_field(struct pci_
* certain registers (like the base address registers (BARs) so that we can
* keep the client from manipulating them directly.
*/
-int pciback_config_init(struct pci_dev *dev)
+int pciback_config_init_dev(struct pci_dev *dev)
{
int err = 0;
struct pciback_dev_data *dev_data = pci_get_drvdata(dev);

+ dev_dbg(&dev->dev, "initializing virtual configuration space\n");
+
INIT_LIST_HEAD(&dev_data->config_fields);

err = pciback_config_header_add_fields(dev);
-
+ if (err)
+ goto out;
+
+ err = pciback_config_capability_add_fields(dev);
+
+ out:
return err;
}
+
+int pciback_config_init(void)
+{
+ int err;
+
+ err = pciback_config_capability_init();
+
+ return err;
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h Mon May 08 14:46:11 2006 -0600
@@ -8,7 +8,9 @@
#define __XEN_PCIBACK_CONF_SPACE_H__

#include <linux/list.h>
+#include <linux/err.h>

+/* conf_field_init can return an errno in a ptr with ERR_PTR() */
typedef void *(*conf_field_init) (struct pci_dev * dev, int offset);
typedef void (*conf_field_reset) (struct pci_dev * dev, int offset, void *data);
typedef void (*conf_field_free) (struct pci_dev * dev, int offset, void *data);
@@ -55,13 +57,25 @@ struct config_field_entry {
struct config_field_entry {
struct list_head list;
struct config_field *field;
+ unsigned int base_offset;
void *data;
};
+
+#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)

/* Add fields to a device - the add_fields macro expects to get a pointer to
* the first entry in an array (of which the ending is marked by size==0)
*/
-int pciback_config_add_field(struct pci_dev *dev, struct config_field *field);
+int pciback_config_add_field_offset(struct pci_dev *dev,
+ struct config_field *field,
+ unsigned int offset);
+
+static inline int pciback_config_add_field(struct pci_dev *dev,
+ struct config_field *field)
+{
+ return pciback_config_add_field_offset(dev, field, 0);
+}
+
static inline int pciback_config_add_fields(struct pci_dev *dev,
struct config_field *field)
{
@@ -74,11 +88,18 @@ static inline int pciback_config_add_fie
return err;
}

-/* Initializers which add fields to the virtual configuration space
- * ** We could add initializers to allow a guest domain to touch
- * the capability lists (for power management, the AGP bridge, etc.)
- */
-int pciback_config_header_add_fields(struct pci_dev *dev);
+static inline int pciback_config_add_fields_offset(struct pci_dev *dev,
+ struct config_field *field,
+ unsigned int offset)
+{
+ int i, err = 0;
+ for (i = 0; field[i].size != 0; i++) {
+ err = pciback_config_add_field_offset(dev, &field[i], offset);
+ if (err)
+ break;
+ }
+ return err;
+}

/* Read/Write the real configuration space */
int pciback_read_config_byte(struct pci_dev *dev, int offset, u8 * value,
@@ -94,4 +115,9 @@ int pciback_write_config_dword(struct pc
int pciback_write_config_dword(struct pci_dev *dev, int offset, u32 value,
void *data);

+int pciback_config_capability_init(void);
+
+int pciback_config_header_add_fields(struct pci_dev *dev);
+int pciback_config_capability_add_fields(struct pci_dev *dev);
+
#endif /* __XEN_PCIBACK_CONF_SPACE_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c Mon May 08 14:46:11 2006 -0600
@@ -169,29 +169,61 @@ static int interrupt_read(struct pci_dev
return 0;
}

-struct config_field header_common[] = {
+static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
+{
+ u8 cur_value;
+ int err;
+
+ err = pci_read_config_byte(dev, offset, &cur_value);
+ if (err)
+ goto out;
+
+ if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
+ || value == PCI_BIST_START)
+ err = pci_write_config_byte(dev, offset, value);
+
+ out:
+ return err;
+}
+
+static struct config_field header_common[] = {
{
.offset = PCI_COMMAND,
.size = 2,
.u.w.read = pciback_read_config_word,
.u.w.write = command_write,
- },
+ },
{
.offset = PCI_INTERRUPT_LINE,
.size = 1,
.u.b.read = interrupt_read,
- .u.b.write = NULL,
- },
+ },
+ {
+ .offset = PCI_INTERRUPT_PIN,
+ .size = 1,
+ .u.b.read = pciback_read_config_byte,
+ },
{
/* Any side effects of letting driver domain control cache line? */
.offset = PCI_CACHE_LINE_SIZE,
.size = 1,
.u.b.read = pciback_read_config_byte,
.u.b.write = pciback_write_config_byte,
- },
- {
- .size = 0,
- },
+ },
+ {
+ .offset = PCI_LATENCY_TIMER,
+ .size = 1,
+ .u.b.read = pciback_read_config_byte,
+ },
+ {
+ .offset = PCI_BIST,
+ .size = 1,
+ .u.b.read = pciback_read_config_byte,
+ .u.b.write = bist_write,
+ },
+ {
+ .size = 0,
+ },
};

#define CFG_FIELD_BAR(reg_offset) \
@@ -216,7 +248,7 @@ struct config_field header_common[] = {
.u.dw.write = rom_write, \
}

-struct config_field header_0[] = {
+static struct config_field header_0[] = {
CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
@@ -226,16 +258,16 @@ struct config_field header_0[] = {
CFG_FIELD_ROM(PCI_ROM_ADDRESS),
{
.size = 0,
- },
-};
-
-struct config_field header_1[] = {
+ },
+};
+
+static struct config_field header_1[] = {
CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
{
.size = 0,
- },
+ },
};

int pciback_config_header_add_fields(struct pci_dev *dev)
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Mon May 08 14:46:11 2006 -0600
@@ -76,7 +76,7 @@ static void pcistub_device_release(struc

/* Clean-up the device */
pciback_reset_device(psdev->dev);
- pciback_config_free(psdev->dev);
+ pciback_config_free_dev(psdev->dev);
kfree(pci_get_drvdata(psdev->dev));
pci_set_drvdata(psdev->dev, NULL);

@@ -180,7 +180,7 @@ void pcistub_put_pci_dev(struct pci_dev
* (so it's ready for the next domain)
*/
pciback_reset_device(found_psdev->dev);
- pciback_config_reset(found_psdev->dev);
+ pciback_config_reset_dev(found_psdev->dev);

spin_lock_irqsave(&found_psdev->lock, flags);
found_psdev->pdev = NULL;
@@ -235,7 +235,7 @@ static int __devinit pcistub_init_device
* would need to be called somewhere to free the memory allocated
* here and then to call kfree(pci_get_drvdata(psdev->dev)).
*/
- dev_data = kmalloc(sizeof(*dev_data), GFP_ATOMIC);
+ dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
if (!dev_data) {
err = -ENOMEM;
goto out;
@@ -243,7 +243,7 @@ static int __devinit pcistub_init_device
pci_set_drvdata(dev, dev_data);

dev_dbg(&dev->dev, "initializing config\n");
- err = pciback_config_init(dev);
+ err = pciback_config_init_dev(dev);
if (err)
goto out;

@@ -268,7 +268,7 @@ static int __devinit pcistub_init_device
return 0;

config_release:
- pciback_config_free(dev);
+ pciback_config_free_dev(dev);

out:
pci_set_drvdata(dev, NULL);
@@ -324,40 +324,31 @@ static int __devinit pcistub_seize(struc
{
struct pcistub_device *psdev;
unsigned long flags;
- int initialize_devices_copy;
int err = 0;

psdev = pcistub_device_alloc(dev);
if (!psdev)
return -ENOMEM;

- /* initialize_devices has to be accessed under a spin lock. But since
- * it can only change from 0 -> 1, if it's already 1, we don't have to
- * worry about it changing. That's why we can take a *copy* of
- * initialize_devices and wait till we're outside of the lock to
- * check if it's 1 (don't ever check if it's 0 outside of the lock)
- */
spin_lock_irqsave(&pcistub_devices_lock, flags);

- initialize_devices_copy = initialize_devices;
-
- if (!initialize_devices_copy) {
+ if (initialize_devices) {
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+ /* don't want irqs disabled when calling pcistub_init_device */
+ err = pcistub_init_device(psdev->dev);
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ if (!err)
+ list_add(&psdev->dev_list, &pcistub_devices);
+ } else {
dev_dbg(&dev->dev, "deferring initialization\n");
list_add(&psdev->dev_list, &seized_devices);
}

spin_unlock_irqrestore(&pcistub_devices_lock, flags);

- if (initialize_devices_copy) {
- /* don't want irqs disabled when calling pcistub_init_device */
- err = pcistub_init_device(psdev->dev);
- if (err)
- goto out;
-
- list_add(&psdev->dev_list, &pcistub_devices);
- }
-
- out:
if (err)
pcistub_device_put(psdev);

@@ -663,9 +654,13 @@ fs_initcall(pcistub_init);

static int __init pciback_init(void)
{
+ int err;
+
+ err = pciback_config_init();
+ if (err)
+ return err;
+
#ifdef MODULE
- int err;
-
err = pcistub_init();
if (err < 0)
return err;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h Mon May 08 14:46:11 2006 -0600
@@ -44,6 +44,7 @@ struct pciback_device {

struct pciback_dev_data {
struct list_head config_fields;
+ int warned_on_write;
};

/* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
@@ -58,9 +59,10 @@ void pciback_reset_device(struct pci_dev
void pciback_reset_device(struct pci_dev *pdev);

/* Access a virtual configuration space for a PCI device */
-int pciback_config_init(struct pci_dev *dev);
-void pciback_config_reset(struct pci_dev *dev);
-void pciback_config_free(struct pci_dev *dev);
+int pciback_config_init(void);
+int pciback_config_init_dev(struct pci_dev *dev);
+void pciback_config_reset_dev(struct pci_dev *dev);
+void pciback_config_free_dev(struct pci_dev *dev);
int pciback_config_read(struct pci_dev *dev, int offset, int size,
u32 * ret_val);
int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c Mon May 08 14:46:11 2006 -0600
@@ -36,8 +36,6 @@ void pciback_reset_device(struct pci_dev
dev->is_busmaster = 0;
}
}
-
- pciback_config_reset(dev);
}

static inline void test_and_schedule_op(struct pciback_device *pdev)
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon May 08 14:46:11 2006 -0600
@@ -6,6 +6,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/vmalloc.h>
#include <xen/xenbus.h>
#include <xen/evtchn.h>
#include "pciback.h"
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon May 08 14:46:11 2006 -0600
@@ -35,7 +35,7 @@ static struct proc_dir_entry *privcmd_in
static struct proc_dir_entry *privcmd_intf;
static struct proc_dir_entry *capabilities_intf;

-#define NR_HYPERCALLS 32
+#define NR_HYPERCALLS 64
static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);

static int privcmd_ioctl(struct inode *inode, struct file *file,
@@ -159,12 +159,14 @@ static int privcmd_ioctl(struct inode *i
break;

case IOCTL_PRIVCMD_MMAPBATCH: {
+#ifndef __ia64__
mmu_update_t u;
+ uint64_t ptep;
+#endif
privcmd_mmapbatch_t m;
struct vm_area_struct *vma = NULL;
unsigned long __user *p;
unsigned long addr, mfn;
- uint64_t ptep;
int i;

if (copy_from_user(&m, udata, sizeof(m))) {
@@ -199,11 +201,9 @@ static int privcmd_ioctl(struct inode *i
if (get_user(mfn, p))
return -EFAULT;
#ifdef __ia64__
- ret = remap_pfn_range(vma,
- addr&PAGE_MASK,
- mfn,
- 1<<PAGE_SHIFT,
- vma->vm_page_prot);
+ ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
+ mfn, 1 << PAGE_SHIFT,
+ vma->vm_page_prot, m.dom);
if (ret < 0)
goto batch_err;
#else
@@ -241,6 +241,7 @@ static int privcmd_ioctl(struct inode *i
return ret;
}

+#ifndef HAVE_ARCH_PRIVCMD_MMAP
static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
{
/* DONTCOPY is essential for Xen as copy_page_range is broken. */
@@ -248,6 +249,7 @@ static int privcmd_mmap(struct file * fi

return 0;
}
+#endif

static struct file_operations privcmd_file_ops = {
.ioctl = privcmd_ioctl,
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Mon May 08 14:46:11 2006 -0600
@@ -50,6 +50,8 @@ typedef struct tpmif_st {
grant_handle_t shmem_handle;
grant_ref_t shmem_ref;
struct page *pagerange;
+
+ char devname[20];
} tpmif_t;

void tpmif_disconnect_complete(tpmif_t * tpmif);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Mon May 08 14:46:11 2006 -0600
@@ -32,6 +32,7 @@ static tpmif_t *alloc_tpmif(domid_t domi
tpmif->domid = domid;
tpmif->status = DISCONNECTED;
tpmif->tpm_instance = instance;
+ snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
atomic_set(&tpmif->refcnt, 1);

tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
@@ -112,11 +113,7 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
{
int err;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = tpmif->domid,
- .u.bind_interdomain.remote_port = evtchn,
- };
+ struct evtchn_bind_interdomain bind_interdomain;

if (tpmif->irq) {
return 0;
@@ -131,19 +128,24 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
return err;
}

- err = HYPERVISOR_event_channel_op(&op);
+
+ bind_interdomain.remote_dom = tpmif->domid;
+ bind_interdomain.remote_port = evtchn;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err) {
unmap_frontend_page(tpmif);
free_vm_area(tpmif->tx_area);
return err;
}

- tpmif->evtchn = op.u.bind_interdomain.local_port;
+ tpmif->evtchn = bind_interdomain.local_port;

tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;

tpmif->irq = bind_evtchn_to_irqhandler(
- tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
+ tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
tpmif->shmem_ref = shared_page;
tpmif->active = 1;

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Mon May 08 14:46:11 2006 -0600
@@ -28,7 +28,8 @@ struct data_exchange {
struct list_head pending_pak;
struct list_head current_pak;
unsigned int copied_so_far;
- u8 has_opener;
+ u8 has_opener:1;
+ u8 aborted:1;
rwlock_t pak_lock; // protects all of the previous fields
wait_queue_head_t wait_queue;
};
@@ -101,6 +102,16 @@ static inline int copy_to_buffer(void *t
return 0;
}

+
+static void dataex_init(struct data_exchange *dataex)
+{
+ INIT_LIST_HEAD(&dataex->pending_pak);
+ INIT_LIST_HEAD(&dataex->current_pak);
+ dataex->has_opener = 0;
+ rwlock_init(&dataex->pak_lock);
+ init_waitqueue_head(&dataex->wait_queue);
+}
+
/***************************************************************
Packet-related functions
***************************************************************/
@@ -148,11 +159,12 @@ static struct packet *packet_alloc(tpmif
u32 size, u8 req_tag, u8 flags)
{
struct packet *pak = NULL;
- pak = kzalloc(sizeof (struct packet), GFP_KERNEL);
+ pak = kzalloc(sizeof (struct packet), GFP_ATOMIC);
if (NULL != pak) {
if (tpmif) {
pak->tpmif = tpmif;
pak->tpm_instance = tpmif->tpm_instance;
+ tpmif_get(tpmif);
}
pak->data_len = size;
pak->req_tag = req_tag;
@@ -180,6 +192,9 @@ static void packet_free(struct packet *p
if (timer_pending(&pak->processing_timer)) {
BUG();
}
+
+ if (pak->tpmif)
+ tpmif_put(pak->tpmif);
kfree(pak->data_buffer);
/*
* cannot do tpmif_put(pak->tpmif); bad things happen
@@ -271,7 +286,6 @@ int _packet_write(struct packet *pak,
struct gnttab_map_grant_ref map_op;
struct gnttab_unmap_grant_ref unmap_op;
tpmif_tx_request_t *tx;
- unsigned long pfn, mfn, mfn_orig;

tx = &tpmif->tx->ring[i].req;

@@ -294,12 +308,6 @@ int _packet_write(struct packet *pak,
DPRINTK(" Grant table operation failure !\n");
return 0;
}
-
- pfn = __pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT;
- mfn = FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
- mfn_orig = phys_to_machine_mapping[pfn];
-
- set_phys_to_machine(pfn, mfn);

tocopy = MIN(size - offset, PAGE_SIZE);

@@ -310,8 +318,6 @@ int _packet_write(struct packet *pak,
return -EFAULT;
}
tx->size = tocopy;
-
- set_phys_to_machine(pfn, mfn_orig);

gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
GNTMAP_host_map, handle);
@@ -514,27 +520,41 @@ static ssize_t vtpm_op_read(struct file
unsigned long flags;

write_lock_irqsave(&dataex.pak_lock, flags);
+ if (dataex.aborted) {
+ dataex.aborted = 0;
+ dataex.copied_so_far = 0;
+ write_unlock_irqrestore(&dataex.pak_lock, flags);
+ return -EIO;
+ }

if (list_empty(&dataex.pending_pak)) {
write_unlock_irqrestore(&dataex.pak_lock, flags);
wait_event_interruptible(dataex.wait_queue,
!list_empty(&dataex.pending_pak));
write_lock_irqsave(&dataex.pak_lock, flags);
+ dataex.copied_so_far = 0;
}

if (!list_empty(&dataex.pending_pak)) {
unsigned int left;
+
pak = list_entry(dataex.pending_pak.next, struct packet, next);
-
left = pak->data_len - dataex.copied_so_far;
+ list_del(&pak->next);
+ write_unlock_irqrestore(&dataex.pak_lock, flags);

DPRINTK("size given by app: %d, available: %d\n", size, left);

ret_size = MIN(size, left);

ret_size = packet_read(pak, ret_size, data, size, 1);
+
+ write_lock_irqsave(&dataex.pak_lock, flags);
+
if (ret_size < 0) {
- ret_size = -EFAULT;
+ del_singleshot_timer_sync(&pak->processing_timer);
+ packet_free(pak);
+ dataex.copied_so_far = 0;
} else {
DPRINTK("Copied %d bytes to user buffer\n", ret_size);

@@ -545,7 +565,6 @@ static ssize_t vtpm_op_read(struct file

del_singleshot_timer_sync(&pak->
processing_timer);
- list_del(&pak->next);
list_add_tail(&pak->next, &dataex.current_pak);
/*
* The more fontends that are handled at the same time,
@@ -554,6 +573,8 @@ static ssize_t vtpm_op_read(struct file
mod_timer(&pak->processing_timer,
jiffies + (num_frontends * 60 * HZ));
dataex.copied_so_far = 0;
+ } else {
+ list_add(&pak->next, &dataex.pending_pak);
}
}
}
@@ -601,8 +622,8 @@ static ssize_t vtpm_op_write(struct file

if (pak == NULL) {
write_unlock_irqrestore(&dataex.pak_lock, flags);
- printk(KERN_ALERT "No associated packet! (inst=%d)\n",
- ntohl(vrh.instance_no));
+ DPRINTK(KERN_ALERT "No associated packet! (inst=%d)\n",
+ ntohl(vrh.instance_no));
return -EFAULT;
}

@@ -784,15 +805,17 @@ static int tpm_send_fail_message(struct
return rc;
}

-static void _vtpm_release_packets(struct list_head *head,
- tpmif_t * tpmif, int send_msgs)
-{
+static int _vtpm_release_packets(struct list_head *head,
+ tpmif_t * tpmif, int send_msgs)
+{
+ int aborted = 0;
+ int c = 0;
struct packet *pak;
- struct list_head *pos,
- *tmp;
+ struct list_head *pos, *tmp;

list_for_each_safe(pos, tmp, head) {
pak = list_entry(pos, struct packet, next);
+ c += 1;

if (tpmif == NULL || pak->tpmif == tpmif) {
int can_send = 0;
@@ -808,8 +831,11 @@ static void _vtpm_release_packets(struct
tpm_send_fail_message(pak, pak->req_tag);
}
packet_free(pak);
- }
- }
+ if (c == 1)
+ aborted = 1;
+ }
+ }
+ return aborted;
}

int vtpm_release_packets(tpmif_t * tpmif, int send_msgs)
@@ -818,7 +844,9 @@ int vtpm_release_packets(tpmif_t * tpmif

write_lock_irqsave(&dataex.pak_lock, flags);

- _vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
+ dataex.aborted = _vtpm_release_packets(&dataex.pending_pak,
+ tpmif,
+ send_msgs);
_vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);

write_unlock_irqrestore(&dataex.pak_lock, flags);
@@ -1020,11 +1048,7 @@ static int __init tpmback_init(void)
return rc;
}

- INIT_LIST_HEAD(&dataex.pending_pak);
- INIT_LIST_HEAD(&dataex.current_pak);
- dataex.has_opener = 0;
- rwlock_init(&dataex.pak_lock);
- init_waitqueue_head(&dataex.wait_queue);
+ dataex_init(&dataex);

spin_lock_init(&tpm_schedule_list_lock);
INIT_LIST_HEAD(&tpm_schedule_list);
@@ -1041,6 +1065,7 @@ module_init(tpmback_init);

static void __exit tpmback_exit(void)
{
+ vtpm_release_packets(NULL, 0);
tpmif_xenbus_exit();
tpmif_interface_exit();
misc_deregister(&vtpms_miscdevice);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Mon May 08 14:46:11 2006 -0600
@@ -132,6 +132,7 @@ int xenbus_unmap_ring(struct xenbus_devi
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring);

+MODULE_LICENSE("Dual BSD/GPL");

/*
* Local variables:
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon May 08 14:46:11 2006 -0600
@@ -214,16 +214,19 @@ EXPORT_SYMBOL_GPL(xenbus_grant_ring);

int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_alloc_unbound,
- .u.alloc_unbound.dom = DOMID_SELF,
- .u.alloc_unbound.remote_dom = dev->otherend_id
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_alloc_unbound alloc_unbound;
+ int err;
+
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = dev->otherend_id;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (err)
xenbus_dev_fatal(dev, err, "allocating event channel");
else
- *port = op.u.alloc_unbound.port;
+ *port = alloc_unbound.port;
+
return err;
}
EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
@@ -231,18 +234,21 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);

int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_bind_interdomain,
- .u.bind_interdomain.remote_dom = dev->otherend_id,
- .u.bind_interdomain.remote_port = remote_port,
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_bind_interdomain bind_interdomain;
+ int err;
+
+ bind_interdomain.remote_dom = dev->otherend_id;
+ bind_interdomain.remote_port = remote_port,
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
if (err)
xenbus_dev_fatal(dev, err,
"binding to event channel %d from domain %d",
remote_port, dev->otherend_id);
else
- *port = op.u.bind_interdomain.local_port;
+ *port = bind_interdomain.local_port;
+
return err;
}
EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
@@ -250,13 +256,15 @@ EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);

int xenbus_free_evtchn(struct xenbus_device *dev, int port)
{
- evtchn_op_t op = {
- .cmd = EVTCHNOP_close,
- .u.close.port = port,
- };
- int err = HYPERVISOR_event_channel_op(&op);
+ struct evtchn_close close;
+ int err;
+
+ close.port = port;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
if (err)
xenbus_dev_error(dev, err, "freeing event channel %d", port);
+
return err;
}

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon May 08 14:46:11 2006 -0600
@@ -981,7 +981,7 @@ static int __init xenbus_probe_init(void
dom0 = (xen_start_info->store_evtchn == 0);

if (dom0) {
- evtchn_op_t op = { 0 };
+ struct evtchn_alloc_unbound alloc_unbound;

/* Allocate page. */
page = get_zeroed_page(GFP_KERNEL);
@@ -993,15 +993,15 @@ static int __init xenbus_probe_init(void
PAGE_SHIFT);

/* Next allocate a local port which xenstored can bind to */
- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = 0;
-
- err = HYPERVISOR_event_channel_op(&op);
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = 0;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
if (err == -ENOSYS)
goto err;
BUG_ON(err);
- xen_start_info->store_evtchn = op.u.alloc_unbound.port;
+ xen_start_info->store_evtchn = alloc_unbound.port;

/* And finally publish the above info in /proc/xen */
xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
@@ -1069,6 +1069,11 @@ static int __init wait_for_devices(void)
{
unsigned long timeout = jiffies + 10*HZ;

+ if (xen_init() < 0) {
+ DPRINTK("failed");
+ return -ENODEV;
+ }
+
while (time_before(jiffies, timeout)) {
if (all_devices_ready())
return 0;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon May 08 14:46:11 2006 -0600
@@ -183,7 +183,7 @@ void *xenbus_dev_request_and_reply(struc

mutex_unlock(&xs_state.request_mutex);

- if ((msg->type == XS_TRANSACTION_END) ||
+ if ((req_msg.type == XS_TRANSACTION_END) ||
((req_msg.type == XS_TRANSACTION_START) &&
(msg->type == XS_ERROR)))
up_read(&xs_state.suspend_mutex);
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -33,6 +33,8 @@
#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__

+#include <linux/string.h> /* memcpy() */
+
#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
#endif
@@ -245,9 +247,16 @@ HYPERVISOR_update_va_mapping(

static inline int
HYPERVISOR_event_channel_op(
- void *op)
-{
- return _hypercall1(int, event_channel_op, op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}

static inline int
@@ -266,9 +275,16 @@ HYPERVISOR_console_io(

static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
-{
- return _hypercall1(int, physdev_op, physdev_op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}

static inline int
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Mon May 08 14:46:11 2006 -0600
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <xen/interface/nmi.h>
#include <asm/ptrace.h>
@@ -162,14 +164,14 @@ HYPERVISOR_poll(
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
+ int rc;
struct sched_poll sched_poll = {
- .ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
-
- int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
-
+ set_xen_guest_handle(sched_poll.ports, ports);
+
+ rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h Mon May 08 14:46:11 2006 -0600
@@ -32,6 +32,9 @@
#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)

#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
+
+#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)

#define ptep_get_and_clear(mm,addr,xp) __pte_ma(xchg(&(xp)->pte_low, 0))
#define pte_same(a, b) ((a).pte_low == (b).pte_low)
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h Mon May 08 14:46:11 2006 -0600
@@ -107,6 +107,20 @@ static inline void pud_clear (pud_t * pu
#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
pmd_index(address))

+/*
+ * For PTEs and PDEs, we must clear the P-bit first when clearing a page table
+ * entry, so clear the bottom half first and enforce ordering with a compiler
+ * barrier.
+ */
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ ptep->pte_low = 0;
+ smp_wmb();
+ ptep->pte_high = 0;
+}
+
+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
+
static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t res;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Mon May 08 14:46:11 2006 -0600
@@ -205,14 +205,12 @@ extern unsigned long pg0[];
extern unsigned long pg0[];

#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
-#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)

/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
#define pmd_none(x) (!(unsigned long)pmd_val(x))
/* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
can temporarily clear it. */
#define pmd_present(x) (pmd_val(x))
-#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))


@@ -272,16 +270,7 @@ static inline pte_t ptep_get_and_clear_f
pte_t pte;
if (full) {
pte = *ptep;
-#ifdef CONFIG_X86_PAE
- /* Cannot do this in a single step, as the compiler may
- issue the two stores in either order, but the hypervisor
- must not see the high part before the low one. */
- ptep->pte_low = 0;
- barrier();
- ptep->pte_high = 0;
-#else
- *ptep = __pte(0);
-#endif
+ pte_clear(mm, addr, ptep);
} else {
pte = ptep_get_and_clear(mm, addr, ptep);
}
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Mon May 08 14:46:11 2006 -0600
@@ -534,12 +534,11 @@ static inline void __load_esp0(struct ts
*/
static inline void set_iopl_mask(unsigned mask)
{
- physdev_op_t op;
+ struct physdev_set_iopl set_iopl;

/* Force the change at ring 0. */
- op.cmd = PHYSDEVOP_SET_IOPL;
- op.u.set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
- HYPERVISOR_physdev_op(&op);
+ set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
}

/* Forward declaration, a strange C thing */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -32,6 +32,8 @@

#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__
+
+#include <linux/string.h> /* memcpy() */

#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
@@ -202,9 +204,16 @@ HYPERVISOR_memory_op(

static inline int
HYPERVISOR_event_channel_op(
- void *op)
-{
- return _hypercall1(int, event_channel_op, op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}

static inline int
@@ -223,9 +232,16 @@ HYPERVISOR_console_io(

static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
-{
- return _hypercall1(int, physdev_op, physdev_op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}

static inline int
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Mon May 08 14:46:11 2006 -0600
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <asm/hypercall.h>
#include <asm/ptrace.h>
@@ -101,13 +103,14 @@ HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
struct sched_poll sched_poll = {
- .ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};

- int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
+ int rc;

+ set_xen_guest_handle(sched_poll.ports, ports);
+ rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);

@@ -131,7 +134,6 @@ HYPERVISOR_poll(
#define pte_mfn(_x) pte_pfn(_x)
#define __pte_ma(_x) ((pte_t) {(_x)})
#define phys_to_machine_mapping_valid(_x) (1)
-#define kmap_flush_unused() do {} while (0)
#define pfn_pte_ma(_x,_y) __pte_ma(0)
#ifndef CONFIG_XEN_IA64_DOM0_VP //XXX
#define set_phys_to_machine(_x,_y) do {} while (0)
diff -r 707737b66f58 -r 5d9eb92e63e2 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 Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -37,6 +37,8 @@
#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__

+#include <linux/string.h> /* memcpy() */
+
#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
#endif
@@ -243,9 +245,16 @@ HYPERVISOR_update_va_mapping(

static inline int
HYPERVISOR_event_channel_op(
- void *op)
-{
- return _hypercall1(int, event_channel_op, op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, event_channel_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct evtchn_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+ }
+ return rc;
}

static inline int
@@ -264,9 +273,16 @@ HYPERVISOR_console_io(

static inline int
HYPERVISOR_physdev_op(
- void *physdev_op)
-{
- return _hypercall1(int, physdev_op, physdev_op);
+ int cmd, void *arg)
+{
+ int rc = _hypercall2(int, physdev_op, cmd, arg);
+ if (unlikely(rc == -ENOSYS)) {
+ struct physdev_op op;
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+ }
+ return rc;
}

static inline int
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/linux/mm.h
--- a/linux-2.6-xen-sparse/include/linux/mm.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/linux/mm.h Mon May 08 14:46:11 2006 -0600
@@ -232,10 +232,9 @@ struct page {
unsigned long private; /* Mapping-private opaque data:
* usually used for buffer_heads
* if PagePrivate set; used for
- * swp_entry_t if PageSwapCache.
- * When page is free, this
+ * swp_entry_t if PageSwapCache;
* indicates order in the buddy
- * system.
+ * system if PG_buddy is set.
*/
struct address_space *mapping; /* If low bit clear, points to
* inode address_space, or NULL.
@@ -247,9 +246,6 @@ struct page {
};
#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
spinlock_t ptl;
-#endif
-#ifdef CONFIG_XEN
- struct list_head ballooned;
#endif
};
pgoff_t index; /* Our offset within mapping. */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/evtchn.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/evtchn.h Mon May 08 14:46:11 2006 -0600
@@ -101,10 +101,8 @@ static inline void clear_evtchn(int port

static inline void notify_remote_via_evtchn(int port)
{
- evtchn_op_t op;
- op.cmd = EVTCHNOP_send,
- op.u.send.port = port;
- (void)HYPERVISOR_event_channel_op(&op);
+ struct evtchn_send send = { .port = port };
+ (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
}

/*
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/xen/public/privcmd.h
--- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h Mon May 08 14:46:11 2006 -0600
@@ -62,13 +62,6 @@ typedef struct privcmd_mmapbatch {
unsigned long __user *arr; /* array of mfns - top nibble set on err */
} privcmd_mmapbatch_t;

-typedef struct privcmd_blkmsg
-{
- unsigned long op;
- void *buf;
- int buf_size;
-} privcmd_blkmsg_t;
-
/*
* @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/lib/Makefile
--- a/linux-2.6-xen-sparse/lib/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/lib/Makefile Mon May 08 14:46:11 2006 -0600
@@ -45,7 +45,7 @@ obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o

obj-$(CONFIG_SWIOTLB) += swiotlb.o
-ifneq ($(CONFIG_IA64),y)
+ifneq ($(CONFIG_XEN_IA64_DOM0_NON_VP),y)
swiotlb-$(CONFIG_XEN) := ../arch/i386/kernel/swiotlb.o
endif

diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/mm/Kconfig
--- a/linux-2.6-xen-sparse/mm/Kconfig Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/Kconfig Mon May 08 14:46:11 2006 -0600
@@ -126,14 +126,14 @@ comment "Memory hotplug is currently inc
# 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 uses the mapping field on pagetable pages to store a pointer to
-# the destructor.
+# 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 XEN
+ default "4096" if X86_XEN || X86_64_XEN
default "4"

#
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/memory.c Mon May 08 14:46:11 2006 -0600
@@ -968,6 +968,7 @@ int get_user_pages(struct task_struct *t
{
int i;
unsigned int vm_flags;
+ int xenpage = 0;

/*
* Require read or write permissions.
@@ -1025,10 +1026,14 @@ int get_user_pages(struct task_struct *t
if (vma && (vma->vm_flags & VM_FOREIGN)) {
struct page **map = vma->vm_private_data;
int offset = (start - vma->vm_start) >> PAGE_SHIFT;
-
+ xenpage =1;
if (map[offset] != NULL) {
- if (pages)
- pages[i] = map[offset];
+ if (pages) {
+ struct page *page = map[offset];
+
+ pages[i] = page;
+ get_page(page);
+ }
if (vmas)
vmas[i] = vma;
i++;
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/mm/page_alloc.c
--- a/linux-2.6-xen-sparse/mm/page_alloc.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/page_alloc.c Mon May 08 14:46:11 2006 -0600
@@ -153,7 +153,8 @@ static void bad_page(struct page *page)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback );
+ 1 << PG_writeback |
+ 1 << PG_buddy );
set_page_count(page, 0);
reset_page_mapcount(page);
page->mapping = NULL;
@@ -224,12 +225,12 @@ static inline unsigned long page_order(s

static inline void set_page_order(struct page *page, int order) {
set_page_private(page, order);
- __SetPagePrivate(page);
+ __SetPageBuddy(page);
}

static inline void rmv_page_order(struct page *page)
{
- __ClearPagePrivate(page);
+ __ClearPageBuddy(page);
set_page_private(page, 0);
}

@@ -268,11 +269,13 @@ __find_combined_index(unsigned long page
* This function checks whether a page is free && is the buddy
* we can do coalesce a page and its buddy if
* (a) the buddy is not in a hole &&
- * (b) the buddy is free &&
- * (c) the buddy is on the buddy system &&
- * (d) a page and its buddy have the same order.
- * for recording page's order, we use page_private(page) and PG_private.
- *
+ * (b) the buddy is in the buddy system &&
+ * (c) a page and its buddy have the same order.
+ *
+ * For recording whether a page is in the buddy system, we use PG_buddy.
+ * Setting, clearing, and testing PG_buddy is serialized by zone->lock.
+ *
+ * For recording page's order, we use page_private(page).
*/
static inline int page_is_buddy(struct page *page, int order)
{
@@ -281,10 +284,10 @@ static inline int page_is_buddy(struct p
return 0;
#endif

- if (PagePrivate(page) &&
- (page_order(page) == order) &&
- page_count(page) == 0)
+ if (PageBuddy(page) && page_order(page) == order) {
+ BUG_ON(page_count(page) != 0);
return 1;
+ }
return 0;
}

@@ -301,7 +304,7 @@ static inline int page_is_buddy(struct p
* as necessary, plus some accounting needed to play nicely with other
* parts of the VM system.
* At each level, we keep a list of pages, which are heads of continuous
- * free pages of length of (1 << order) and marked with PG_Private.Page's
+ * free pages of length of (1 << order) and marked with PG_buddy. Page's
* order is recorded in page_private(page) field.
* So when we are allocating or freeing one, we can derive the state of the
* other. That is, if we allocate a small block, and both were
@@ -364,7 +367,8 @@ static inline int free_pages_check(struc
1 << PG_slab |
1 << PG_swapcache |
1 << PG_writeback |
- 1 << PG_reserved ))))
+ 1 << PG_reserved |
+ 1 << PG_buddy ))))
bad_page(page);
if (PageDirty(page))
__ClearPageDirty(page);
@@ -523,7 +527,8 @@ static int prep_new_page(struct page *pa
1 << PG_slab |
1 << PG_swapcache |
1 << PG_writeback |
- 1 << PG_reserved ))))
+ 1 << PG_reserved |
+ 1 << PG_buddy ))))
bad_page(page);

/*
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/dev.c Mon May 08 14:46:11 2006 -0600
@@ -2994,11 +2994,11 @@ void netdev_run_todo(void)

switch(dev->reg_state) {
case NETREG_REGISTERING:
+ dev->reg_state = NETREG_REGISTERED;
err = netdev_register_sysfs(dev);
if (err)
printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
dev->name, err);
- dev->reg_state = NETREG_REGISTERED;
break;

case NETREG_UNREGISTERING:
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/scripts/Makefile.xen
--- a/linux-2.6-xen-sparse/scripts/Makefile.xen Mon May 08 13:41:18 2006 -0600
+++ b/linux-2.6-xen-sparse/scripts/Makefile.xen Mon May 08 14:46:11 2006 -0600
@@ -2,9 +2,9 @@
# cherrypickxen($1 = allobj)
cherrypickxen = $(foreach var, $(1), \
$(shell o=$(var); \
- c=$${o/%.o/-xen.c}; \
- s=$${o/%.o/-xen.S}; \
- oxen=$${o/%.o/-xen.o}; \
+ c=$${o%.o}-xen.c; \
+ s=$${o%.o}-xen.S; \
+ oxen=$${o%.o}-xen.o; \
[ -f $(srctree)/$(src)/$${c} ] || \
[ -f $(srctree)/$(src)/$${s} ] \
&& echo $$oxen \
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/Rules.mk
--- a/tools/Rules.mk Mon May 08 13:41:18 2006 -0600
+++ b/tools/Rules.mk Mon May 08 14:46:11 2006 -0600
@@ -12,7 +12,7 @@ XEN_LIBXENSTAT = $(XEN_ROOT)/tools/x

X11_LDPATH = -L/usr/X11R6/$(LIBDIR)

-CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030101
+CFLAGS += -D__XEN_TOOLS__

%.opic: %.c
$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
@@ -23,15 +23,23 @@ CFLAGS += -D__XEN_INTERFACE_VERSION__=0x
%.o: %.cc
$(CC) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

-.PHONY: mk-symlinks
-mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
-mk-symlinks:
+OS = $(shell uname -s)
+
+.PHONY: mk-symlinks mk-symlinks-xen mk-symlinks-$(OS)
+
+mk-symlinks-Linux: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
+mk-symlinks-Linux:
+ mkdir -p xen/linux
+ ( cd xen/linux && \
+ ln -sf ../../$(LINUX_ROOT)/include/xen/public/*.h . )
+ ( cd xen && rm -f sys && ln -sf linux sys )
+
+mk-symlinks-xen:
mkdir -p xen
( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
mkdir -p xen/hvm
( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
mkdir -p xen/io
( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
- mkdir -p xen/linux
- ( cd xen/linux && \
- ln -sf ../../$(LINUX_ROOT)/include/xen/public/*.h . )
+
+mk-symlinks: mk-symlinks-xen mk-symlinks-$(OS)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/debugger/pdb/pdb_caml_process.c
--- a/tools/debugger/pdb/pdb_caml_process.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/debugger/pdb/pdb_caml_process.c Mon May 08 14:46:11 2006 -0600
@@ -18,7 +18,6 @@
#include <xenctrl.h>
#include <xen/xen.h>
#include <xen/io/domain_controller.h>
-#include <xen/linux/privcmd.h>
#include "pdb_module.h"
#include "pdb_caml_xen.h"

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/debugger/pdb/pdb_caml_xcs.c
--- a/tools/debugger/pdb/pdb_caml_xcs.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/debugger/pdb/pdb_caml_xcs.c Mon May 08 14:46:11 2006 -0600
@@ -21,7 +21,6 @@

#include <xen/xen.h>
#include <xen/io/domain_controller.h>
-#include <xen/linux/privcmd.h>

#include <arpa/inet.h>
#include <xcs_proto.h>
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/examples/network-bridge
--- a/tools/examples/network-bridge Mon May 08 13:41:18 2006 -0600
+++ b/tools/examples/network-bridge Mon May 08 14:46:11 2006 -0600
@@ -59,9 +59,8 @@ findCommand "$@"
findCommand "$@"
evalVariables "$@"

-vifnum=${vifnum:-0}
+vifnum=${vifnum:-$(ip route list | awk '/^default / { sub(/eth/,"",$NF); print $NF }')}
bridge=${bridge:-xenbr${vifnum}}
-netdev=${netdev:-$(ip route list default scope global| awk '{ print $NF }')}
netdev=${netdev:-eth${vifnum}}
antispoof=${antispoof:-no}

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/ioemu/configure
--- a/tools/ioemu/configure Mon May 08 13:41:18 2006 -0600
+++ b/tools/ioemu/configure Mon May 08 14:46:11 2006 -0600
@@ -230,7 +230,7 @@ fi

if test -z "$vnc"; then

-if libvncserver-config --version >& /dev/null; then
+if libvncserver-config --version > /dev/null 2>&1; then
vnc=yes
else
vnc=no
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/ioemu/hw/pc.c Mon May 08 14:46:11 2006 -0600
@@ -166,14 +166,20 @@ static void cmos_init(uint64_t ram_size,
switch(boot_device) {
case 'a':
case 'b':
- rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
+ //rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
+ rtc_set_memory(s, 0x3d, 0x21); /* a->c->d */
+ rtc_set_memory(s, 0x38, 0x30);
break;
default:
case 'c':
- rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
+ //rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
+ rtc_set_memory(s, 0x3d, 0x32); /* c->d->a */
+ rtc_set_memory(s, 0x38, 0x10);
break;
case 'd':
- rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
+ //rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
+ rtc_set_memory(s, 0x3d, 0x23); /* d->c->a */
+ rtc_set_memory(s, 0x38, 0x10);
break;
}

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/Makefile
--- a/tools/libxc/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/Makefile Mon May 08 14:46:11 2006 -0600
@@ -16,6 +16,7 @@ SRCS += xc_domain.c
SRCS += xc_domain.c
SRCS += xc_evtchn.c
SRCS += xc_misc.c
+SRCS += xc_acm.c
SRCS += xc_physdev.c
SRCS += xc_private.c
SRCS += xc_sedf.c
@@ -26,6 +27,10 @@ SRCS += xc_ptrace_core.c
SRCS += xc_ptrace_core.c
SRCS += xc_pagetab.c
endif
+
+SRCS_Linux += xc_linux.c
+
+SRCS += $(SRCS_Linux)

BUILD_SRCS :=
BUILD_SRCS += xc_linux_build.c
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_domain.c Mon May 08 14:46:11 2006 -0600
@@ -171,7 +171,7 @@ int xc_domain_getinfolist(int xc_handle,
op.cmd = DOM0_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = first_domain;
op.u.getdomaininfolist.max_domains = max_domains;
- op.u.getdomaininfolist.buffer = info;
+ set_xen_guest_handle(op.u.getdomaininfolist.buffer, info);

if ( xc_dom0_op(xc_handle, &op) < 0 )
ret = -1;
@@ -195,7 +195,7 @@ int xc_vcpu_getcontext(int xc_handle,
op.cmd = DOM0_GETVCPUCONTEXT;
op.u.getvcpucontext.domain = (domid_t)domid;
op.u.getvcpucontext.vcpu = (uint16_t)vcpu;
- op.u.getvcpucontext.ctxt = ctxt;
+ set_xen_guest_handle(op.u.getvcpucontext.ctxt, ctxt);

if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
return rc;
@@ -220,7 +220,7 @@ int xc_shadow_control(int xc_handle,
op.cmd = DOM0_SHADOW_CONTROL;
op.u.shadow_control.domain = (domid_t)domid;
op.u.shadow_control.op = sop;
- op.u.shadow_control.dirty_bitmap = dirty_bitmap;
+ set_xen_guest_handle(op.u.shadow_control.dirty_bitmap, dirty_bitmap);
op.u.shadow_control.pages = pages;

rc = do_dom0_op(xc_handle, &op);
@@ -295,13 +295,15 @@ int xc_domain_memory_increase_reservatio
{
int err;
struct xen_memory_reservation reservation = {
- .extent_start = extent_start, /* may be NULL */
.nr_extents = nr_extents,
.extent_order = extent_order,
.address_bits = address_bits,
.domid = domid
};

+ /* may be NULL */
+ set_xen_guest_handle(reservation.extent_start, extent_start);
+
err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
if ( err == nr_extents )
return 0;
@@ -326,12 +328,13 @@ int xc_domain_memory_decrease_reservatio
{
int err;
struct xen_memory_reservation reservation = {
- .extent_start = extent_start,
.nr_extents = nr_extents,
.extent_order = extent_order,
.address_bits = 0,
.domid = domid
};
+
+ set_xen_guest_handle(reservation.extent_start, extent_start);

if ( extent_start == NULL )
{
@@ -364,12 +367,12 @@ int xc_domain_memory_populate_physmap(in
{
int err;
struct xen_memory_reservation reservation = {
- .extent_start = extent_start,
.nr_extents = nr_extents,
.extent_order = extent_order,
.address_bits = address_bits,
.domid = domid
};
+ set_xen_guest_handle(reservation.extent_start, extent_start);

err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
if ( err == nr_extents )
@@ -395,9 +398,9 @@ int xc_domain_translate_gpfn_list(int xc
struct xen_translate_gpfn_list op = {
.domid = domid,
.nr_gpfns = nr_gpfns,
- .gpfn_list = gpfn_list,
- .mfn_list = mfn_list
};
+ set_xen_guest_handle(op.gpfn_list, gpfn_list);
+ set_xen_guest_handle(op.mfn_list, mfn_list);

return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op);
}
@@ -467,7 +470,7 @@ int xc_vcpu_setcontext(int xc_handle,
op.cmd = DOM0_SETVCPUCONTEXT;
op.u.setvcpucontext.domain = domid;
op.u.setvcpucontext.vcpu = vcpu;
- op.u.setvcpucontext.ctxt = ctxt;
+ set_xen_guest_handle(op.u.setvcpucontext.ctxt, ctxt);

if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
return rc;
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_evtchn.c Mon May 08 14:46:11 2006 -0600
@@ -9,24 +9,25 @@
#include "xc_private.h"


-static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
+static int do_evtchn_op(int xc_handle, int cmd, void *arg, size_t arg_size)
{
int ret = -1;
DECLARE_HYPERCALL;

hypercall.op = __HYPERVISOR_event_channel_op;
- hypercall.arg[0] = (unsigned long)op;
+ hypercall.arg[0] = cmd;
+ hypercall.arg[1] = (unsigned long)arg;

- if ( mlock(op, sizeof(*op)) != 0 )
+ if ( mlock(arg, arg_size) != 0 )
{
- PERROR("do_evtchn_op: op mlock failed");
+ PERROR("do_evtchn_op: arg mlock failed");
goto out;
}

if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);

- safe_munlock(op, sizeof(*op));
+ safe_munlock(arg, arg_size);
out:
return ret;
}
@@ -37,13 +38,14 @@ int xc_evtchn_alloc_unbound(int xc_handl
uint32_t remote_dom)
{
int rc;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_alloc_unbound,
- .u.alloc_unbound.dom = (domid_t)dom,
- .u.alloc_unbound.remote_dom = (domid_t)remote_dom };
+ struct evtchn_alloc_unbound arg = {
+ .dom = (domid_t)dom,
+ .remote_dom = (domid_t)remote_dom
+ };

- if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
- rc = op.u.alloc_unbound.port;
+ rc = do_evtchn_op(xc_handle, EVTCHNOP_alloc_unbound, &arg, sizeof(arg));
+ if ( rc == 0 )
+ rc = arg.port;

return rc;
}
@@ -54,14 +56,7 @@ int xc_evtchn_status(int xc_handle,
evtchn_port_t port,
xc_evtchn_status_t *status)
{
- int rc;
- evtchn_op_t op = {
- .cmd = EVTCHNOP_status,
- .u.status.dom = (domid_t)dom,
- .u.status.port = port };
-
- if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
- memcpy(status, &op.u.status, sizeof(*status));
-
- return rc;
+ status->dom = (domid_t)dom;
+ status->port = port;
+ return do_evtchn_op(xc_handle, EVTCHNOP_status, status, sizeof(*status));
}
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_hvm_build.c Mon May 08 14:46:11 2006 -0600
@@ -440,7 +440,7 @@ static int xc_hvm_build_internal(int xc_

launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
- launch_op.u.setvcpucontext.ctxt = ctxt;
+ set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt);

launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = xc_dom0_op(xc_handle, &launch_op);
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_ia64_stubs.c Mon May 08 14:46:11 2006 -0600
@@ -75,7 +75,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
op.cmd = DOM0_GETMEMLIST;
op.u.getmemlist.domain = (domid_t)domid;
op.u.getmemlist.max_pfns = max_pfns;
- op.u.getmemlist.buffer = __pfn_buf;
+ set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf);

if ( (max_pfns != -1UL)
&& mlock(__pfn_buf, __nr_pages * sizeof(unsigned long)) != 0 )
@@ -729,7 +729,7 @@ int xc_hvm_build(int xc_handle,

launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
- launch_op.u.setvcpucontext.ctxt = ctxt;
+ set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt);

launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = do_dom0_op(xc_handle, &launch_op);
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_linux_build.c Mon May 08 14:46:11 2006 -0600
@@ -1180,7 +1180,7 @@ static int xc_linux_build_internal(int x

launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
- launch_op.u.setvcpucontext.ctxt = ctxt;
+ set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt);

launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = xc_dom0_op(xc_handle, &launch_op);
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_linux_restore.c Mon May 08 14:46:11 2006 -0600
@@ -583,11 +583,11 @@ int xc_linux_restore(int xc_handle, int
if (count > 0) {

struct xen_memory_reservation reservation = {
- .extent_start = pfntab,
.nr_extents = count,
.extent_order = 0,
.domid = dom
};
+ set_xen_guest_handle(reservation.extent_start, pfntab);

if ((rc = xc_memory_op(xc_handle, XENMEM_decrease_reservation,
&reservation)) != count) {
@@ -727,7 +727,7 @@ int xc_linux_restore(int xc_handle, int
op.cmd = DOM0_SETVCPUCONTEXT;
op.u.setvcpucontext.domain = (domid_t)dom;
op.u.setvcpucontext.vcpu = 0;
- op.u.setvcpucontext.ctxt = &ctxt;
+ set_xen_guest_handle(op.u.setvcpucontext.ctxt, &ctxt);
rc = xc_dom0_op(xc_handle, &op);

if (rc != 0) {
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_linux_save.c Mon May 08 14:46:11 2006 -0600
@@ -12,6 +12,7 @@
#include <unistd.h>
#include <sys/time.h>

+#include "xc_private.h"
#include "xg_private.h"
#include "xg_save_restore.h"

@@ -505,20 +506,21 @@ static unsigned long *xc_map_m2p(int xc_
int prot)
{
struct xen_machphys_mfn_list xmml;
- privcmd_mmap_t ioctlx;
privcmd_mmap_entry_t *entries;
unsigned long m2p_chunks, m2p_size;
unsigned long *m2p;
+ unsigned long *extent_start;
int i, rc;

m2p_size = M2P_SIZE(max_mfn);
m2p_chunks = M2P_CHUNKS(max_mfn);

xmml.max_extents = m2p_chunks;
- if (!(xmml.extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) {
+ if (!(extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) {
ERR("failed to allocate space for m2p mfns");
return NULL;
}
+ set_xen_guest_handle(xmml.extent_start, extent_start);

if (xc_memory_op(xc_handle, XENMEM_machphys_mfn_list, &xmml) ||
(xmml.nr_extents != m2p_chunks)) {
@@ -537,22 +539,19 @@ static unsigned long *xc_map_m2p(int xc_
return NULL;
}

- ioctlx.num = m2p_chunks;
- ioctlx.dom = DOMID_XEN;
- ioctlx.entry = entries;
-
for (i=0; i < m2p_chunks; i++) {
entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE));
- entries[i].mfn = xmml.extent_start[i];
+ entries[i].mfn = extent_start[i];
entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
}

- if ((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
- ERR("ioctl_mmap failed (rc = %d)", rc);
+ if ((rc = xc_map_foreign_ranges(xc_handle, DOMID_XEN,
+ entries, m2p_chunks)) < 0) {
+ ERR("xc_mmap_foreign_ranges failed (rc = %d)", rc);
return NULL;
}

- free(xmml.extent_start);
+ free(extent_start);
free(entries);

return m2p;
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_misc.c Mon May 08 14:46:11 2006 -0600
@@ -5,19 +5,6 @@
*/

#include "xc_private.h"
-
-int xc_interface_open(void)
-{
- int fd = open("/proc/xen/privcmd", O_RDWR);
- if ( fd == -1 )
- PERROR("Could not obtain handle on privileged command interface");
- return fd;
-}
-
-int xc_interface_close(int xc_handle)
-{
- return close(xc_handle);
-}

int xc_readconsolering(int xc_handle,
char **pbuffer,
@@ -30,7 +17,7 @@ int xc_readconsolering(int xc_handle,
unsigned int nr_chars = *pnr_chars;

op.cmd = DOM0_READCONSOLE;
- op.u.readconsole.buffer = buffer;
+ set_xen_guest_handle(op.u.readconsole.buffer, buffer);
op.u.readconsole.count = nr_chars;
op.u.readconsole.clear = clear;

@@ -38,10 +25,7 @@ int xc_readconsolering(int xc_handle,
return ret;

if ( (ret = do_dom0_op(xc_handle, &op)) == 0 )
- {
- *pbuffer = op.u.readconsole.buffer;
*pnr_chars = op.u.readconsole.count;
- }

safe_munlock(buffer, nr_chars);

@@ -91,7 +75,7 @@ int xc_perfc_control(int xc_handle,

op.cmd = DOM0_PERFCCONTROL;
op.u.perfccontrol.op = opcode;
- op.u.perfccontrol.desc = desc;
+ set_xen_guest_handle(op.u.perfccontrol.desc, desc);

rc = do_dom0_op(xc_handle, &op);

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_private.c Mon May 08 14:46:11 2006 -0600
@@ -5,63 +5,6 @@
*/

#include "xc_private.h"
-#include <xen/memory.h>
-
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
- unsigned long *arr, int num )
-{
- privcmd_mmapbatch_t ioctlx;
- void *addr;
- addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
- if ( addr == MAP_FAILED )
- return NULL;
-
- ioctlx.num=num;
- ioctlx.dom=dom;
- ioctlx.addr=(unsigned long)addr;
- ioctlx.arr=arr;
- if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 )
- {
- int saved_errno = errno;
- perror("XXXXXXXX");
- (void)munmap(addr, num*PAGE_SIZE);
- errno = saved_errno;
- return NULL;
- }
- return addr;
-
-}
-
-/*******************/
-
-void *xc_map_foreign_range(int xc_handle, uint32_t dom,
- int size, int prot,
- unsigned long mfn )
-{
- privcmd_mmap_t ioctlx;
- privcmd_mmap_entry_t entry;
- void *addr;
- addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
- if ( addr == MAP_FAILED )
- return NULL;
-
- ioctlx.num=1;
- ioctlx.dom=dom;
- ioctlx.entry=&entry;
- entry.va=(unsigned long) addr;
- entry.mfn=mfn;
- entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
- if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 )
- {
- int saved_errno = errno;
- (void)munmap(addr, size);
- errno = saved_errno;
- return NULL;
- }
- return addr;
-}
-
-/*******************/

/* NB: arr must be mlock'ed */
int xc_get_pfn_type_batch(int xc_handle,
@@ -71,7 +14,7 @@ int xc_get_pfn_type_batch(int xc_handle,
op.cmd = DOM0_GETPAGEFRAMEINFO2;
op.u.getpageframeinfo2.domain = (domid_t)dom;
op.u.getpageframeinfo2.num = num;
- op.u.getpageframeinfo2.array = arr;
+ set_xen_guest_handle(op.u.getpageframeinfo2.array, arr);
return do_dom0_op(xc_handle, &op);
}

@@ -191,6 +134,9 @@ int xc_memory_op(int xc_handle,
struct xen_memory_reservation *reservation = arg;
struct xen_machphys_mfn_list *xmml = arg;
struct xen_translate_gpfn_list *trans = arg;
+ unsigned long *extent_start;
+ unsigned long *gpfn_list;
+ unsigned long *mfn_list;
long ret = -EINVAL;

hypercall.op = __HYPERVISOR_memory_op;
@@ -207,8 +153,9 @@ int xc_memory_op(int xc_handle,
PERROR("Could not mlock");
goto out1;
}
- if ( (reservation->extent_start != NULL) &&
- (mlock(reservation->extent_start,
+ get_xen_guest_handle(extent_start, reservation->extent_start);
+ if ( (extent_start != NULL) &&
+ (mlock(extent_start,
reservation->nr_extents * sizeof(unsigned long)) != 0) )
{
PERROR("Could not mlock");
@@ -222,7 +169,8 @@ int xc_memory_op(int xc_handle,
PERROR("Could not mlock");
goto out1;
}
- if ( mlock(xmml->extent_start,
+ get_xen_guest_handle(extent_start, xmml->extent_start);
+ if ( mlock(extent_start,
xmml->max_extents * sizeof(unsigned long)) != 0 )
{
PERROR("Could not mlock");
@@ -243,16 +191,18 @@ int xc_memory_op(int xc_handle,
PERROR("Could not mlock");
goto out1;
}
- if ( mlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
+ get_xen_guest_handle(gpfn_list, trans->gpfn_list);
+ if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
{
PERROR("Could not mlock");
safe_munlock(trans, sizeof(*trans));
goto out1;
}
- if ( mlock(trans->mfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
- {
- PERROR("Could not mlock");
- safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
+ get_xen_guest_handle(mfn_list, trans->mfn_list);
+ if ( mlock(mfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
+ {
+ PERROR("Could not mlock");
+ safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long));
safe_munlock(trans, sizeof(*trans));
goto out1;
}
@@ -267,21 +217,25 @@ int xc_memory_op(int xc_handle,
case XENMEM_decrease_reservation:
case XENMEM_populate_physmap:
safe_munlock(reservation, sizeof(*reservation));
- if ( reservation->extent_start != NULL )
- safe_munlock(reservation->extent_start,
+ get_xen_guest_handle(extent_start, reservation->extent_start);
+ if ( extent_start != NULL )
+ safe_munlock(extent_start,
reservation->nr_extents * sizeof(unsigned long));
break;
case XENMEM_machphys_mfn_list:
safe_munlock(xmml, sizeof(*xmml));
- safe_munlock(xmml->extent_start,
+ get_xen_guest_handle(extent_start, xmml->extent_start);
+ safe_munlock(extent_start,
xmml->max_extents * sizeof(unsigned long));
break;
case XENMEM_add_to_physmap:
safe_munlock(arg, sizeof(struct xen_add_to_physmap));
break;
case XENMEM_translate_gpfn_list:
- safe_munlock(trans->mfn_list, trans->nr_gpfns * sizeof(long));
- safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
+ get_xen_guest_handle(mfn_list, trans->mfn_list);
+ safe_munlock(mfn_list, trans->nr_gpfns * sizeof(long));
+ get_xen_guest_handle(gpfn_list, trans->gpfn_list);
+ safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long));
safe_munlock(trans, sizeof(*trans));
break;
}
@@ -317,7 +271,7 @@ int xc_get_pfn_list(int xc_handle,
op.cmd = DOM0_GETMEMLIST;
op.u.getmemlist.domain = (domid_t)domid;
op.u.getmemlist.max_pfns = max_pfns;
- op.u.getmemlist.buffer = pfn_buf;
+ set_xen_guest_handle(op.u.getmemlist.buffer, pfn_buf);

#ifdef VALGRIND
memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_private.h Mon May 08 14:46:11 2006 -0600
@@ -15,7 +15,7 @@

#include "xenctrl.h"

-#include <xen/linux/privcmd.h>
+#include <xen/sys/privcmd.h>

/* valgrind cannot see when a hypercall has filled in some values. For this
reason, we must zero the privcmd_hypercall_t or dom0_op_t instance before a
@@ -56,20 +56,7 @@ static inline void safe_munlock(const vo
errno = saved_errno;
}

-static inline int do_privcmd(int xc_handle,
- unsigned int cmd,
- unsigned long data)
-{
- return ioctl(xc_handle, cmd, data);
-}
-
-static inline int do_xen_hypercall(int xc_handle,
- privcmd_hypercall_t *hypercall)
-{
- return do_privcmd(xc_handle,
- IOCTL_PRIVCMD_HYPERCALL,
- (unsigned long)hypercall);
-}
+int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall);

static inline int do_xen_version(int xc_handle, int cmd, void *dest)
{
@@ -111,23 +98,7 @@ static inline int do_dom0_op(int xc_hand
return ret;
}

-
-/*
- * ioctl-based mfn mapping interface
- */
-
-/*
-typedef struct privcmd_mmap_entry {
- unsigned long va;
- unsigned long mfn;
- unsigned long npages;
-} privcmd_mmap_entry_t;
-
-typedef struct privcmd_mmap {
- int num;
- domid_t dom;
- privcmd_mmap_entry_t *entry;
-} privcmd_mmap_t;
-*/
+int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+ privcmd_mmap_entry_t *entries, int nr);

#endif /* __XC_PRIVATE_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_tbuf.c
--- a/tools/libxc/xc_tbuf.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xc_tbuf.c Mon May 08 14:46:11 2006 -0600
@@ -4,6 +4,14 @@
* API for manipulating and accessing trace buffer parameters
*
* Copyright (c) 2005, Rob Gardner
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
*/

#include "xc_private.h"
@@ -49,3 +57,41 @@ int xc_tbuf_get_size(int xc_handle, uint
return rc;
}

+int xc_tbuf_get_mfn(int xc_handle, unsigned long *mfn)
+{
+ int rc;
+ DECLARE_DOM0_OP;
+
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO;
+
+ rc = xc_dom0_op(xc_handle, &op);
+ if ( rc == 0 )
+ *mfn = op.u.tbufcontrol.buffer_mfn;
+ return rc;
+}
+
+int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask)
+{
+ DECLARE_DOM0_OP;
+
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ op.u.tbufcontrol.op = DOM0_TBUF_SET_CPU_MASK;
+ op.u.tbufcontrol.cpu_mask = mask;
+
+ return do_dom0_op(xc_handle, &op);
+}
+
+int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask)
+{
+ DECLARE_DOM0_OP;
+
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ op.u.tbufcontrol.op = DOM0_TBUF_SET_EVT_MASK;
+ op.u.tbufcontrol.evt_mask = mask;
+
+ return do_dom0_op(xc_handle, &op);
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xenctrl.h Mon May 08 14:46:11 2006 -0600
@@ -19,6 +19,7 @@
#include <xen/sched_ctl.h>
#include <xen/memory.h>
#include <xen/acm.h>
+#include <xen/acm_ops.h>

#ifdef __ia64__
#define XC_PAGE_SHIFT 14
@@ -560,6 +561,18 @@ int xc_tbuf_set_size(int xc_handle, uint
*/
int xc_tbuf_get_size(int xc_handle, uint32_t *size);

+/**
+ * This function retrieves the machine frame of the trace buffer.
+
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm mfn will contain the machine frame of the buffer.
+ * @return 0 on success, -1 on failure.
+ */
+int xc_tbuf_get_mfn(int xc_handle, unsigned long *mfn);
+
+int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask);
+
+int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask);

/* Execute a privileged dom0 operation. */
int xc_dom0_op(int xc_handle, dom0_op_t *op);
@@ -581,4 +594,6 @@ int xc_add_mmu_update(int xc_handle, xc_
unsigned long long ptr, unsigned long long val);
int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);

+int xc_acm_op(int xc_handle, struct acm_op *op);
+
#endif
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Mon May 08 13:41:18 2006 -0600
+++ b/tools/libxc/xg_private.h Mon May 08 14:46:11 2006 -0600
@@ -13,7 +13,7 @@
#include "xenctrl.h"
#include "xenguest.h"

-#include <xen/linux/privcmd.h>
+#include <xen/sys/privcmd.h>
#include <xen/memory.h>

/* valgrind cannot see when a hypercall has filled in some values. For this
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/misc/xend
--- a/tools/misc/xend Mon May 08 13:41:18 2006 -0600
+++ b/tools/misc/xend Mon May 08 14:46:11 2006 -0600
@@ -2,7 +2,7 @@
# -*- mode: python; -*-
#============================================================================
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-# Copyright (C) 2005 XenSource Ltd
+# Copyright (C) 2005-2006 XenSource Inc
#============================================================================

"""Xen management daemon.
@@ -21,15 +21,31 @@
and recover its state when restarted.
"""
import os
+import os.path
import sys
import socket
import signal
import time
import commands

-# add fallback path for non-native python path installs if needed
-sys.path.append('/usr/lib/python')
-sys.path.append('/usr/lib64/python')
+
+# Use the auxbin module in Xend to determine the correct Python path. We
+# take the first installed instance of auxbin that we find, and then run it
+# to determine the correct path, appending that to sys.path.
+
+AUXBIN = 'xen/util/auxbin.py'
+
+for p in ['python%s' % sys.version[:3], 'python']:
+ for l in ['/usr/lib64', '/usr/lib']:
+ d = os.path.join(l, p)
+ if os.path.exists(os.path.join(d, AUXBIN)):
+ sys.path.append(d)
+ import xen.util.auxbin
+ libpath = xen.util.auxbin.libpath()
+ sys.path = sys.path[:-1]
+ sys.path.append(libpath)
+ break
+
from xen.xend.server import SrvDaemon

class CheckError(ValueError):
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/lowlevel/acm/acm.c
--- a/tools/python/xen/lowlevel/acm/acm.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/lowlevel/acm/acm.c Mon May 08 14:46:11 2006 -0600
@@ -28,51 +28,22 @@
#include <netinet/in.h>
#include <xen/acm.h>
#include <xen/acm_ops.h>
-#include <xen/linux/privcmd.h>
+
+#include <xenctrl.h>

#define PERROR(_m, _a...) \
fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
errno, strerror(errno))

-
-
-static inline int do_acm_op(int xc_handle, struct acm_op *op)
-{
- int ret = -1;
- privcmd_hypercall_t hypercall;
-
- op->interface_version = ACM_INTERFACE_VERSION;
-
- hypercall.op = __HYPERVISOR_acm_op;
- hypercall.arg[0] = (unsigned long) op;
-
- if (mlock(op, sizeof(*op)) != 0) {
- PERROR("Could not lock memory for Xen policy hypercall");
- goto out1;
- }
- ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
- if (ret < 0) {
- if (errno == EACCES)
- PERROR("ACM operation failed.");
- goto out2;
- }
- out2:
- munlock(op, sizeof(*op));
- out1:
- return ret;
-}
-
-
-
/* generic shared function */
void * __getssid(int domid, uint32_t *buflen)
{
struct acm_op op;
- int acm_cmd_fd;
+ int xc_handle;
#define SSID_BUFFER_SIZE 4096
void *buf = NULL;

- if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) < 0) {
+ if ((xc_handle = xc_interface_open()) < 0) {
goto out1;
}
if ((buf = malloc(SSID_BUFFER_SIZE)) == NULL) {
@@ -87,7 +58,9 @@ void * __getssid(int domid, uint32_t *bu
op.u.getssid.get_ssid_by = DOMAINID;
op.u.getssid.id.domainid = domid;

- if (do_acm_op(acm_cmd_fd, &op) < 0) {
+ if (xc_acm_op(xc_handle, &op) < 0) {
+ if (errno == EACCES)
+ PERROR("ACM operation failed.");
free(buf);
buf = NULL;
goto out2;
@@ -96,7 +69,7 @@ void * __getssid(int domid, uint32_t *bu
goto out2;
}
out2:
- close(acm_cmd_fd);
+ xc_interface_close(xc_handle);
out1:
return buf;
}
@@ -175,13 +148,13 @@ static PyObject *getdecision(PyObject *
{
char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
struct acm_op op;
- int acm_cmd_fd, ret;
+ int xc_handle;

if (!PyArg_ParseTuple(args, "ssss", &arg1_name, &arg1, &arg2_name, &arg2)) {
return NULL;
}

- if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
+ if ((xc_handle = xc_interface_open()) <= 0) {
PERROR("Could not open xen privcmd device!\n");
return NULL;
}
@@ -208,8 +181,12 @@ static PyObject *getdecision(PyObject *
op.u.getdecision.id2.ssidref = atol(arg2);
}

- ret = do_acm_op(acm_cmd_fd, &op);
- close(acm_cmd_fd);
+ if (xc_acm_op(xc_handle, &op) < 0) {
+ if (errno == EACCES)
+ PERROR("ACM operation failed.");
+ }
+
+ xc_interface_close(xc_handle);

if (op.u.getdecision.acm_decision == ACM_ACCESS_PERMITTED)
decision = "PERMITTED";
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/util/auxbin.py
--- a/tools/python/xen/util/auxbin.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/util/auxbin.py Mon May 08 14:46:11 2006 -0600
@@ -12,14 +12,15 @@
# 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) 2005 XenSource Ltd
+# Copyright (C) 2005-2006 XenSource Inc.
#============================================================================


-LIB_BIN_32 = "/usr/lib/xen/bin"
-LIB_BIN_64 = "/usr/lib64/xen/bin"
+LIB_32 = "/usr/lib"
+LIB_64 = "/usr/lib64"
+LIB_BIN_SUFFIX = "xen/bin"

-## The architectures on which the LIB_BIN_64 directory is used. This
+## The architectures on which the LIB_64 directory is used. This
# deliberately excludes ia64.
LIB_64_ARCHS = [ 'x86_64', 'ppc64', 's390x', 'sparc64']

@@ -41,8 +42,12 @@ def pathTo(exe):


def path():
+ return os.path.join(libpath(), LIB_BIN_SUFFIX)
+
+
+def libpath():
machine = os.uname()[4]
- if machine in LIB_64_ARCHS and os.path.exists(LIB_BIN_64):
- return LIB_BIN_64
+ if machine in LIB_64_ARCHS and os.path.exists(LIB_64):
+ return LIB_64
else:
- return LIB_BIN_32
+ return LIB_32
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xend/XendBootloader.py Mon May 08 14:46:11 2006 -0600
@@ -19,14 +19,13 @@ from XendLogging import log
from XendLogging import log
from XendError import VmError

-def bootloader(blexec, disk, quiet = 0, vcpus = None, entry = None):
+def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
"""Run the boot loader executable on the given disk and return a
config image.
@param blexec Binary to use as the boot loader
@param disk Disk to run the boot loader on.
@param quiet Run in non-interactive mode, just booting the default.
- @param vcpus Number of vcpus for the domain.
- @param entry Default entry to boot."""
+ @param blargs Arguments to pass to the bootloader."""

if not os.access(blexec, os.X_OK):
msg = "Bootloader isn't executable"
@@ -49,8 +48,8 @@ def bootloader(blexec, disk, quiet = 0,
if quiet:
args.append("-q")
args.append("--output=%s" %(fifo,))
- if entry is not None:
- args.append("--entry=%s" %(entry,))
+ if blargs is not None:
+ args.extend(blargs.split())
args.append(disk)

try:
@@ -87,9 +86,10 @@ def bootloader(blexec, disk, quiet = 0,
pin = sxp.Parser()
pin.input(ret)
pin.input_eof()
+ blcfg = pin.val

- config_image = pin.val
- if vcpus and sxp.child_value(config_image, "vcpus") is None:
- config_image.append(['vcpus', vcpus])
-
- return config_image
+ if imgcfg is None:
+ return blcfg
+ else:
+ c = sxp.merge(blcfg, imgcfg)
+ return c
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon May 08 14:46:11 2006 -0600
@@ -132,6 +132,8 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [.
('memory', int),
('maxmem', int),
('bootloader', str),
+ ('bootloader_args', str),
+ ('features', str),
]

ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
@@ -549,6 +551,7 @@ class XendDomainInfo:
defaultInfo('on_poweroff', lambda: "destroy")
defaultInfo('on_reboot', lambda: "restart")
defaultInfo('on_crash', lambda: "restart")
+ defaultInfo('features', lambda: "")
defaultInfo('cpu', lambda: None)
defaultInfo('cpus', lambda: [])
defaultInfo('cpu_weight', lambda: 1.0)
@@ -569,6 +572,7 @@ class XendDomainInfo:
defaultInfo('memory', lambda: 0)
defaultInfo('maxmem', lambda: 0)
defaultInfo('bootloader', lambda: None)
+ defaultInfo('bootloader_args', lambda: None)
defaultInfo('backend', lambda: [])
defaultInfo('device', lambda: [])
defaultInfo('image', lambda: None)
@@ -775,6 +779,9 @@ class XendDomainInfo:
"""For use only by image.py and XendCheckpoint.py"""
return self.console_port

+ def getFeatures(self):
+ """For use only by image.py."""
+ return self.info['features']

def getVCpuCount(self):
return self.info['vcpus']
@@ -1229,6 +1236,11 @@ class XendDomainInfo:
self.domid,
self.info['cpu_weight'])

+ # if we have a boot loader but no image, then we need to set things
+ # up by running the boot loader non-interactively
+ if self.infoIsSet('bootloader') and not self.infoIsSet('image'):
+ self.configure_bootloader()
+
if not self.infoIsSet('image'):
raise VmError('Missing image in configuration')

@@ -1608,24 +1620,27 @@ class XendDomainInfo:


def configure_bootloader(self):
+ """Run the bootloader if we're configured to do so."""
if not self.info['bootloader']:
return
- # if we're restarting with a bootloader, we need to run it
blcfg = None
- config = self.sxpr()
- # FIXME: this assumes that we want to use the first disk
- for dev in sxp.children(config, "device"):
- disk = sxp.child(dev, "vbd")
+ # FIXME: this assumes that we want to use the first disk device
+ for (n,c) in self.info['device']:
+ if not n or not c or n != "vbd":
+ continue
+ disk = sxp.child_value(c, "uname")
if disk is None:
continue
- fn = blkdev_uname_to_file(sxp.child_value(disk, "uname"))
+ fn = blkdev_uname_to_file(disk)
blcfg = bootloader(self.info['bootloader'], fn, 1,
- self.info['vcpus'])
+ self.info['bootloader_args'],
+ self.info['image'])
+ break
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
- self.info['image'] = sxp.to_string(blcfg)
+ self.info['image'] = blcfg


def send_sysrq(self, key):
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xend/image.py Mon May 08 14:46:11 2006 -0600
@@ -68,7 +68,6 @@ class ImageHandler:
self.kernel = None
self.ramdisk = None
self.cmdline = None
- self.features = None

self.configure(imageConfig, deviceConfig)

@@ -90,7 +89,6 @@ class ImageHandler:
if args:
self.cmdline += " " + args
self.ramdisk = get_cfg("ramdisk", '')
- self.features = get_cfg("features", '')

self.vm.storeVm(("image/ostype", self.ostype),
("image/kernel", self.kernel),
@@ -177,7 +175,7 @@ class LinuxImageHandler(ImageHandler):
log.debug("cmdline = %s", self.cmdline)
log.debug("ramdisk = %s", self.ramdisk)
log.debug("vcpus = %d", self.vm.getVCpuCount())
- log.debug("features = %s", self.features)
+ log.debug("features = %s", self.vm.getFeatures())

return xc.linux_build(dom = self.vm.getDomid(),
image = self.kernel,
@@ -185,7 +183,7 @@ class LinuxImageHandler(ImageHandler):
console_evtchn = console_evtchn,
cmdline = self.cmdline,
ramdisk = self.ramdisk,
- features = self.features)
+ features = self.vm.getFeatures())

class HVMImageHandler(ImageHandler):

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xend/server/SrvDaemon.py Mon May 08 14:46:11 2006 -0600
@@ -87,8 +87,6 @@ class Daemon:


def daemonize(self):
- if not XEND_DAEMONIZE: return
-
# Detach from TTY.

# Become the group leader (already a child process)
@@ -133,6 +131,13 @@ class Daemon:

ret = 0

+ # If we're not going to create a daemon, simply
+ # call the run method right here.
+ if not XEND_DAEMONIZE:
+ self.tracing(trace)
+ self.run(None)
+ return ret;
+
# we use a pipe to communicate between the parent and the child process
# this way we know when the child has actually initialized itself so
# we can avoid a race condition during startup
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xend/server/pciif.py Mon May 08 14:46:11 2006 -0600
@@ -94,7 +94,7 @@ class PciController(DevController):

else:
# Xen 2.0 configuration compatibility
- domain = get_param(dev_config, 'domain', 0)
+ domain = get_param(config, 'domain', 0)
bus = get_param(config, 'bus')
slot = get_param(config, 'dev')
func = get_param(config, 'func')
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xm/create.py Mon May 08 14:46:11 2006 -0600
@@ -122,9 +122,13 @@ gopts.var('bootloader', val='FILE',
fn=set_value, default=None,
use="Path to bootloader.")

+gopts.var('bootargs', val='NAME',
+ fn=set_value, default=None,
+ use="Arguments to pass to boot loader")
+
gopts.var('bootentry', val='NAME',
fn=set_value, default=None,
- use="Entry to boot via boot loader")
+ use="DEPRECATED. Entry to boot via boot loader. Use bootargs.")

gopts.var('kernel', val='FILE',
fn=set_value, default=None,
@@ -444,8 +448,11 @@ def configure_image(vals):
def configure_image(vals):
"""Create the image config.
"""
+ if not vals.builder:
+ return None
config_image = [ vals.builder ]
- config_image.append([ 'kernel', os.path.abspath(vals.kernel) ])
+ if vals.kernel:
+ config_image.append([ 'kernel', os.path.abspath(vals.kernel) ])
if vals.ramdisk:
config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ])
if vals.cmdline_ip:
@@ -456,8 +463,6 @@ def configure_image(vals):
config_image.append(['root', cmdline_root])
if vals.extra:
config_image.append(['args', vals.extra])
- if vals.features:
- config_image.append(['features', vals.features])

if vals.builder == 'hvm':
configure_hvm(config_image, vals)
@@ -614,7 +619,7 @@ def configure_hvm(config_image, vals):
if (vals.__dict__[a]):
config_image.append([a, vals.__dict__[a]])

-def run_bootloader(vals):
+def run_bootloader(vals, config_image):
if not os.access(vals.bootloader, os.X_OK):
err("Bootloader isn't executable")
if len(vals.disk) < 1:
@@ -622,8 +627,13 @@ def run_bootloader(vals):
(uname, dev, mode, backend) = vals.disk[0]
file = blkif.blkdev_uname_to_file(uname)

+ if vals.bootentry:
+ warn("The bootentry option is deprecated. Use bootargs and pass "
+ "--entry= directly.")
+ vals.bootargs = "--entry=%s" %(vals.bootentry,)
+
return bootloader(vals.bootloader, file, not vals.console_autoconnect,
- vals.vcpus, vals.bootentry)
+ vals.bootargs, config_image)

def make_config(vals):
"""Create the domain configuration.
@@ -638,7 +648,7 @@ def make_config(vals):
config.append([n, v])

map(add_conf, ['name', 'memory', 'maxmem', 'restart', 'on_poweroff',
- 'on_reboot', 'on_crash', 'vcpus'])
+ 'on_reboot', 'on_crash', 'vcpus', 'features'])

if vals.uuid is not None:
config.append(['uuid', vals.uuid])
@@ -655,11 +665,12 @@ def make_config(vals):
if vals.tpmif:
config.append(['backend', ['tpmif']])

+ config_image = configure_image(vals)
if vals.bootloader:
+ config_image = run_bootloader(vals, config_image)
config.append(['bootloader', vals.bootloader])
- config_image = run_bootloader(vals)
- else:
- config_image = configure_image(vals)
+ if vals.bootargs:
+ config.append(['bootloader_args'], vals.bootargs)
config.append(['image', config_image])

config_devs = []
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/python/xen/xm/tests/test_create.py
--- a/tools/python/xen/xm/tests/test_create.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/python/xen/xm/tests/test_create.py Mon May 08 14:46:11 2006 -0600
@@ -112,7 +112,6 @@ on_crash = 'destroy'
'''
name = "testname"
memory = 256
-ssidref = 1
kernel = "/mykernel"
maxmem = 1024
cpu = 2
@@ -132,7 +131,6 @@ cpu_weight = 0.75
'memory' : 256,
'maxmem' : 1024,
'cpu' : 2,
- 'ssidref' : 1,
'cpu_weight' : 0.75,
'vcpus' : 1,
'boot' : 'c',
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/security/secpol_tool.c Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@
*
* sHype policy management tool. This code runs in a domain and
* manages the Xen security policy by interacting with the
- * Xen access control module via a /proc/xen/privcmd proc-ioctl,
+ * Xen access control module via the privcmd device,
* which is translated into a acm_op hypercall into Xen.
*
* indent -i4 -kr -nut
@@ -36,7 +36,8 @@
#include <stdint.h>
#include <xen/acm.h>
#include <xen/acm_ops.h>
-#include <xen/linux/privcmd.h>
+
+#include <xenctrl.h>

#define PERROR(_m, _a...) \
fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
@@ -50,47 +51,6 @@ void usage(char *progname)
"\t dumpstats\n"
"\t loadpolicy <binary policy file>\n", progname);
exit(-1);
-}
-
-static inline int do_policycmd(int xc_handle, unsigned int cmd,
- unsigned long data)
-{
- return ioctl(xc_handle, cmd, data);
-}
-
-static inline int do_xen_hypercall(int xc_handle,
- privcmd_hypercall_t * hypercall)
-{
- return do_policycmd(xc_handle,
- IOCTL_PRIVCMD_HYPERCALL,
- (unsigned long) hypercall);
-}
-
-static inline int do_acm_op(int xc_handle, struct acm_op *op)
-{
- int ret = -1;
- privcmd_hypercall_t hypercall;
-
- op->interface_version = ACM_INTERFACE_VERSION;
-
- hypercall.op = __HYPERVISOR_acm_op;
- hypercall.arg[0] = (unsigned long) op;
-
- if (mlock(op, sizeof(*op)) != 0) {
- PERROR("Could not lock memory for Xen policy hypercall");
- goto out1;
- }
-
- if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0) {
- printf("ACM operation failed: errno=%d\n", errno);
- if (errno == EACCES)
- fprintf(stderr, "ACM operation failed -- need to"
- " rebuild the user-space tool set?\n");
- goto out2;
- }
-
- out2:(void) munlock(op, sizeof(*op));
- out1:return ret;
}

/*************************** DUMPS *******************************/
@@ -276,10 +236,15 @@ int acm_domain_getpolicy(int xc_handle)

memset(pull_buffer, 0x00, sizeof(pull_buffer));
op.cmd = ACM_GETPOLICY;
- op.interface_version = ACM_INTERFACE_VERSION;
op.u.getpolicy.pullcache = (void *) pull_buffer;
op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
- ret = do_acm_op(xc_handle, &op);
+ if ((ret = xc_acm_op(xc_handle, &op)) < 0) {
+ printf("ACM operation failed: errno=%d\n", errno);
+ if (errno == EACCES)
+ fprintf(stderr, "ACM operation failed -- need to"
+ " rebuild the user-space tool set?\n");
+ }
+
/* dump policy */
acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
return ret;
@@ -314,10 +279,9 @@ int acm_domain_loadpolicy(int xc_handle,
/* dump it and then push it down into xen/acm */
acm_dump_policy_buffer(buffer, len);
op.cmd = ACM_SETPOLICY;
- op.interface_version = ACM_INTERFACE_VERSION;
op.u.setpolicy.pushcache = (void *) buffer;
op.u.setpolicy.pushcache_size = len;
- ret = do_acm_op(xc_handle, &op);
+ ret = xc_acm_op(xc_handle, &op);

if (ret)
printf
@@ -364,10 +328,9 @@ int acm_domain_dumpstats(int xc_handle)

memset(stats_buffer, 0x00, sizeof(stats_buffer));
op.cmd = ACM_DUMPSTATS;
- op.interface_version = ACM_INTERFACE_VERSION;
op.u.dumpstats.pullcache = (void *) stats_buffer;
op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
- ret = do_acm_op(xc_handle, &op);
+ ret = xc_acm_op(xc_handle, &op);

if (ret < 0) {
printf
@@ -426,12 +389,12 @@ int main(int argc, char **argv)
int main(int argc, char **argv)
{

- int acm_cmd_fd, ret = 0;
+ int xc_handle, ret = 0;

if (argc < 2)
usage(argv[0]);

- if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
+ if ((xc_handle = xc_interface_open()) <= 0) {
printf("ERROR: Could not open xen privcmd device!\n");
exit(-1);
}
@@ -439,18 +402,18 @@ int main(int argc, char **argv)
if (!strcmp(argv[1], "getpolicy")) {
if (argc != 2)
usage(argv[0]);
- ret = acm_domain_getpolicy(acm_cmd_fd);
+ ret = acm_domain_getpolicy(xc_handle);
} else if (!strcmp(argv[1], "loadpolicy")) {
if (argc != 3)
usage(argv[0]);
- ret = acm_domain_loadpolicy(acm_cmd_fd, argv[2]);
+ ret = acm_domain_loadpolicy(xc_handle, argv[2]);
} else if (!strcmp(argv[1], "dumpstats")) {
if (argc != 2)
usage(argv[0]);
- ret = acm_domain_dumpstats(acm_cmd_fd);
+ ret = acm_domain_dumpstats(xc_handle);
} else
usage(argv[0]);

- close(acm_cmd_fd);
+ xc_interface_close(xc_handle);
return ret;
}
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenmon/xenbaked.c
--- a/tools/xenmon/xenbaked.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/xenmon/xenbaked.c Mon May 08 14:46:11 2006 -0600
@@ -410,14 +410,13 @@ struct t_buf *map_tbufs(unsigned long tb
struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
unsigned long size)
{
- int xc_handle; /* file descriptor for /proc/xen/privcmd */
+ int xc_handle;
struct t_buf *tbufs_mapped;

xc_handle = xc_interface_open();

if ( xc_handle < 0 )
{
- PERROR("Open /proc/xen/privcmd when mapping trace buffers\n");
exit(EXIT_FAILURE);
}

@@ -677,7 +676,10 @@ void alloc_qos_data(int ncpu)
for (n=0; n<ncpu; n++) {

for (i=0; i<sizeof(_new_qos_data); i=i+pgsize)
- write(qos_fd, dummy, pgsize);
+ if ((write(qos_fd, dummy, pgsize)) != pgsize) {
+ PERROR(SHARED_MEM_FILE);
+ exit(2);
+ }

new_qos = (_new_qos_data *) mmap(0, sizeof(_new_qos_data), PROT_READ|PROT_WRITE,
MAP_SHARED, qos_fd, off);
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenstat/libxenstat/Makefile
--- a/tools/xenstat/libxenstat/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/tools/xenstat/libxenstat/Makefile Mon May 08 14:46:11 2006 -0600
@@ -33,28 +33,26 @@ LIB=src/libxenstat.a
LIB=src/libxenstat.a
SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
-OBJECTS=src/xenstat.o src/xen-interface.o
+OBJECTS=src/xenstat.o
SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR)

WARN_FLAGS=-Wall -Werror

CFLAGS+=-Isrc -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
-LDFLAGS+=-Lsrc
+LDFLAGS+=-Lsrc -L$(XEN_XENSTORE)/ -L$(XEN_LIBXC)/

.PHONY: all
all: $(LIB)

$(LIB): $(OBJECTS)
- $(AR) rc $@ $^ $(XEN_XENSTORE)/libxenstore.so
+ $(AR) rc $@ $^ $(XEN_XENSTORE)/libxenstore.so $(XEN_LIBXC)/libxenctrl.so
$(RANLIB) $@

$(SHLIB): $(OBJECTS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS)
+ $(CC) $(CFLAGS) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS) \
+ -lxenstore -lxenctrl

-src/xenstat.o: src/xenstat.c src/xenstat.h src/xen-interface.h
- $(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
-
-src/xen-interface.o: src/xen-interface.c src/xen-interface.h
+src/xenstat.o: src/xenstat.c src/xenstat.h
$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<

src/libxenstat.so.$(MAJOR): $(LIB)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat.c Mon May 08 14:46:11 2006 -0600
@@ -20,9 +20,10 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <xen-interface.h>
#include <xs.h>
#include "xenstat.h"
+
+#include "xenctrl.h"

/*
* Types
@@ -31,7 +32,7 @@
#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)

struct xenstat_handle {
- xi_handle *xihandle;
+ int xc_handle;
struct xs_handle *xshandle; /* xenstore handle */
int page_size;
FILE *procnetdev;
@@ -150,9 +151,9 @@ xenstat_handle *xenstat_init(void)
}
#endif

- handle->xihandle = xi_init();
- if (handle->xihandle == NULL) {
- perror("xi_init");
+ handle->xc_handle = xc_interface_open();
+ if (handle->xc_handle == -1) {
+ perror("xc_interface_open");
free(handle);
return NULL;
}
@@ -160,6 +161,7 @@ xenstat_handle *xenstat_init(void)
handle->xshandle = xs_daemon_open_readonly(); /* open handle to xenstore*/
if (handle->xshandle == NULL) {
perror("unable to open xenstore\n");
+ xc_interface_close(handle->xc_handle);
free(handle);
return NULL;
}
@@ -173,7 +175,7 @@ void xenstat_uninit(xenstat_handle * han
if (handle) {
for (i = 0; i < NUM_COLLECTORS; i++)
collectors[i].uninit(handle);
- xi_uninit(handle->xihandle);
+ xc_interface_close(handle->xc_handle);
xs_daemon_close(handle->xshandle);
free(handle);
}
@@ -197,7 +199,7 @@ xenstat_node *xenstat_get_node(xenstat_h
node->handle = handle;

/* Get information about the physical system */
- if (xi_get_physinfo(handle->xihandle, &physinfo) < 0) {
+ if (xc_physinfo(handle->xc_handle, &physinfo) < 0) {
free(node);
return NULL;
}
@@ -223,9 +225,8 @@ xenstat_node *xenstat_get_node(xenstat_h
do {
xenstat_domain *domain;

- new_domains = xi_get_domaininfolist(handle->xihandle,
- domaininfo, num_domains,
- DOMAIN_CHUNK_SIZE);
+ new_domains = xc_domain_getinfolist(handle->xc_handle,
+ num_domains, DOMAIN_CHUNK_SIZE, domaininfo);

node->domains = realloc(node->domains,
(num_domains + new_domains)
@@ -467,8 +468,8 @@ static int xenstat_collect_vcpus(xenstat
/* FIXME: need to be using a more efficient mechanism*/
dom0_getvcpuinfo_t info;

- if (xi_get_domain_vcpu_info(node->handle->xihandle,
- node->domains[i].id, vcpu, &info) != 0)
+ if (xc_vcpu_getinfo(node->handle->xc_handle,
+ node->domains[i].id, vcpu, &info) != 0)
return 0;

node->domains[i].vcpus[vcpu].online = info.online;
@@ -677,8 +678,14 @@ static int xenstat_collect_xen_version(x
/* Collect Xen version information if not already collected */
if (node->handle->xen_version[0] == '\0') {
/* Get the Xen version number and extraversion string */
- if (xi_get_xen_version(node->handle->xihandle,
- &vnum, &version) < 0)
+ vnum = xc_version(node->handle->xc_handle,
+ XENVER_version, NULL);
+
+ if (vnum < 0)
+ return 0;
+
+ if (xc_version(node->handle->xc_handle, XENVER_extraversion,
+ &version) < 0)
return 0;
/* Format the version information as a string and store it */
snprintf(node->handle->xen_version, VERSION_SIZE, "%ld.%ld%s",
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/xenstore/xenstored_core.c Mon May 08 14:46:11 2006 -0600
@@ -173,7 +173,7 @@ void trace(const char *fmt, ...)
va_list arglist;
char *str;
char sbuf[1024];
- int ret;
+ int ret, dummy;

if (tracefd < 0)
return;
@@ -184,7 +184,7 @@ void trace(const char *fmt, ...)
va_end(arglist);

if (ret <= 1024) {
- write(tracefd, sbuf, ret);
+ dummy = write(tracefd, sbuf, ret);
return;
}

@@ -192,7 +192,7 @@ void trace(const char *fmt, ...)
va_start(arglist, fmt);
str = talloc_vasprintf(NULL, fmt, arglist);
va_end(arglist);
- write(tracefd, str, strlen(str));
+ dummy = write(tracefd, str, strlen(str));
talloc_free(str);
}

@@ -238,7 +238,8 @@ static void trigger_reopen_log(int signa
static void trigger_reopen_log(int signal __attribute__((unused)))
{
char c = 'A';
- write(reopen_log_pipe[1], &c, 1);
+ int dummy;
+ dummy = write(reopen_log_pipe[1], &c, 1);
}


@@ -1678,7 +1679,8 @@ static void write_pidfile(const char *pi
exit(0);

len = sprintf(buf, "%d\n", getpid());
- write(fd, buf, len);
+ if (write(fd, buf, len) != len)
+ barf_perror("Writing pid file %s", pidfile);
}

/* Stevens. */
@@ -1703,7 +1705,8 @@ static void daemonize(void)

#ifndef TESTING /* Relative paths for socket names */
/* Move off any mount points we might be in. */
- chdir("/");
+ if (chdir("/") == -1)
+ barf_perror("Failed to chdir");
#endif
/* Discard our parent's old-fashioned umask prejudices. */
umask(0);
@@ -1900,7 +1903,8 @@ int main(int argc, char *argv[])

if (FD_ISSET(reopen_log_pipe[0], &inset)) {
char c;
- read(reopen_log_pipe[0], &c, 1);
+ if (read(reopen_log_pipe[0], &c, 1) != 1)
+ barf_perror("read failed");
reopen_log();
}

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon May 08 13:41:18 2006 -0600
+++ b/tools/xentrace/xentrace.c Mon May 08 14:46:11 2006 -0600
@@ -20,10 +20,21 @@
#include <errno.h>
#include <argp.h>
#include <signal.h>
-
-#include "xc_private.h"
-
+#include <inttypes.h>
+#include <string.h>
+
+#include <xen/xen.h>
#include <xen/trace.h>
+
+#include <xenctrl.h>
+
+#define PERROR(_m, _a...) \
+do { \
+ int __saved_errno = errno; \
+ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
+ __saved_errno, strerror(__saved_errno)); \
+ errno = __saved_errno; \
+} while (0)

extern FILE *stderr;

@@ -100,26 +111,22 @@ void write_rec(unsigned int cpu, struct
*/
void get_tbufs(unsigned long *mfn, unsigned long *size)
{
- int ret;
- dom0_op_t op; /* dom0 op we'll build */
+ uint32_t size32;
int xc_handle = xc_interface_open(); /* for accessing control interface */

- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO;
-
- ret = do_dom0_op(xc_handle, &op);
+ if (xc_tbuf_get_size(xc_handle, &size32) != 0)
+ goto fail;
+ *size = size32;
+
+ if (xc_tbuf_get_mfn(xc_handle, mfn) != 0)
+ goto fail;

xc_interface_close(xc_handle);
-
- if ( ret != 0 )
- {
- PERROR("Failure to get trace buffer pointer from Xen");
- exit(EXIT_FAILURE);
- }
-
- *mfn = op.u.tbufcontrol.buffer_mfn;
- *size = op.u.tbufcontrol.size;
+ return;
+
+fail:
+ PERROR("Failure to get trace buffer pointer from Xen");
+ exit(EXIT_FAILURE);
}

/**
@@ -133,14 +140,13 @@ struct t_buf *map_tbufs(unsigned long tb
struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
unsigned long size)
{
- int xc_handle; /* file descriptor for /proc/xen/privcmd */
+ int xc_handle;
struct t_buf *tbufs_mapped;

xc_handle = xc_interface_open();

if ( xc_handle < 0 )
{
- PERROR("Open /proc/xen/privcmd when mapping trace buffers\n");
exit(EXIT_FAILURE);
}

@@ -167,24 +173,17 @@ struct t_buf *map_tbufs(unsigned long tb
*/
void set_mask(uint32_t mask, int type)
{
- int ret;
- dom0_op_t op; /* dom0 op we'll build */
+ int ret = 0;
int xc_handle = xc_interface_open(); /* for accessing control interface */

- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- if (type == 1) { /* cpu mask */
- op.u.tbufcontrol.op = DOM0_TBUF_SET_CPU_MASK;
- op.u.tbufcontrol.cpu_mask = mask;
+ if (type == 1) {
+ ret = xc_tbuf_set_cpu_mask(xc_handle, mask);
fprintf(stderr, "change cpumask to 0x%x\n", mask);
- }else if (type == 0) { /* event mask */
- op.u.tbufcontrol.op = DOM0_TBUF_SET_EVT_MASK;
- op.u.tbufcontrol.evt_mask = mask;
+ } else if (type == 0) {
+ ret = xc_tbuf_set_evt_mask(xc_handle, mask);
fprintf(stderr, "change evtmask to 0x%x\n", mask);
}

- ret = do_dom0_op(xc_handle, &op);
-
xc_interface_close(xc_handle);

if ( ret != 0 )
@@ -192,7 +191,6 @@ void set_mask(uint32_t mask, int type)
PERROR("Failure to get trace buffer pointer from Xen and set the new mask");
exit(EXIT_FAILURE);
}
-
}

/**
@@ -260,14 +258,11 @@ struct t_rec **init_rec_ptrs(struct t_bu
*/
unsigned int get_num_cpus(void)
{
- dom0_op_t op;
+ xc_physinfo_t physinfo;
int xc_handle = xc_interface_open();
int ret;

- op.cmd = DOM0_PHYSINFO;
- op.interface_version = DOM0_INTERFACE_VERSION;
-
- ret = do_dom0_op(xc_handle, &op);
+ ret = xc_physinfo(xc_handle, &physinfo);

if ( ret != 0 )
{
@@ -277,10 +272,10 @@ unsigned int get_num_cpus(void)

xc_interface_close(xc_handle);

- return (op.u.physinfo.threads_per_core *
- op.u.physinfo.cores_per_socket *
- op.u.physinfo.sockets_per_node *
- op.u.physinfo.nr_nodes);
+ return (physinfo.threads_per_core *
+ physinfo.cores_per_socket *
+ physinfo.sockets_per_node *
+ physinfo.nr_nodes);
}


diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/configure.ac Mon May 08 14:46:11 2006 -0600
@@ -1,7 +1,7 @@
# xm-test configure.ac input script

# Basic header information
-AC_INIT([xm-test], [0.7.0])
+AC_INIT([xm-test], [0.7.1])
AM_INIT_AUTOMAKE([1.7 foreign])

# Check for dependencies
@@ -13,7 +13,7 @@ AC_CHECK_PROG([LILO], lilo, lilo, "no",
# are two levels above the tests
TESTLIB=../../lib
RD_PATH=../../ramdisk
-TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:/usr/lib/python RD_PATH=$RD_PATH"
+TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB RD_PATH=$RD_PATH"

AC_ARG_ENABLE(hvm-support,
[[ --enable-hvm-support enable hardware virtual machine assist]],
@@ -37,6 +37,36 @@ fi

AM_CONDITIONAL(HVM, test x$ENABLE_HVM = xTrue)
AC_SUBST(ENABLE_HVM)
+
+# Network needs to know ips to use: dhcp or a range of IPs in the form
+# of: 192.168.1.1-192.168.1.100
+# If not dhcp, a netmask and network address must be supplied. Defaults to
+# zeroconf range.
+NET_IP_RANGE="169.254.0.1-169.254.255.255"
+AC_ARG_WITH(net-ip-range,
+ [. --with-net-ip-range=ip-range Set a range of ip addresses to use for xm-test guest domain networks. Can specify dhcp or a range of IPs: 192.168.1.1-192.168.1.100 [[default="169.254.0.1-169.254.255.255"]]],
+ [ NET_IP_RANGE="$withval" ])
+
+iprange=`echo $NET_IP_RANGE | perl -e 'while(<>) { print if /\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+/ }'`
+
+NETWORK_ADDRESS="169.254.0.0"
+AC_ARG_WITH(network-address,
+ [. --with-network-address=ip Set network address to use with ip range [[default="169.254.0.0"]]],
+ [ NETWORK_ADDRESS="$withval" ])
+
+NETMASK="255.255.0.0"
+AC_ARG_WITH(netmask,
+ [ --with-netmask=mask Set netmask to use with ip range [[default="255.255.0.0"]]],
+ [ NETMASK="$withval" ])
+
+if test "x$NET_IP_RANGE" != "xdhcp" && test -z "$iprange"
+then
+ AC_MSG_ERROR(Invalid net-ip-range.)
+fi
+
+AC_SUBST(NET_IP_RANGE)
+AC_SUBST(NETWORK_ADDRESS)
+AC_SUBST(NETMASK)

AC_ARG_WITH(hvm-kernel,
[[ --with-hvm-kernel=kernel Use this kernel for hvm disk.img testing]],
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/Console.py
--- a/tools/xm-test/lib/XmTestLib/Console.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/Console.py Mon May 08 14:46:11 2006 -0600
@@ -234,11 +234,14 @@ class XmConsole:
"return": 0,
}

- def closeConsole(self):
+ def __closeConsole(self):
"""Closes the console connection and ensures that the console
- process is killed"""
- os.close(self.consoleFd)
- os.kill(self.consolePid, 2)
+ process is killed. This should only be called by the domain.
+ Tests should call domain.closeConsole()"""
+ if self.consolePid != 0:
+ os.close(self.consoleFd)
+ os.kill(self.consolePid, 2)
+ self.consolePid = 0


def setLimit(self, limit):
@@ -249,6 +252,10 @@ class XmConsole:
self.limit = int(limit)
except Exception, e:
self.limit = None
+
+ def setHistorySaveCmds(self, value):
+ # True or False
+ self.historySaveCmds = value


if __name__ == "__main__":
@@ -272,7 +279,7 @@ if __name__ == "__main__":
print "Console failed (%)" % str(e)
sys.exit(255)

- t.closeConsole()
+ t._XmConsole__closeConsole()

print run["output"],
sys.exit(run["return"])
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/Test.py
--- a/tools/xm-test/lib/XmTestLib/Test.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/Test.py Mon May 08 14:46:11 2006 -0600
@@ -173,8 +173,7 @@ def isConsoleDead():
domain = XmTestDomain()

try:
- domain.start()
- console = XmConsole(domain.getName())
+ console = domain.start()
console.runCmd("ls")
except DomainError, e:
return True
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/XenDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenDomain.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/XenDomain.py Mon May 08 14:46:11 2006 -0600
@@ -27,6 +27,8 @@ from Xm import *
from Xm import *
from Test import *
from config import *
+from Console import *
+from XenDevice import *

BLOCK_ROOT_DEV = "hda"

@@ -193,8 +195,18 @@ class XenDomain:
self.name = getUniqueName()

self.config = config
-
- def start(self):
+ self.console = None
+ self.devices = {}
+ self.netEnv = "bridge"
+
+ # Set domain type, either PV for ParaVirt domU or HVM for
+ # FullVirt domain
+ if ENABLE_HVM_SUPPORT:
+ self.type = "HVM"
+ else:
+ self.type = "PV"
+
+ def start(self, noConsole=False):

ret, output = traceCommand("xm create %s" % self.config)

@@ -203,10 +215,32 @@ class XenDomain:
extra=output,
errorcode=ret)

+ # HVM domains require waiting for boot
+ if self.getDomainType() == "HVM":
+ waitForBoot()
+
+ # Go through device list and run console cmds
+ for dev in self.devices.keys():
+ self.devices[dev].execAddCmds()
+
+ if self.console and noConsole == True:
+ self.closeConsole()
+
+ elif self.console and noConsole == False:
+ return self.console
+
+ elif not self.console and noConsole == False:
+ return self.getConsole()
+
def stop(self):
prog = "xm"
cmd = " shutdown "

+ self.removeAllDevices()
+
+ if self.console:
+ self.closeConsole()
+
ret, output = traceCommand(prog + cmd + self.config.getOpt("name"))

return ret
@@ -215,6 +249,11 @@ class XenDomain:
prog = "xm"
cmd = " destroy "

+ self.removeAllDevices()
+
+ if self.console:
+ self.closeConsole()
+
ret, output = traceCommand(prog + cmd + self.config.getOpt("name"))

return ret
@@ -224,6 +263,71 @@ class XenDomain:

def getId(self):
return domid(self.getName());
+
+ def getDomainType(self):
+ return self.type
+
+ def closeConsole(self):
+ # The domain closeConsole command must be called by tests, not the
+ # console's close command. Once close is called, the console is
+ # gone. You can't get history or anything else from it.
+ if self.console:
+ self.console._XmConsole__closeConsole()
+ self.console = None
+
+ def getConsole(self):
+ if self.console:
+ self.closeConsole()
+
+ self.console = XmConsole(self.getName())
+ # Activate the console
+ self.console.sendInput("input")
+
+ return self.console
+
+ def newDevice(self, Device, *args):
+ """Device Factory: Generic factory for creating new XenDevices.
+ All device creation should be done through the XenDomain
+ factory. Supply a XenDevice instance and its args and the
+ constructor will be called."""
+ # Make sure device with id hasn't already been added
+ if self.devices.has_key(args[0]):
+ raise DeviceError("Error: Domain already has device %s" % args[0])
+
+ # Call constructor for supplied Device instance
+ dargs = (self,)
+ dargs += args
+ dev = apply(Device, dargs)
+
+ if self.isRunning():
+ # Note: This needs to be done, XenDevice should have an attach
+ # method.
+ print "Domain is running, need to attach new device to domain."
+
+ self.devices[dev.id] = dev
+ self.config.appOpt(dev.configNode, str(dev))
+ return dev
+
+ def removeDevice(self, id):
+ if self.devices.has_key(id):
+ self.devices[id].removeDevice()
+
+ def removeAllDevices(self):
+ for k in self.devices.keys():
+ self.removeDevice(k)
+
+ def isRunning(self):
+ return isDomainRunning(self.name)
+
+ def getNetEnv(self):
+ # We need to know the network environment: bridge, NAT, or routed.
+ return self.netEnv
+
+ def getDevice(self, id):
+ dev = self.devices[id]
+ if dev:
+ return dev
+ print "Device %s not found for domain %s" % (id, self.getName())


class XmTestDomain(XenDomain):
@@ -246,13 +350,32 @@ class XmTestDomain(XenDomain):

XenDomain.__init__(self, config.getOpt("name"), config=config)

- def start(self):
- XenDomain.start(self)
- if ENABLE_HVM_SUPPORT:
- waitForBoot()
-
def minSafeMem(self):
return 32
+
+class XmTestNetDomain(XmTestDomain):
+
+ def __init__(self, name=None, extraConfig=None, baseConfig=configDefaults):
+ """Create a new xm-test domain with one network device
+ @param name: The requested domain name
+ @param extraConfig: Additional configuration options
+ @param baseConfig: The initial configuration defaults to use
+ """
+ config = XenConfig()
+ config.setOpts(baseConfig)
+ if extraConfig:
+ config.setOpts(extraConfig)
+
+ if name:
+ config.setOpt("name", name)
+ elif not config.getOpt("name"):
+ config.setOpt("name", getUniqueName())
+
+ XenDomain.__init__(self, config.getOpt("name"), config=config)
+
+ # Add one network devices to domain
+ self.newDevice(XenNetDevice, "eth0")
+

if __name__ == "__main__":

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/__init__.py
--- a/tools/xm-test/lib/XmTestLib/__init__.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/__init__.py Mon May 08 14:46:11 2006 -0600
@@ -3,21 +3,44 @@
# Author: Dan Smith <danms@us.ibm.com>
#

+import os.path
+import sys
+
+# Use the auxbin module in Xend to determine the correct Python path. We
+# take the first installed instance of auxbin that we find, and then run it
+# to determine the correct path, appending that to sys.path.
+
+AUXBIN = 'xen/util/auxbin.py'
+
+for p in ['python%s' % sys.version[:3], 'python']:
+ for l in ['/usr/lib64', '/usr/lib']:
+ d = os.path.join(l, p)
+ if os.path.exists(os.path.join(d, AUXBIN)):
+ sys.path.append(d)
+ import xen.util.auxbin
+ libpath = xen.util.auxbin.libpath()
+ sys.path = sys.path[:-1]
+ sys.path.append(libpath)
+ break
+
from Console import *
-from Network import *
from Test import *
from Xm import *
from XenDomain import *
from config import *
+from XenDevice import *
+from NetConfig import *

# Give this test a clean slate
-destroyAllDomUs();
+destroyAllDomUs()

if os.environ.get("TEST_VERBOSE"):
verbose = True
else:
verbose = False

-
if verbose:
timeStamp()
+
+# We need to track network configuration, like ips, etc.
+xmtest_netconf = NetConfig()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/config.py.in
--- a/tools/xm-test/lib/XmTestLib/config.py.in Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/config.py.in Mon May 08 14:46:11 2006 -0600
@@ -1,4 +1,6 @@
#!/usr/bin/python

ENABLE_HVM_SUPPORT = @ENABLE_HVM@
-
+NETWORK_IP_RANGE = "@NET_IP_RANGE@"
+NETWORK = "@NETWORK_ADDRESS@"
+NETMASK = "@NETMASK@"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/ramdisk/Makefile.am Mon May 08 14:46:11 2006 -0600
@@ -2,7 +2,7 @@ INITRD ?= http://xm-test.xensource.com/r

EXTRA_DIST = skel configs patches

-BR_TAR = buildroot-20060215.tar.bz2
+BR_TAR = buildroot-20060427.tar.bz2
BR_URL = http://buildroot.uclibc.org/downloads/snapshots/$(BR_TAR)
#BR_URL = http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2
BR_SRC = buildroot
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/ramdisk/configs/buildroot
--- a/tools/xm-test/ramdisk/configs/buildroot Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/ramdisk/configs/buildroot Mon May 08 14:46:11 2006 -0600
@@ -15,7 +15,7 @@ BR2_i386=y
# BR2_sh is not set
# BR2_sparc is not set
# BR2_x86_64 is not set
-BR2_x86_i386=y
+BR2_x86_i386=y
# BR2_x86_i486 is not set
# BR2_x86_i586 is not set
# BR2_x86_i686 is not set
@@ -69,29 +69,34 @@ BR2_PTHREADS_OLD=y
# BR2_BINUTILS_VERSION_2_15 is not set
# BR2_BINUTILS_VERSION_2_15_94_0_2_2 is not set
# BR2_BINUTILS_VERSION_2_15_97 is not set
-BR2_BINUTILS_VERSION_2_16_1=y
+# BR2_BINUTILS_VERSION_2_16_1 is not set
# BR2_BINUTILS_VERSION_2_16_90_0_3 is not set
# BR2_BINUTILS_VERSION_2_16_91_0_3 is not set
# BR2_BINUTILS_VERSION_2_16_91_0_4 is not set
# BR2_BINUTILS_VERSION_2_16_91_0_5 is not set
# BR2_BINUTILS_VERSION_2_16_91_0_6 is not set
-BR2_BINUTILS_VERSION="2.16.1"
+BR2_BINUTILS_VERSION_2_16_91_0_7=y
+BR2_BINUTILS_VERSION="2.16.91.0.7"
+BR2_EXTRA_BINUTILS_CONFIG_OPTIONS=""

#
# Gcc Options
#
# BR2_GCC_VERSION_3_3_5 is not set
# BR2_GCC_VERSION_3_3_6 is not set
-BR2_GCC_VERSION_3_4_2=y
+# BR2_GCC_VERSION_3_4_2 is not set
# BR2_GCC_VERSION_3_4_3 is not set
# BR2_GCC_VERSION_3_4_4 is not set
# BR2_GCC_VERSION_3_4_5 is not set
+BR2_GCC_VERSION_3_4_6=y
# BR2_GCC_VERSION_4_0_0 is not set
# BR2_GCC_VERSION_4_0_1 is not set
# BR2_GCC_VERSION_4_0_2 is not set
+# BR2_GCC_VERSION_4_0_3 is not set
# BR2_GCC_VERSION_4_1_0 is not set
-# BR2_GCC_VERSION_4_2_0 is not set
-BR2_GCC_VERSION="3.4.2"
+# BR2_GCC_VERSION_4_2 is not set
+# BR2_GCC_IS_SNAP is not set
+BR2_GCC_VERSION="3.4.6"
# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set
BR2_EXTRA_GCC_CONFIG_OPTIONS=""
# BR2_INSTALL_LIBSTDCPP is not set
@@ -107,7 +112,7 @@ BR2_CCACHE=y
#
# BR2_PACKAGE_GDB is not set
# BR2_PACKAGE_GDB_SERVER is not set
-# BR2_PACKAGE_GDB_CLIENT is not set
+# BR2_PACKAGE_GDB_HOST is not set

#
# elf2flt
@@ -176,6 +181,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG="package/busy
# BR2_PACKAGE_DM is not set
# BR2_PACKAGE_DNSMASQ is not set
# BR2_PACKAGE_DROPBEAR is not set
+# BR2_PACKAGE_ETHTOOL is not set
# BR2_PACKAGE_EXPAT is not set
# BR2_PACKAGE_E2FSPROGS is not set
# BR2_PACKAGE_FAKEROOT is not set
@@ -184,6 +190,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG="package/busy
# BR2_PACKAGE_GETTEXT is not set
# BR2_PACKAGE_LIBINTL is not set
# BR2_PACKAGE_GZIP is not set
+# BR2_PACKAGE_HASERL is not set
# BR2_PACKAGE_HOSTAP is not set
# BR2_PACKAGE_HOTPLUG is not set
# BR2_PACKAGE_IOSTAT is not set
@@ -253,6 +260,7 @@ BR2_QTE_TMAKE_VERSION="1.13"
# BR2_PACKAGE_SMARTMONTOOLS is not set
# BR2_PACKAGE_SOCAT is not set
# BR2_PACKAGE_STRACE is not set
+# BR2_PACKAGE_SUDO is not set
# BR2_PACKAGE_SYSKLOGD is not set
# BR2_PACKAGE_SYSVINIT is not set
# BR2_PACKAGE_TCL is not set
@@ -265,6 +273,7 @@ BR2_QTE_TMAKE_VERSION="1.13"
# BR2_PACKAGE_TTCP is not set
# BR2_PACKAGE_UDEV is not set
# BR2_PACKAGE_UDHCP is not set
+# BR2_PACKAGE_UEMACS is not set
# BR2_PACKAGE_USBUTILS is not set
# BR2_PACKAGE_UTIL-LINUX is not set
# BR2_PACKAGE_VALGRIND is not set
@@ -298,6 +307,7 @@ BR2_TARGET_ROOTFS_EXT2_COPYTO=""
# BR2_TARGET_ROOTFS_JFFS2 is not set
# BR2_TARGET_ROOTFS_SQUASHFS is not set
# BR2_TARGET_ROOTFS_TAR is not set
+# BR2_TARGET_ROOTFS_ISO9660 is not set

#
# bootloader for target device
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/_sanity/01_domu_proc.py
--- a/tools/xm-test/tests/_sanity/01_domu_proc.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/_sanity/01_domu_proc.py Mon May 08 14:46:11 2006 -0600
@@ -15,13 +15,11 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL(str(e))

try:
- console = XmConsole(domain.getName())
- console.sendInput("foo")
run = console.runCmd("cat /proc/cpuinfo")
except ConsoleError, e:
FAIL(str(e))
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/01_block_attach_device_pos.py
--- a/tools/xm-test/tests/block-create/01_block_attach_device_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/01_block_attach_device_pos.py Mon May 08 14:46:11 2006 -0600
@@ -3,11 +3,10 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-attach not supported for HVM domains")
@@ -16,7 +15,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
@@ -25,13 +24,7 @@ except DomainError, e:

# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -39,9 +32,7 @@ except ConsoleError, e:
FAIL(str(e))


-status, output = traceCommand("xm block-attach %s phy:ram1 sdb1 w" % domain.getName())
-if status != 0:
- FAIL("xm block-attach returned invalid %i != 0" % status)
+block_attach(domain, "phy:ram1", "sdb1")

try:
run = console.runCmd("cat /proc/partitions")
@@ -49,7 +40,7 @@ except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py
--- a/tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py Mon May 08 14:46:11 2006 -0600
@@ -3,11 +3,10 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-attach not supported for HVM domains")
@@ -16,22 +15,16 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
+# Set console to save commands and make sure we can run cmds
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -39,9 +32,7 @@ except ConsoleError, e:
FAIL(str(e))


-status, output = traceCommand("xm block-attach %s file:/dev/ram1 sdb2 w" % domain.getName())
-if status != 0:
- FAIL("xm block-attach returned invalid %i != 0" % status)
+block_attach(domain, "file:/dev/ram1", "sdb2")

try:
run = console.runCmd("cat /proc/partitions")
@@ -49,7 +40,7 @@ except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py
--- a/tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py Mon May 08 14:46:11 2006 -0600
@@ -3,9 +3,7 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *

@@ -16,22 +14,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -49,7 +40,7 @@ for i in range(10):
FAIL("Device is not actually attached to domU")

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py
--- a/tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py Mon May 08 14:46:11 2006 -0600
@@ -3,11 +3,10 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-attach not supported for HVM domains")
@@ -16,22 +15,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -40,24 +32,18 @@ except ConsoleError, e:


for i in range(10):
- status, output = traceCommand("xm block-attach %s phy:ram1 sdb1 w" % domain.getName())
- if status != 0:
- FAIL("xm block-attach returned invalid %i != 0" % status)
- # verify that it comes
+ block_attach(domain, "phy:ram1", "sdb1")
run = console.runCmd("cat /proc/partitions")
if not re.search("sdb1", run["output"]):
FAIL("Failed to attach block device: /proc/partitions does not show that!")

- status, output = traceCommand("xm block-detach %s 2065" % domain.getName())
- if status != 0:
- FAIL("xm block-detach returned invalid %i != 0" % status)
- # verify that it goes
+ block_detach(domain, "sdb1")
run = console.runCmd("cat /proc/partitions")
if re.search("sdb1", run["output"]):
FAIL("Failed to dettach block device: /proc/partitions still showing that!")

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py
--- a/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py Mon May 08 14:46:11 2006 -0600
@@ -3,9 +3,7 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *

@@ -16,22 +14,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -53,7 +44,7 @@ except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py
--- a/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py Mon May 08 14:46:11 2006 -0600
@@ -3,9 +3,7 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *

@@ -16,22 +14,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -52,7 +43,7 @@ except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py
--- a/tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py Mon May 08 14:46:11 2006 -0600
@@ -3,11 +3,10 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-attach not supported for HVM domains")
@@ -16,22 +15,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -43,10 +35,7 @@ if s != 0:
FAIL("mke2fs returned %i != 0" % s)

for i in range(10):
- status, output = traceCommand("xm block-attach %s phy:ram1 hda1 w" % domain.getName())
- if status != 0:
- FAIL("xm block-attach returned invalid %i != 0" % status)
- # verify that it comes
+ block_attach(domain, "phy:ram1", "hda1")
run = console.runCmd("cat /proc/partitions")
if not re.search("hda1", run["output"]):
FAIL("Failed to attach block device: /proc/partitions does not show that!")
@@ -63,16 +52,13 @@ for i in range(10):
print run['output']
console.runCmd("umount /mnt/hda1")

- status, output = traceCommand("xm block-detach %s 769" % domain.getName())
- if status != 0:
- FAIL("xm block-detach returned invalid %i != 0" % status)
- # verify that it goes
+ block_detach(domain, "hda1")
run = console.runCmd("cat /proc/partitions")
if re.search("hda1", run["output"]):
FAIL("Failed to dettach block device: /proc/partitions still showing that!")

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py
--- a/tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py Mon May 08 14:46:11 2006 -0600
@@ -3,15 +3,14 @@
# Copyright (C) International Business Machines Corp., 2005
# Author: Murillo F. Bernardes <mfb@br.ibm.com>

-import sys
import re
-import time
import random
from xen.util import blkif

from os import path.basename

from XmTestLib import *
+from XmTestLib.block_utils import *

def availableRamdisks():
i = 0
@@ -21,11 +20,7 @@ def availableRamdisks():
return i

def attach(phy, devname):
- # Attach
- status, output = traceCommand("xm block-attach %s phy:%s %s w" % (domain.getName(), phy, devname))
- if status != 0:
- return -1, "xm block-attach returned invalid %i != 0" % status
-
+ block_attach(domain, "phy:%s" % phy, devname)
run = console.runCmd("cat /proc/partitions")
if not re.search(basename(devname), run["output"]):
return -2, "Failed to attach block device: /proc/partitions does not show that!"
@@ -33,16 +28,12 @@ def attach(phy, devname):
return 0, None


-def dettach(devname):
- devnum = blkif.blkdev_name_to_number(devname)
-
- status, output = traceCommand("xm block-detach %s %d" % (domain.getName(), devnum))
- if status != 0:
- return -1, "xm block-attach returned invalid %i != 0" % status
+def detach(devname):
+ block_detach(domain, devname)

run = console.runCmd("cat /proc/partitions")
if re.search(basename(devname), run["output"]):
- return -2, "Failed to dettach block device: /proc/partitions still showing that!"
+ return -2, "Failed to detach block device: /proc/partitions still showing that!"

return 0, None

@@ -53,22 +44,15 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -98,12 +82,12 @@ while i < ramdisks or devices:
devname = random.choice(devices)
devices.remove(devname)
print "Detaching %s" % devname
- status, msg = dettach(devname)
+ status, msg = detach(devname)
if status:
FAIL(msg)

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py
--- a/tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py Mon May 08 14:46:11 2006 -0600
@@ -4,6 +4,7 @@
# Author: Dan Smith <danms@us.ibm.com>

from XmTestLib import *
+from XmTestLib.block_utils import block_detach

if ENABLE_HVM_SUPPORT:
SKIP("Block-detach not supported for HVM domains")
@@ -12,15 +13,14 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain")

try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- console.sendInput("input")
+ console.setHistorySaveCmds(value=True)
run = console.runCmd("cat /proc/partitions | grep hda1")
run2 = console.runCmd("cat /proc/partitions")
except ConsoleError, e:
@@ -29,11 +29,7 @@ if run["return"] != 0:
if run["return"] != 0:
FAIL("block device isn't attached; can't detach!")

-status, output = traceCommand("xm block-detach %s 769" % domain.getName(),
- logOutput=True)
-if status != 0:
- FAIL("block-detach returned invalid %i != 0" % status)
-
+block_detach(domain, "hda1")
try:

run = console.runCmd("cat /proc/partitions | grep hda1")
@@ -41,7 +37,7 @@ except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()
domain.stop()

if run["return"] == 0:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py
--- a/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py Mon May 08 14:46:11 2006 -0600
@@ -4,6 +4,7 @@
# Author: Dan Smith <danms@us.ibm.com>

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-detach not supported for HVM domains")
@@ -11,24 +12,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain")

-status, output = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % domain.getName())
-if status != 0:
- FAIL("Failed to attach block device")
- pass
-
+block_attach(domain, "phy:/dev/ram0", "hda1")
try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- console.sendInput("input")
run = console.runCmd("cat /proc/partitions | grep hda1")
except ConsoleError, e:
saveLog(console.getHistory())
@@ -37,17 +28,14 @@ if run["return"] != 0:
if run["return"] != 0:
FAIL("Failed to verify that block dev is attached")

-status, output = traceCommand("xm block-detach %s 769" % domain.getName())
-if status != 0:
- FAIL("block-detach returned invalid %i != 0" % status)
-
+block_detach(domain, "hda1")
try:
run = console.runCmd("cat /proc/partitions | grep hda1")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

+domain.stop()
+
if run["return"] == 0:
FAIL("block-detach failed to detach block device")
-
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py
--- a/tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py Mon May 08 14:46:11 2006 -0600
@@ -13,7 +13,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print e.extra
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py
--- a/tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py Mon May 08 14:46:11 2006 -0600
@@ -4,6 +4,7 @@
# Author: Dan Smith <danms@us.ibm.com>

from XmTestLib import *
+from XmTestLib.block_utils import block_detach

if ENABLE_HVM_SUPPORT:
SKIP("Block-detach not supported for HVM domains")
@@ -12,15 +13,13 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain")

try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- console.sendInput("input")
run = console.runCmd("cat /proc/partitions | grep hda1")
run2 = console.runCmd("cat /proc/partitions")
except ConsoleError, e:
@@ -29,11 +28,7 @@ if run["return"] != 0:
if run["return"] != 0:
FAIL("block device isn't attached; can't detach!")

-status, output = traceCommand("xm block-detach %s hda1" % domain.getName(),
- logOutput=True)
-if status != 0:
- FAIL("block-detach returned invalid %i != 0" % status)
-
+block_detach(domain, "hda1")
try:

run = console.runCmd("cat /proc/partitions | grep hda1")
@@ -41,7 +36,7 @@ except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()
domain.stop()

if run["return"] == 0:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py
--- a/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py Mon May 08 14:46:11 2006 -0600
@@ -4,18 +4,9 @@
# Author: Dan Smith <danms@us.ibm.com>

from XmTestLib import *
+from XmTestLib.block_utils import *

-import time
import re
-
-def checkBlockList(domain):
- s, o = traceCommand("xm block-list %s" % domain.getName())
- if s != 0:
- FAIL("block-list failed")
- if re.search("769", o):
- return True
- else:
- return False

def checkXmLongList(domain):
s, o = traceCommand("xm list --long %s" % domain.getName())
@@ -36,28 +27,12 @@ except DomainError,e:
except DomainError,e:
FAIL(str(e))

-s, o = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % domain.getName())
-if s != 0:
- FAIL("block-attach failed")
-
-if not checkBlockList(domain):
- FAIL("block-list does not show that hda1 was attached")
+block_attach(domain, "phy:/dev/ram0", "hda1")

if not checkXmLongList(domain):
FAIL("xm long list does not show that hda1 was attached")

-time.sleep(2)
-
-s, o = traceCommand("xm block-detach %s hda1" % domain.getName())
-if s != 0:
- FAIL("block-detach failed")
-
-time.sleep(2)
-
-if checkBlockList(domain):
- FAIL("block-list does not show that hda1 was removed")
+block_detach(domain, "hda1")

if checkXmLongList(domain):
FAIL("xm long list does not show that hda1 was removed")
-
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-list/01_block-list_pos.py
--- a/tools/xm-test/tests/block-list/01_block-list_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-list/01_block-list_pos.py Mon May 08 14:46:11 2006 -0600
@@ -15,7 +15,7 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
@@ -31,16 +31,12 @@ elif where < 0:

#Verify the block device on DomainU
try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- console.sendInput("input")
run = console.runCmd("cat /proc/partitions | grep hda1")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

+domain.stop()
+
if run["return"] != 0:
FAIL("Failed to verify that block dev is attached on DomainU")
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py
--- a/tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py Mon May 08 14:46:11 2006 -0600
@@ -1,5 +1,5 @@
#!/usr/bin/python
-
+
# Copyright (C) International Business Machines Corp., 2005
# Author: Li Ge <lge@us.ibm.com)

@@ -7,23 +7,22 @@


from XmTestLib import *
+from XmTestLib.block_utils import block_attach

if ENABLE_HVM_SUPPORT:
SKIP("Block-list not supported for HVM domains")

domain = XmTestDomain()
-
+
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain")

#Attach one virtual block device to domainU
-status, output = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % domain.getId())
-if status != 0:
- FAIL("Fail to attach block device")
+block_attach(domain, "phy:/dev/ram0", "hda1")

#Verify block-list on Domain0
status, output = traceCommand("xm block-list %s" % domain.getId())
@@ -36,16 +35,12 @@ elif where < 0 :

#Verify attached block device on DomainU
try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- console.sendInput("input")
run = console.runCmd("cat /proc/partitions | grep hda1")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

+domain.stop()
+
if run["return"] != 0:
FAIL("Failed to verify that block dev is attached on DomainU")
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py
--- a/tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py Mon May 08 14:46:11 2006 -0600
@@ -15,7 +15,7 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
@@ -43,16 +43,12 @@ elif (where1 < 0) and (where2 < 0):

#Verify attached block device on DomainU
try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- console.sendInput("input")
run = console.runCmd("cat /proc/partitions | grep hda1;cat /proc/partitions | grep hda2")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))

+domain.stop()
+
if run["return"] != 0:
FAIL("Failed to verify that block dev is attached on DomainU")
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-list/04_block-list_nodb_pos.py
--- a/tools/xm-test/tests/block-list/04_block-list_nodb_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-list/04_block-list_nodb_pos.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print e.extra
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py
--- a/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py Mon May 08 14:46:11 2006 -0600
@@ -4,6 +4,7 @@
# Author: Dan Smith <danms@us.ibm.com>

from XmTestLib import *
+from XmTestLib.block_utils import *

if ENABLE_HVM_SUPPORT:
SKIP("Block-list not supported for HVM domains")
@@ -11,13 +12,8 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
- FAIL(str(e))
-
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
FAIL(str(e))

s, o = traceCommand("xm block-list %s" % domain.getName())
@@ -26,9 +22,7 @@ if o:
if o:
FAIL("block-list without devices reported something!")

-s, o = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % domain.getName())
-if s != 0:
- FAIL("Unable to attach /dev/ram0->hda1")
+block_attach(domain, "phy:/dev/ram0", "hda1")

s, o = traceCommand("xm block-list %s" % domain.getName())
if s != 0:
@@ -36,9 +30,7 @@ if o.find("769") == -1:
if o.find("769") == -1:
FAIL("block-list didn't show the block device I just attached!")

-s, o = traceCommand("xm block-attach %s phy:/dev/ram1 hda2 w" % domain.getName())
-if s != 0:
- FAIL("Unable to attach /dev/ram1->hda2")
+block_attach(domain, "phy:/dev/ram1", "hda2")

s, o = traceCommand("xm block-list %s" % domain.getName())
if s != 0:
@@ -46,11 +38,8 @@ if o.find("770") == -1:
if o.find("770") == -1:
FAIL("block-list didn't show the other block device I just attached!")

-s, o = traceCommand("xm block-detach %s 769" % domain.getName())
-if s != 0:
- FAIL("block-detach of hda1 failed")
+block_detach(domain, "hda1")

-time.sleep(1)
s, o = traceCommand("xm block-list %s" % domain.getName())
if s != 0:
FAIL("block-list failed after detaching a device")
@@ -59,11 +48,8 @@ if o.find("770") == -1:
if o.find("770") == -1:
FAIL("hda2 not shown after detach of hda1!")

-s, o = traceCommand("xm block-detach %s 770" % domain.getName())
-if s != 0:
- FAIL("block-detach of hda2 failed")
+block_detach(domain, "hda2")

-time.sleep(1)
s, o = traceCommand("xm block-list %s" % domain.getName())
if s != 0:
FAIL("block-list failed after detaching another device")
@@ -72,4 +58,4 @@ if o:
if o:
FAIL("block-list still shows something after all devices detached!")

-
+domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/01_create_basic_pos.py
--- a/tools/xm-test/tests/create/01_create_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/01_create_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -18,36 +18,28 @@ if int(getInfo("free_memory")) < domain.

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
+
+# Save a transcript for human review
+saveLog(console.getHistory())

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
-
-# Save a transcript for human review
-saveLog(console.getHistory())

# Check the output of 'ls'

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/04_create_conflictname_neg.py
--- a/tools/xm-test/tests/create/04_create_conflictname_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/04_create_conflictname_neg.py Mon May 08 14:46:11 2006 -0600
@@ -17,7 +17,7 @@ domain1 = XmTestDomain("default")

#start it
try:
- domain1.start()
+ domain1.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain1 because:"
@@ -30,7 +30,7 @@ domain2 = XmTestDomain("default")
#start it
eyecatcher = "Pass"
try:
- domain2.start()
+ domain2.start(noConsole=True)
except DomainError, e:
eyecatcher = "Fail"
# Stop the domain1 (nice shutdown)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/06_create_mem_neg.py
--- a/tools/xm-test/tests/create/06_create_mem_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/06_create_mem_neg.py Mon May 08 14:46:11 2006 -0600
@@ -23,7 +23,7 @@ domain1=XmTestDomain(extraConfig=config1
domain1=XmTestDomain(extraConfig=config1)

try:
- domain1.start()
+ domain1.start(noConsole=True)
eyecatcher1 = "Created"
except DomainError, e:
eyecatcher1 = "Fail"
@@ -42,7 +42,7 @@ domain2=XmTestDomain(extraConfig=config2
domain2=XmTestDomain(extraConfig=config2)

try:
- domain2.start()
+ domain2.start(noConsole=True)
eyecatcher2 = "Created"
except DomainError, e:
eyecatcher2 = "Fail"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/07_create_mem64_pos.py
--- a/tools/xm-test/tests/create/07_create_mem64_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/07_create_mem64_pos.py Mon May 08 14:46:11 2006 -0600
@@ -28,7 +28,7 @@ domain_mem64=XmTestDomain(extraConfig=co

#start it
try:
- domain_mem64.start()
+ domain_mem64.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain_mem64 because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/08_create_mem128_pos.py
--- a/tools/xm-test/tests/create/08_create_mem128_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/08_create_mem128_pos.py Mon May 08 14:46:11 2006 -0600
@@ -28,7 +28,7 @@ domain_mem128=XmTestDomain(extraConfig=c

#start it
try:
- domain_mem128.start()
+ domain_mem128.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain_mem128 because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/09_create_mem256_pos.py
--- a/tools/xm-test/tests/create/09_create_mem256_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/09_create_mem256_pos.py Mon May 08 14:46:11 2006 -0600
@@ -28,7 +28,7 @@ domain_mem256=XmTestDomain(extraConfig=c

#start it
try:
- domain_mem256.start()
+ domain_mem256.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain_mem256 because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/10_create_fastdestroy.py
--- a/tools/xm-test/tests/create/10_create_fastdestroy.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/10_create_fastdestroy.py Mon May 08 14:46:11 2006 -0600
@@ -28,7 +28,7 @@ for i in range(0,50):
for i in range(0,50):
domain = XmTestDomain("testdomain")
try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError,e:
print "Failed: " + e.extra
NSPerror = check_for_NSP_error(e.extra)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/11_create_concurrent_pos.py
--- a/tools/xm-test/tests/create/11_create_concurrent_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/11_create_concurrent_pos.py Mon May 08 14:46:11 2006 -0600
@@ -43,15 +43,13 @@ for d in range(0, NUM_DOMS):
extraConfig={"memory":MEM_PER_DOM})

try:
- dom.start()
+ cons = dom.start()
except DomainError, e:
if verbose:
print str(e)
FAIL("[%i] Failed to create domain" % d)

try:
- cons = XmConsole(dom.getName())
- cons.sendInput("foo")
cons.runCmd("ls")
except ConsoleError, e:
FAIL("[%i] Failed to attach console to %s" % (d, dom.getName()))
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/12_create_concurrent_stress_pos.py
--- a/tools/xm-test/tests/create/12_create_concurrent_stress_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/12_create_concurrent_stress_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,17 +17,11 @@ for i in range(0,DOMS):
dom = XmTestDomain(extraConfig={"memory" : MEM})

try:
- dom.start()
+ cons = dom.start()
except DomainError, e:
if verbose:
print str(e)
FAIL("Failed to start %s" % dom.getName())
-
- try:
- cons = XmConsole(dom.getName())
- cons.sendInput("foo")
- except ConsoleError, e:
- FAIL(str(e))

if verbose:
print "[%i/%i] Started %s" % (i, DOMS, dom.getName())
@@ -56,4 +50,3 @@ for d, c in domains:
if run["return"] != 0:
FAIL("Domain %s didn't survive!" % d.getName())

-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/13_create_multinic_pos.py
--- a/tools/xm-test/tests/create/13_create_multinic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/13_create_multinic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -5,26 +5,21 @@

from XmTestLib import *

-# The current device model, qemu-dm, only supports 8 MAX_NICS currently.
+# The device model, qemu-dm, only supports 8 MAX_NICS currently.
if ENABLE_HVM_SUPPORT:
MAX_NICS = 8
- nic = "type=ioemu, bridge=xenbr0"
else:
MAX_NICS = 10
- nic = ''

for i in range(0,MAX_NICS):
- config = {"vif": [ nic ] * i}
- domain = XmTestDomain(extraConfig=config)
+ domain = XmTestNetDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL("(%i nics) " % i + str(e))

try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
console.runCmd("ls")
except ConsoleError, e:
FAIL("(%i nics) Console didn't respond: probably crashed!" % i)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/14_create_blockroot_pos.py
--- a/tools/xm-test/tests/create/14_create_blockroot_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/14_create_blockroot_pos.py Mon May 08 14:46:11 2006 -0600
@@ -31,20 +31,14 @@ else:
domain = XenDomain(name=domConfig.getOpt("name"), config=domConfig)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL(str(e))

#waitForBoot()

try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
# console.debugMe = True
- console.sendInput("foo")
run = console.runCmd("ls")

except ConsoleError, e:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/15_create_smallmem_pos.py
--- a/tools/xm-test/tests/create/15_create_smallmem_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/15_create_smallmem_pos.py Mon May 08 14:46:11 2006 -0600
@@ -12,13 +12,11 @@ domain = XmTestDomain(extraConfig={"memo
"extra" :"mem=%iM" % MEM})

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL("Unable to start a domain with %i MB" % MEM)

try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
console.runCmd("ls")
except ConsoleError, e:
if e.reason == RUNAWAY:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/create/16_create_smallmem_neg.py
--- a/tools/xm-test/tests/create/16_create_smallmem_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/create/16_create_smallmem_neg.py Mon May 08 14:46:11 2006 -0600
@@ -13,14 +13,10 @@ domain = XmTestDomain(extraConfig={"memo
"extra" :"mem=%iM" % MEM})

try:
- domain.start()
+ console = domain.start()
+ console.runCmd("ls")
except DomainError, e:
FAIL("Unable to start a domain with %i MB" % MEM)
-
-try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
- console.runCmd("ls")
except ConsoleError, e:
if e.reason == RUNAWAY:
print "Domain with %i MB has runaway console as expected" % MEM
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/destroy/01_destroy_basic_pos.py
--- a/tools/xm-test/tests/destroy/01_destroy_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/destroy/01_destroy_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -14,29 +14,21 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("foo")
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Check the output of 'ls'
if not re.search("proc", run["output"]):
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/destroy/05_destroy_byid_pos.py
--- a/tools/xm-test/tests/destroy/05_destroy_byid_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/destroy/05_destroy_byid_pos.py Mon May 08 14:46:11 2006 -0600
@@ -7,8 +7,7 @@
# Positive Test:
# Test Description:
# 1. Create a domain
-# 2. Attach a console to the domain.
-# 3. Destroy the domain by id
+# 2. Destroy the domain by id

import sys
import re
@@ -21,7 +20,7 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/destroy/07_destroy_stale_pos.py
--- a/tools/xm-test/tests/destroy/07_destroy_stale_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/destroy/07_destroy_stale_pos.py Mon May 08 14:46:11 2006 -0600
@@ -108,14 +108,11 @@ def runTests(tests):
# Create a domain

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL(str(e))

- # Attach a console and make sure it's live
try:
- console = XmConsole(domain.getName())
- console.sendInput("foo")
console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/list/04_list_goodparm_pos.py
--- a/tools/xm-test/tests/list/04_list_goodparm_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/list/04_list_goodparm_pos.py Mon May 08 14:46:11 2006 -0600
@@ -12,23 +12,17 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-
status, output = traceCommand("xm list %s" % domain.getName())

if status != 0:
FAIL("`xm list %s' failed with invalid status %i != 0" % (domain.getName(), status))

-console.closeConsole()
+domain.closeConsole()
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/memset/01_memset_basic_pos.py
--- a/tools/xm-test/tests/memset/01_memset_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/memset/01_memset_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -28,24 +28,33 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
# Make sure it's up an running before we continue
console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))

+try:
+ run = console.runCmd("cat /proc/xen/balloon | grep Current");
+except ConsoleError, e:
+ FAIL(str(e))
+
+match = re.match("[^0-9]+([0-9]+)", run["output"])
+if not match:
+ FAIL("Invalid domU meminfo line")
+
+origmem = int(match.group(1)) / 1024
+newmem = origmem - 1
+
# set mem-set for less than default
-cmd = "xm mem-set %s %i" % (domain.getName(), 63)
+cmd = "xm mem-set %s %i" % (domain.getName(), newmem)
status, output = traceCommand(cmd)
if status != 0:
if verbose:
@@ -55,7 +64,7 @@ if status != 0:

for i in [1,2,3,4,5,6,7,8,9,10]:
mem = getDomMem(domain.getName())
- if mem == 63:
+ if mem == newmem:
break
time.sleep(1)

@@ -63,8 +72,8 @@ mem = getDomMem(domain.getName())
mem = getDomMem(domain.getName())
if not mem:
FAIL("Failed to get memory amount for domain %s" % domain.getName())
-elif mem != 63:
- FAIL("Dom0 failed to verify 63 MB; got %i MB" % mem)
+elif mem != newmem:
+ FAIL("Dom0 failed to verify %i MB; got %i MB" % newmem,mem)

# verify memory set internally
try:
@@ -79,12 +88,12 @@ if not m:

domUmem = int(m.group(1)) / 1024

-if domUmem != 63:
+if domUmem != newmem:
FAIL("DomU reported incorrect memory amount: %i MB" % (domUmem))

# quiesce everything
# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/memset/03_memset_random_pos.py
--- a/tools/xm-test/tests/memset/03_memset_random_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/memset/03_memset_random_pos.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to start domain:"
@@ -22,14 +22,24 @@ except DomainError, e:
FAIL(str(e))

times = random.randint(10,50)
-origmem = domain.config.getOpt("memory")
-currmem = domain.config.getOpt("memory")

try:
console = XmConsole(domain.getName())
console.sendInput("input")
except ConsoleError, e:
FAIL(str(e))
+
+try:
+ run = console.runCmd("cat /proc/xen/balloon | grep Current");
+except ConsoleError, e:
+ FAIL(str(e))
+
+match = re.match("[^0-9]+([0-9]+)", run["output"])
+if not match:
+ FAIL("Invalid domU meminfo line")
+
+origmem = int(match.group(1)) / 1024
+currmem = origmem

for i in range(0,times):
amt = random.randint(-10,10)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/memset/04_memset_smallmem_pos.py
--- a/tools/xm-test/tests/memset/04_memset_smallmem_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/memset/04_memset_smallmem_pos.py Mon May 08 14:46:11 2006 -0600
@@ -11,7 +11,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to start domain: "
@@ -19,8 +19,6 @@ except DomainError, e:
FAIL(str(e))

try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
# Make sure it's alive before we proceed
console.runCmd("ls")
except ConsoleError, e:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/migrate/01_migrate_localhost_pos.py
--- a/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py Mon May 08 14:46:11 2006 -0600
@@ -25,29 +25,21 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("foo")
# Set a variable to check on the other side
run = console.runCmd("foo=bar")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

old_domid = domid(domain.getName())

@@ -68,11 +60,12 @@ if (old_domid == new_domid):

# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
+ console = domain.getConsole()
console.debugMe = True
except ConsoleError, e:
pass

+console.setHistorySaveCmds(value=True)
console.sendInput("ls")

# Run 'ls'
@@ -86,7 +79,7 @@ if not re.search("bar", run["output"]):
FAIL("Migrated domain has been reset")

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network-attach/01_network_attach_pos.py
--- a/tools/xm-test/tests/network-attach/01_network_attach_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py Mon May 08 14:46:11 2006 -0600
@@ -15,22 +15,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -45,7 +37,7 @@ if status:

##
# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py
--- a/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,22 +17,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("input")
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -51,7 +43,7 @@ if status:


# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py
--- a/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,25 +17,16 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
-try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- # network-detach is crashing, so we enable console debugging
- # for now, so that reports include the oops
- console.debugMe = True
-except ConsoleError, e:
- FAIL(str(e))
+console.debugMe = True

try:
- # Activate the console
- console.sendInput("input")
# Run 'ls'
run = console.runCmd("ls")
except ConsoleError, e:
@@ -54,7 +45,7 @@ for i in range(10):
FAIL(msg)

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/02_network_local_ping_pos.py
--- a/tools/xm-test/tests/network/02_network_local_ping_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/02_network_local_ping_pos.py Mon May 08 14:46:11 2006 -0600
@@ -16,47 +16,27 @@ pingsizes = [. 1, 48, 64, 512, 1440, 1500
pingsizes = [. 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192,
32767, 65507 ]

-
-
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")

-# read an IP address from the config
-ip = Net.ip("dom1", "eth0")
-mask = Net.mask("dom1", "eth0")
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- config = {"vif" : ['type=ioemu']}
-else:
- config = {"vif" : ['ip=%s' % ip ]}
-
-domain = XmTestDomain(extraConfig=config)
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("bhs")
-
- # Bring up the "lo" interface.
- console.runCmd("ifconfig lo 127.0.0.1")
-
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+ console.setHistorySaveCmds(value=True)

# First the loopback pings
lofails=""
@@ -67,6 +47,8 @@ try:

# Next comes eth0
eth0fails=""
+ netdev = domain.getDevice("eth0")
+ ip = netdev.getNetDevIP()
for size in pingsizes:
out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip)
if out["return"]:
@@ -76,6 +58,7 @@ except NetworkError, e:
except NetworkError, e:
FAIL(str(e))

+domain.stop()

# Tally up failures
failures=""
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/03_network_local_tcp_pos.py
--- a/tools/xm-test/tests/network/03_network_local_tcp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/03_network_local_tcp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,51 +17,28 @@ trysizes = [. 1, 48, 64, 512, 1440, 1448,
trysizes = [. 1, 48, 64, 512, 1440, 1448, 1500, 1505, 4096, 4192,
32767, 65495 ]

-
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a guest domain w/1 nic
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

try:
- # read an IP address from the config
- ip = Net.ip("dom1", "eth0")
- mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- brg = "xenbr0"
- config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
- brg = None
- config = {"vif" : ['ip=%s' % ip]}
-
-domain = XmTestDomain(extraConfig=config)
-try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("bhs")
-
- # Bring up the "lo" interface.
- console.runCmd("ifconfig lo 127.0.0.1")
-
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+ console.setHistorySaveCmds(value=True)

# First do loopback
lofails=""
@@ -73,6 +50,8 @@ try:

# Next comes eth0
eth0fails=""
+ netdev = domain.getDevice("eth0")
+ ip = netdev.getNetDevIP()
for size in trysizes:
out = console.runCmd("hping2 " + ip + " -E /dev/urandom -q -c 20 "
+ "--fast -d "+ str(size))
@@ -83,6 +62,7 @@ except NetworkError, e:
except NetworkError, e:
FAIL(str(e))

+domain.stop()

# Tally up failures
failures=""
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/04_network_local_udp_pos.py
--- a/tools/xm-test/tests/network/04_network_local_udp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/04_network_local_udp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -20,47 +20,24 @@ from XmTestLib import *
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

try:
- # read an IP address from the config
- ip = Net.ip("dom1", "eth0")
- mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- brg = "xenbr0"
- config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
- brg = None
- config = {"vif" : ['ip=%s' % ip]}
-
-domain = XmTestDomain(extraConfig=config)
-try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("bhs")
-
- # Bring up the "lo" interface.
- console.runCmd("ifconfig lo 127.0.0.1")
-
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+ console.setHistorySaveCmds(value=True)

# First do loopback
lofails=""
@@ -73,6 +50,8 @@ try:

# Next comes eth0
eth0fails=""
+ netdev = domain.getDevice("eth0")
+ ip = netdev.getNetDevIP()
for size in trysizes:
out = console.runCmd("hping2 " + ip + " -E /dev/urandom -2 -q -c 20 "
+ "--fast -d " + str(size))
@@ -84,6 +63,7 @@ except NetworkError, e:
except NetworkError, e:
FAIL(str(e))

+domain.stop()

# Tally up failures
failures=""
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/05_network_dom0_ping_pos.py
--- a/tools/xm-test/tests/network/05_network_dom0_ping_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py Mon May 08 14:46:11 2006 -0600
@@ -16,57 +16,31 @@ pingsizes = [. 1, 48, 64, 512, 1440, 1500
pingsizes = [. 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192,
32767, 65507 ]

-
-
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a guest domain w/1 nic
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

try:
- # read an IP address from the config
- ip = Net.ip("dom1", "eth0")
- mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- brg = "xenbr0"
- config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
- config = {"vif" : ['ip=%s' % ip ]}
- brg = None
-
-domain = XmTestDomain(extraConfig=config)
-try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Add a suitable dom0 IP address
- dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
# Ping dom0
fails=""
+ netdev = domain.getDevice("eth0")
+ dom0ip = netdev.getDom0AliasIP()
for size in pingsizes:
out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + dom0ip)
if out["return"]:
@@ -74,6 +48,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+domain.stop()
+
if len(fails):
FAIL("Ping to dom0 failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/06_network_dom0_tcp_pos.py
--- a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -16,57 +16,32 @@ trysizes = [. 1, 48, 64, 512, 1440, 1500,
trysizes = [. 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192,
32767, 65495 ]

-
-
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a guest domain w/1 nic
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

try:
- # read an IP address from the config
- ip = Net.ip("dom1", "eth0")
- mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- brg = "xenbr0"
- config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
- brg = None
- config = {"vif" : ["ip=%s" % ip]}
-
-domain = XmTestDomain(extraConfig=config)
-try:
- domain.start()
+ console = domain.start()
+ console.setHistorySaveCmds(value=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Add a suitable dom0 IP address
- dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
# Ping dom0
fails=""
+ netdev = domain.getDevice("eth0")
+ dom0ip = netdev.getDom0AliasIP()
for size in trysizes:
out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -q -c 20 "
+ "--fast -d " + str(size))
@@ -76,6 +51,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+domain.stop()
+
if len(fails):
FAIL("TCP hping2 to dom0 failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/07_network_dom0_udp_pos.py
--- a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -16,57 +16,31 @@ trysizes = [. 1, 48, 64, 512, 1440, 1500,
trysizes = [. 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192,
32767, 65495 ]

-
-
from XmTestLib import *
rc = 0

-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a guest domain w/1 nic
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")

try:
- # read an IP address from the config
- ip = Net.ip("dom1", "eth0")
- mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
- brg = "xenbr0"
- config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
- brg = None
- config = {"vif" : ["ip=%s" % ip]}
-
-domain = XmTestDomain(extraConfig=config)
-try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-
-# Attach a console
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Add a suitable dom0 IP address
- dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", bridge=brg)
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
# Ping dom0
fails=""
+ netdev = domain.getDevice("eth0")
+ dom0ip = netdev.getDom0AliasIP()
for size in trysizes:
out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -2 -q -c 20"
+ " --fast -d " + str(size))
@@ -76,6 +50,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+domain.stop()
+
if len(fails):
FAIL("UDP hping2 to dom0 failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/11_network_domU_ping_pos.py
--- a/tools/xm-test/tests/network/11_network_domU_ping_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,57 +17,37 @@ pingsizes = [. 1, 48, 64, 512, 1440, 1500

from XmTestLib import *

-def netDomain(ip):
- if ENABLE_HVM_SUPPORT:
- config = {"vif" : ['type=ioemu']}
- else:
- config = {"vif" : ['ip=%s' % ip ]}
+def netDomain():

- dom = XmTestDomain(extraConfig=config)
+ dom = XmTestDomain()
+ dom.newDevice(XenNetDevice, "eth0")
try:
- dom.start()
+ console = dom.start()
+ console.setHistorySaveCmds(value=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))
- try:
- # Attach a console
- console = XmConsole(dom.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
- except ConsoleError, e:
- FAIL(str(e))
- return console
+ return dom

rc = 0

-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+pinger = netDomain()
+pinger_console = pinger.getConsole()
+victim = netDomain()

try:
- # pick an IP address
- ip1 = Net.ip("dom1", "eth2")
- mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- # pick another IP address
- ip2 = Net.ip("dom2", "eth2")
- mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-pinger_console = netDomain(ip1)
-victim_console = netDomain(ip2)
-
-try:
- pinger_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
- victim_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
# Ping the victim over eth0
fails=""
+ v_netdev = victim.getDevice("eth0")
+ ip2 = v_netdev.getNetDevIP()
for size in pingsizes:
out = pinger_console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip2)
if out["return"]:
@@ -75,6 +55,8 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+pinger.stop()
+victim.stop()
+
if len(fails):
FAIL("Ping failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/12_network_domU_tcp_pos.py
--- a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,57 +17,37 @@ pingsizes = [. 1, 48, 64, 512, 1440, 1500

from XmTestLib import *

-def netDomain(ip):
- if ENABLE_HVM_SUPPORT:
- config = {"vif" : ['type=ioemu']}
- else:
- config = {"vif" : ["ip=%s" % ip]}
+def netDomain():

- dom = XmTestDomain(extraConfig=config)
+ dom = XmTestDomain()
+ dom.newDevice(XenNetDevice, "eth0")
try:
- dom.start()
+ console = dom.start()
+ console.setHistorySaveCmds(value=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))
- try:
- # Attach a console
- console = XmConsole(dom.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
- except ConsoleError, e:
- FAIL(str(e))
- return console
+ return dom

rc = 0

-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+src = netDomain()
+src_console = src.getConsole()
+dst = netDomain()

try:
- # pick an IP address
- ip1 = Net.ip("dom1", "eth2")
- mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- # pick another IP address
- ip2 = Net.ip("dom2", "eth2")
- mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-src_console = netDomain(ip1)
-dst_console = netDomain(ip2)
-
-try:
- src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
- dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
# Ping the victim over eth0
fails=""
+ dst_netdev = dst.getDevice("eth0")
+ ip2 = dst_netdev.getNetDevIP()
for size in pingsizes:
out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -q -c 20 "
+ "--fast -d " + str(size))
@@ -77,6 +57,8 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+src.stop()
+dst.stop()
+
if len(fails):
FAIL("TCP hping2 failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/network/13_network_domU_udp_pos.py
--- a/tools/xm-test/tests/network/13_network_domU_udp_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/network/13_network_domU_udp_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,57 +17,37 @@ pingsizes = [. 1, 48, 64, 512, 1440, 1500

from XmTestLib import *

-def netDomain(ip):
- if ENABLE_HVM_SUPPORT:
- config = {"vif" : ['type=ioemu']}
- else:
- config = {"vif" : ["ip=%s" % ip]}
+def netDomain():

- dom = XmTestDomain(extraConfig=config)
+ dom = XmTestDomain()
+ dom.newDevice(XenNetDevice, "eth0")
try:
- dom.start()
+ console = dom.start()
+ console.setHistorySaveCmds(value=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))
- try:
- # Attach a console
- console = XmConsole(dom.getName(), historySaveCmds=True)
- # Activate the console
- console.sendInput("bhs")
- except ConsoleError, e:
- FAIL(str(e))
- return console
+ return dom

rc = 0

-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+ SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+src = netDomain()
+src_console = src.getConsole()
+dst = netDomain()

try:
- # pick an IP address
- ip1 = Net.ip("dom1", "eth2")
- mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-try:
- # pick another IP address
- ip2 = Net.ip("dom2", "eth2")
- mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
- FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-src_console = netDomain(ip1)
-dst_console = netDomain(ip2)
-
-try:
- src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
- dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
# Ping the victim over eth0
fails=""
+ dst_netdev = dst.getDevice("eth0")
+ ip2 = dst_netdev.getNetDevIP()
for size in pingsizes:
out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -2 -q "
+ "-c 20 --fast -d " + str(size))
@@ -77,6 +57,8 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

+src.stop()
+dst.stop()
+
if len(fails):
FAIL("UDP hping2 failed for size" + fails + ".")
-
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/pause/01_pause_basic_pos.py
--- a/tools/xm-test/tests/pause/01_pause_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/pause/01_pause_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -20,29 +20,21 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("foo")
# Make sure a command succeeds
run = console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Pause the domain
status, output = traceCommand("xm pause %s" % domain.getName())
@@ -51,7 +43,8 @@ if status != 0:

# Try to attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
+ console = domain.getConsole()
+ console.setHistorySaveCmds(value=True)
run = console.runCmd("ls")
#If we get here, console attached to paused domain (unexpected)
FAIL("console attached to supposedly paused domain")
@@ -59,7 +52,7 @@ except ConsoleError, e:
pass

# Close the console
-console.closeConsole()
+domain.closeConsole()

status, output = traceCommand("xm unpause %s" % domain.getName())
if status != 0:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/pause/02_pause_badopt_neg.py
--- a/tools/xm-test/tests/pause/02_pause_badopt_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/pause/02_pause_badopt_neg.py Mon May 08 14:46:11 2006 -0600
@@ -11,7 +11,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/reboot/01_reboot_basic_pos.py
--- a/tools/xm-test/tests/reboot/01_reboot_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/reboot/01_reboot_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -11,19 +11,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-console.closeConsole()
+domain.closeConsole()

status, output = traceCommand("xm reboot %s" % domain.getName())

@@ -33,7 +28,7 @@ time.sleep(15)
time.sleep(15)

try:
- console = XmConsole(domain.getName())
+ console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))

@@ -43,7 +38,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()

domain.destroy()

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/reboot/02_reboot_badopt_neg.py
--- a/tools/xm-test/tests/reboot/02_reboot_badopt_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/reboot/02_reboot_badopt_neg.py Mon May 08 14:46:11 2006 -0600
@@ -11,7 +11,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/restore/01_restore_basic_pos.py
--- a/tools/xm-test/tests/restore/01_restore_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/restore/01_restore_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -18,7 +18,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
@@ -27,13 +27,11 @@ except DomainError, e:

# Make sure the domain isn't DOA
try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
console.runCmd("foo=bar")
except ConsoleError, e:
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()

# Save it out
try:
@@ -67,7 +65,7 @@ if not isDomainRunning(domain.getName())

# Make sure it's alive
try:
- newConsole = XmConsole(domain.getName())
+ newConsole = domain.getConsole()
# Enable debug dumping because this generates a Oops on x86_64
newConsole.debugMe = True
newConsole.sendInput("ls")
@@ -77,7 +75,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL("Restored domain is dead (%s)" % str(e))

-newConsole.closeConsole()
+domain.closeConsole()

# This only works because the domain
# still has the same name
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/restore/04_restore_withdevices_pos.py
--- a/tools/xm-test/tests/restore/04_restore_withdevices_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/restore/04_restore_withdevices_pos.py Mon May 08 14:46:11 2006 -0600
@@ -23,14 +23,11 @@ if s != 0:
FAIL("Unable to mke2fs /dev/ram1 in dom0")

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
FAIL(str(e))

try:
- console = XmConsole(domain.getName())
- console.sendInput("foo")
-
run = console.runCmd("mkdir /mnt/a /mnt/b")
if run["return"] != 0:
FAIL("Unable to mkdir /mnt/a /mnt/b")
@@ -67,7 +64,7 @@ except ConsoleError, e:
except ConsoleError, e:
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()

try:
s, o = traceCommand("xm save %s /tmp/test.state" % domain.getName(),
@@ -91,7 +88,7 @@ if s != 0:
FAIL("xm restore exited with %i != 0" % s)

try:
- console = XmConsole(domain.getName())
+ console = domain.getConsole()
# Enable debug dumping, as this causes an Oops on x86_64
console.debugMe = True

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/save/01_save_basic_pos.py
--- a/tools/xm-test/tests/save/01_save_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/save/01_save_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -13,20 +13,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Make sure the domain isn't DOA
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-console.closeConsole()
+domain.closeConsole()

# Save it out
try:
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/save/03_save_bogusfile_neg.py
--- a/tools/xm-test/tests/save/03_save_bogusfile_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/save/03_save_bogusfile_neg.py Mon May 08 14:46:11 2006 -0600
@@ -16,20 +16,14 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Make sure the domain isn't DOA
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- FAIL(str(e))
-
-console.closeConsole()
+domain.closeConsole()

# Save it out
status, output = traceCommand("xm save %s /NOWHERE/test.state" % domain.getName())
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/01_sedf_period_slice_pos.py
--- a/tools/xm-test/tests/sedf/01_sedf_period_slice_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/01_sedf_period_slice_pos.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/02_sedf_period_lower_neg.py
--- a/tools/xm-test/tests/sedf/02_sedf_period_lower_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/02_sedf_period_lower_neg.py Mon May 08 14:46:11 2006 -0600
@@ -16,7 +16,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/03_sedf_slice_lower_neg.py
--- a/tools/xm-test/tests/sedf/03_sedf_slice_lower_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/03_sedf_slice_lower_neg.py Mon May 08 14:46:11 2006 -0600
@@ -16,7 +16,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/04_sedf_slice_upper_neg.py
--- a/tools/xm-test/tests/sedf/04_sedf_slice_upper_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/04_sedf_slice_upper_neg.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/05_sedf_extratime_pos.py
--- a/tools/xm-test/tests/sedf/05_sedf_extratime_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/05_sedf_extratime_pos.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sedf/06_sedf_extratime_disable_neg.py
--- a/tools/xm-test/tests/sedf/06_sedf_extratime_disable_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sedf/06_sedf_extratime_disable_neg.py Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ domain = XmTestDomain(extraConfig = {"sc
domain = XmTestDomain(extraConfig = {"sched":"sedf"})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/shutdown/01_shutdown_basic_pos.py
--- a/tools/xm-test/tests/shutdown/01_shutdown_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/shutdown/01_shutdown_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -19,29 +19,21 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("foo")
# Make sure a command succeeds
run = console.runCmd("ls /bin")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
status, output = traceCommand("xm shutdown %s" % domain.getName())
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/shutdown/02_shutdown_badparm_neg.py
--- a/tools/xm-test/tests/shutdown/02_shutdown_badparm_neg.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/shutdown/02_shutdown_badparm_neg.py Mon May 08 14:46:11 2006 -0600
@@ -20,7 +20,7 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py
--- a/tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sysrq/02_sysrq_sync_pos.py Mon May 08 14:46:11 2006 -0600
@@ -17,19 +17,12 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))
-
-# Attach a console to it
-try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-

status, output = traceCommand("xm sysrq %s s" % domain.getName())

@@ -40,15 +33,13 @@ if status != 0:

# Run 'ls'
try:
- # Activate the console
- console.sendInput("foo")
# Check the dmesg output on the domU
run = console.runCmd("dmesg | grep Emerg\n")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

# Stop the domain (nice shutdown)
domain.stop()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py
--- a/tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/sysrq/03_sysrq_withreboot_pos.py Mon May 08 14:46:11 2006 -0600
@@ -13,7 +13,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create domain:"
@@ -27,12 +27,6 @@ if status != 0:
# Wait for the reboot to finish
time.sleep(20)

-try:
- console = XmConsole(domain.getName())
- console.sendInput("input")
-except ConsoleError, e:
- FAIL(str(e))
-
status, output = traceCommand("xm sysrq %s s" % domain.getName())
if status != 0:
FAIL("sysrq failed with %i != 0" % status)
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/unpause/01_unpause_basic_pos.py
--- a/tools/xm-test/tests/unpause/01_unpause_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/unpause/01_unpause_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -22,29 +22,21 @@ domain = XmTestDomain()

# Start it
try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
print e.extra
FAIL(str(e))

-# Attach a console to it
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
-except ConsoleError, e:
- FAIL(str(e))
-
-try:
- # Activate the console
- console.sendInput("foo")
# Make sure a command succeeds
run = console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

seed(time.time())

@@ -69,13 +61,13 @@ if status != 0:

# Are we still alive after all that?
try:
- console = XmConsole(domain.getName(), historySaveCmds=True)
+ console = domain.getConsole()
run = console.runCmd("ls")
except ConsoleError, e:
FAIL(str(e))

# Close the console
-console.closeConsole()
+domain.closeConsole()

if run["return"] != 0:
FAIL("console failed to attach to supposedly unpaused domain")
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py
--- a/tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -42,7 +42,7 @@ domain = XmTestDomain(extraConfig={"vcpu
domain = XmTestDomain(extraConfig={"vcpus":2})

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py
--- a/tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vcpu-pin/01_vcpu-pin_basic_pos.py Mon May 08 14:46:11 2006 -0600
@@ -20,7 +20,7 @@ domain = XmTestDomain()
domain = XmTestDomain()

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print "Failed to create test domain because:"
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vtpm/01_vtpm-list_pos.py
--- a/tools/xm-test/tests/vtpm/01_vtpm-list_pos.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vtpm/01_vtpm-list_pos.py Mon May 08 14:46:11 2006 -0600
@@ -16,7 +16,7 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ domain.start(noConsole=True)
except DomainError, e:
if verbose:
print e.extra
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py
--- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py Mon May 08 14:46:11 2006 -0600
@@ -16,7 +16,7 @@ domain = XmTestDomain(extraConfig=config
domain = XmTestDomain(extraConfig=config)

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
@@ -24,12 +24,6 @@ except DomainError, e:
FAIL("Unable to create domain")

domName = domain.getName()
-
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- vtpm_cleanup(domName)
- FAIL(str(e))

try:
console.sendInput("input")
@@ -49,7 +43,7 @@ if re.search("No such file",run[."output"
vtpm_cleanup(domName)
FAIL("TPM frontend support not compiled into (domU?) kernel")

-console.closeConsole()
+domain.closeConsole()

domain.stop()

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vtpm/03_vtpm-susp_res.py
--- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py Mon May 08 14:46:11 2006 -0600
@@ -15,9 +15,10 @@ import os.path

config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
+consoleHistory = ""

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
@@ -25,12 +26,6 @@ except DomainError, e:
FAIL("Unable to create domain")

domName = domain.getName()
-
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- vtpm_cleanup(domName)
- FAIL(str(e))

try:
console.sendInput("input")
@@ -50,19 +45,21 @@ if re.search("No such file",run[."output"
vtpm_cleanup(domName)
FAIL("TPM frontend support not compiled into (domU?) kernel")

-console.closeConsole()
+consoleHistory = console.getHistory()
+domain.closeConsole()

try:
status, ouptut = traceCommand("xm save %s %s.save" %
(domName, domName),
timeout=30)
+
except TimeoutError, e:
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL(str(e))

if status != 0:
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL("xm save did not succeed")

@@ -72,19 +69,19 @@ try:
timeout=30)
except TimeoutError, e:
os.remove("%s.save" % domName)
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL(str(e))

os.remove("%s.save" % domName)

if status != 0:
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL("xm restore did not succeed")

try:
- console = XmConsole(domain.getName())
+ console = domain.getConsole()
except ConsoleError, e:
vtpm_cleanup(domName)
FAIL(str(e))
@@ -96,7 +93,7 @@ except ConsoleError, e:
vtpm_cleanup(domName)
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()

domain.stop()

diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py Mon May 08 13:41:18 2006 -0600
+++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py Mon May 08 14:46:11 2006 -0600
@@ -15,9 +15,10 @@ import os.path

config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
+consoleHistory = ""

try:
- domain.start()
+ console = domain.start()
except DomainError, e:
if verbose:
print e.extra
@@ -25,12 +26,6 @@ except DomainError, e:
FAIL("Unable to create domain")

domName = domain.getName()
-
-try:
- console = XmConsole(domain.getName())
-except ConsoleError, e:
- vtpm_cleanup(domName)
- FAIL(str(e))

try:
console.sendInput("input")
@@ -50,7 +45,8 @@ if re.search("No such file",run[."output"
vtpm_cleanup(domName)
FAIL("TPM frontend support not compiled into (domU?) kernel")

-console.closeConsole()
+consoleHistory = console.getHistory()
+domain.closeConsole()

old_domid = domid(domName)

@@ -59,12 +55,12 @@ try:
domName,
timeout=90)
except TimeoutError, e:
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL(str(e))

if status != 0:
- saveLog(console.getHistory())
+ saveLog(consoleHistory)
vtpm_cleanup(domName)
FAIL("xm migrate did not succeed. External device migration activated?")

@@ -77,7 +73,7 @@ if (old_domid == new_domid):
FAIL("xm migrate failed, domain id is still %s" % old_domid)

try:
- console = XmConsole(domain.getName())
+ console = domain.getConsole()
except ConsoleError, e:
vtpm_cleanup(domName)
FAIL(str(e))
@@ -89,7 +85,7 @@ except ConsoleError, e:
vtpm_cleanup(domName)
FAIL(str(e))

-console.closeConsole()
+domain.closeConsole()

domain.stop()

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/Makefile
--- a/xen/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/xen/Makefile Mon May 08 14:46:11 2006 -0600
@@ -1,9 +1,10 @@
# This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated.
-export XEN_VERSION := 3
-export XEN_SUBVERSION := 0
-export XEN_EXTRAVERSION := -unstable
-export XEN_FULLVERSION := $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
+export XEN_VERSION = 3
+export XEN_SUBVERSION = 0
+export XEN_EXTRAVERSION ?= -unstable
+export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
+-include xen-version

export BASEDIR := $(CURDIR)

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Mon May 08 14:46:11 2006 -0600
@@ -106,12 +106,12 @@ void hyper_dom0_op(void)
vmx_vcpu_increment_iip(vcpu);
}

-void hyper_event_channel_op(void)
+void hyper_event_channel_op_compat(void)
{
VCPU *vcpu=current;
u64 r32,ret;
vcpu_get_gr_nat(vcpu,16,&r32);
- ret=do_event_channel_op(guest_handle_from_ptr(r32, evtchn_op_t));
+ ret=do_event_channel_op_compat(guest_handle_from_ptr(r32, evtchn_op_t));
vcpu_set_gr(vcpu, 8, ret, 0);
vmx_vcpu_increment_iip(vcpu);
}
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_ivt.S Mon May 08 14:46:11 2006 -0600
@@ -1156,7 +1156,7 @@ hyper_call_table:
data8 hyper_not_support //hyper_multicall
data8 hyper_not_support //hyper_update_va_mapping
data8 hyper_not_support //hyper_set_timer_op /* 15 */
- data8 hyper_event_channel_op
+ data8 hyper_event_channel_op_compat
data8 hyper_xen_version
data8 hyper_not_support //hyper_console_io
data8 hyper_not_support //hyper_physdev_op
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c Mon May 08 14:46:11 2006 -0600
@@ -20,7 +20,7 @@
#include <public/sched_ctl.h>
#include <asm/vmx.h>
extern unsigned long total_pages;
-long arch_do_dom0_op(dom0_op_t *op, GUEST_HANDLE(dom0_op_t) u_dom0_op)
+long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
{
long ret = 0;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c Mon May 08 14:46:11 2006 -0600
@@ -1237,7 +1237,7 @@ static void physdev_init_dom0(struct dom
{
if (iomem_permit_access(d, 0UL, ~0UL))
BUG();
- if (irqs_permit_access(d, 0, NR_PIRQS-1))
+ if (irqs_permit_access(d, 0, NR_IRQS-1))
BUG();
}

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/xen/hypercall.c Mon May 08 14:46:11 2006 -0600
@@ -27,7 +27,8 @@
#include <xen/domain.h>

extern unsigned long translate_domain_mpaddr(unsigned long);
-static long do_physdev_op(GUEST_HANDLE(physdev_op_t) uop);
+static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
+static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
/* FIXME: where these declarations should be there ? */
extern int dump_privop_counts_to_user(char *, int);
extern int zero_privop_counts_to_user(char *, int);
@@ -53,10 +54,10 @@ hypercall_t ia64_hypercall_table[] =
(hypercall_t)do_multicall,
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping */
(hypercall_t)do_ni_hypercall, /* do_set_timer_op */ /* 15 */
- (hypercall_t)do_event_channel_op,
+ (hypercall_t)do_event_channel_op_compat,
(hypercall_t)do_xen_version,
(hypercall_t)do_console_io,
- (hypercall_t)do_physdev_op,
+ (hypercall_t)do_physdev_op_compat,
(hypercall_t)do_grant_table_op, /* 20 */
(hypercall_t)do_ni_hypercall, /* do_vm_assist */
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping_otherdomain */
@@ -68,7 +69,9 @@ hypercall_t ia64_hypercall_table[] =
(hypercall_t)do_ni_hypercall, /* do_nmi_op */
(hypercall_t)do_sched_op,
(hypercall_t)do_ni_hypercall, /* */ /* 30 */
- (hypercall_t)do_ni_hypercall /* */
+ (hypercall_t)do_ni_hypercall, /* */
+ (hypercall_t)do_event_channel_op,
+ (hypercall_t)do_physdev_op
};

uint32_t nr_hypercalls =
@@ -330,71 +333,117 @@ iosapic_guest_write(
iosapic_guest_write(
unsigned long physbase, unsigned int reg, u32 pval);

-static long do_physdev_op(GUEST_HANDLE(physdev_op_t) uop)
+static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+ int irq;
+ long ret;
+
+ switch ( cmd )
+ {
+ case PHYSDEVOP_eoi: {
+ struct physdev_eoi eoi;
+ ret = -EFAULT;
+ if ( copy_from_guest(&eoi, arg, 1) != 0 )
+ break;
+ ret = pirq_guest_eoi(current->domain, eoi.irq);
+ break;
+ }
+
+ /* Legacy since 0x00030202. */
+ case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
+ ret = pirq_guest_unmask(current->domain);
+ break;
+ }
+
+ case PHYSDEVOP_irq_status_query: {
+ struct physdev_irq_status_query irq_status_query;
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+ break;
+ irq = irq_status_query.irq;
+ ret = -EINVAL;
+ if ( (irq < 0) || (irq >= NR_IRQS) )
+ break;
+ irq_status_query.flags = 0;
+ /* Edge-triggered interrupts don't need an explicit unmask downcall. */
+ if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") )
+ irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+ ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
+ break;
+ }
+
+ case PHYSDEVOP_apic_read: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
+ ret = -EPERM;
+ if ( !IS_PRIV(current->domain) )
+ break;
+ ret = iosapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+ if ( copy_to_guest(arg, &apic, 1) != 0 )
+ ret = -EFAULT;
+ break;
+ }
+
+ case PHYSDEVOP_apic_write: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
+ ret = -EPERM;
+ if ( !IS_PRIV(current->domain) )
+ break;
+ ret = iosapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
+ break;
+ }
+
+ case PHYSDEVOP_alloc_irq_vector: {
+ struct physdev_irq irq_op;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+ break;
+
+ ret = -EPERM;
+ if ( !IS_PRIV(current->domain) )
+ break;
+
+ ret = -EINVAL;
+ if ( (irq = irq_op.irq) >= NR_IRQS )
+ break;
+
+ irq_op.vector = assign_irq_vector(irq);
+ ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
+ break;
+ }
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
{
struct physdev_op op;
- long ret;
- int irq;

if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
return -EFAULT;

- switch ( op.cmd )
- {
- case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
- ret = pirq_guest_unmask(current->domain);
- break;
-
- case PHYSDEVOP_IRQ_STATUS_QUERY:
- irq = op.u.irq_status_query.irq;
- ret = -EINVAL;
- if ( (irq < 0) || (irq >= NR_IRQS) )
- break;
- op.u.irq_status_query.flags = 0;
- /* Edge-triggered interrupts don't need an explicit unmask downcall. */
- if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") )
- op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
- ret = 0;
- break;
-
- case PHYSDEVOP_APIC_READ:
- ret = -EPERM;
- if ( !IS_PRIV(current->domain) )
- break;
- ret = iosapic_guest_read(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- &op.u.apic_op.value);
- break;
-
- case PHYSDEVOP_APIC_WRITE:
- ret = -EPERM;
- if ( !IS_PRIV(current->domain) )
- break;
- ret = iosapic_guest_write(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- op.u.apic_op.value);
- break;
-
- case PHYSDEVOP_ASSIGN_VECTOR:
- if ( !IS_PRIV(current->domain) )
- return -EPERM;
-
- if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
- return -EINVAL;
-
- op.u.irq_op.vector = assign_irq_vector(irq);
- ret = 0;
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- if ( copy_to_guest(uop, &op, 1) )
- ret = -EFAULT;
-
- return ret;
-}
+ return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+ struct evtchn_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/ia64/xen/irq.c Mon May 08 14:46:11 2006 -0600
@@ -411,22 +411,40 @@ void __do_IRQ_guest(int irq)
}
}

+int pirq_guest_eoi(struct domain *d, int irq)
+{
+ irq_desc_t *desc;
+
+ if ( (irq < 0) || (irq >= NR_IRQS) )
+ return -EINVAL;
+
+ desc = &irq_desc[irq];
+ spin_lock_irq(&desc->lock);
+ if ( test_and_clear_bit(irq, &d->pirq_mask) &&
+ (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+ desc->handler->end(irq);
+ spin_unlock_irq(&desc->lock);
+
+ return 0;
+
+}
+
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
- int pirq;
+ int irq;
shared_info_t *s = d->shared_info;

- for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
- pirq < NR_PIRQS;
- pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
- {
- desc = &irq_desc[pirq];
+ for ( irq = find_first_bit(d->pirq_mask, NR_IRQS);
+ irq < NR_IRQS;
+ irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
+ {
+ desc = &irq_desc[irq];
spin_lock_irq(&desc->lock);
- if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
- test_and_clear_bit(pirq, &d->pirq_mask) &&
+ if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) &&
+ test_and_clear_bit(irq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
- desc->handler->end(pirq);
+ desc->handler->end(irq);
spin_unlock_irq(&desc->lock);
}

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/Makefile Mon May 08 14:46:11 2006 -0600
@@ -10,6 +10,7 @@ obj-y += apic.o
obj-y += apic.o
obj-y += audit.o
obj-y += bitops.o
+obj-y += compat.o
obj-y += delay.o
obj-y += dmi_scan.o
obj-y += dom0_ops.o
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/dom0_ops.c Mon May 08 14:46:11 2006 -0600
@@ -49,7 +49,7 @@ static void read_msr_for(void *unused)
(void)rdmsr_safe(msr_addr, msr_lo, msr_hi);
}

-long arch_do_dom0_op(struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op)
+long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
{
long ret = 0;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/domain.c Mon May 08 14:46:11 2006 -0600
@@ -364,7 +364,7 @@ int arch_set_info_guest(

long
arch_do_vcpu_op(
- int cmd, struct vcpu *v, GUEST_HANDLE(void) arg)
+ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg)
{
long rc = 0;

@@ -753,7 +753,10 @@ int __sync_lazy_execstate(void)
switch_required = (this_cpu(curr_vcpu) != current);

if ( switch_required )
+ {
+ ASSERT(current == idle_vcpu[smp_processor_id()]);
__context_switch();
+ }

local_irq_restore(flags);

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/domain_build.c Mon May 08 14:46:11 2006 -0600
@@ -809,7 +809,7 @@ int construct_dom0(struct domain *d,
/* DOM0 is permitted full I/O capabilities. */
rc |= ioports_permit_access(dom0, 0, 0xFFFF);
rc |= iomem_permit_access(dom0, 0UL, ~0UL);
- rc |= irqs_permit_access(dom0, 0, NR_PIRQS-1);
+ rc |= irqs_permit_access(dom0, 0, NR_IRQS-1);

/*
* Modify I/O port access permissions.
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Mon May 08 14:46:11 2006 -0600
@@ -61,6 +61,9 @@ static unsigned long trace_values[.NR_CPU
/* Useful define */
#define MAX_INST_SIZE 15

+#define set_segment_register(name, value) \
+ __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
+
/*
* External functions, etc. We should move these to some suitable header file(s) */

@@ -79,6 +82,8 @@ void svm_dump_regs(const char *from, str

static void svm_relinquish_guest_resources(struct domain *d);

+/* Host save area */
+struct host_save_area *host_save_area[ NR_CPUS ] = {0};
static struct asid_pool ASIDpool[NR_CPUS];

/*
@@ -185,11 +190,16 @@ void stop_svm(void)
void stop_svm(void)
{
u32 eax, edx;
+ int cpu = smp_processor_id();

/* We turn off the EFER_SVME bit. */
rdmsr(MSR_EFER, eax, edx);
eax &= ~EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
+
+ /* release the HSA */
+ free_host_save_area( host_save_area[ cpu ] );
+ host_save_area[ cpu ] = NULL;

printk("AMD SVM Extension is disabled.\n");
}
@@ -431,8 +441,11 @@ int start_svm(void)
int start_svm(void)
{
u32 eax, ecx, edx;
-
- /* Xen does not fill x86_capability words except 0. */
+ u32 phys_hsa_lo, phys_hsa_hi;
+ u64 phys_hsa;
+ int cpu = smp_processor_id();
+
+ /* Xen does not fill x86_capability words except 0. */
ecx = cpuid_ecx(0x80000001);
boot_cpu_data.x86_capability[5] = ecx;

@@ -443,7 +456,14 @@ int start_svm(void)
eax |= EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
asidpool_init(smp_processor_id());
- printk("AMD SVM Extension is enabled for cpu %d.\n", smp_processor_id());
+ printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );
+
+ /* Initialize the HSA for this core */
+ host_save_area[ cpu ] = alloc_host_save_area();
+ phys_hsa = (u64) virt_to_maddr( host_save_area[ cpu ] );
+ phys_hsa_lo = (u32) phys_hsa;
+ phys_hsa_hi = (u32) (phys_hsa >> 32);
+ wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);

/* Setup HVM interfaces */
hvm_funcs.disable = stop_svm;
@@ -546,20 +566,6 @@ void save_svm_cpu_user_regs(struct vcpu
ctxt->ds = vmcb->ds.sel;
}

-#if defined (__x86_64__)
-void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v )
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- regs->rip = vmcb->rip;
- regs->rsp = vmcb->rsp;
- regs->rflags = vmcb->rflags;
- regs->cs = vmcb->cs.sel;
- regs->ds = vmcb->ds.sel;
- regs->es = vmcb->es.sel;
- regs->ss = vmcb->ss.sel;
-}
-#elif defined (__i386__)
void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -571,11 +577,11 @@ void svm_store_cpu_user_regs(struct cpu_
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
-}
-#endif
+ regs->fs = vmcb->fs.sel;
+ regs->gs = vmcb->gs.sel;
+}

/* XXX Use svm_load_cpu_guest_regs instead */
-#if defined (__i386__)
void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -588,30 +594,17 @@ void svm_load_cpu_user_regs(struct vcpu
vmcb->rflags = regs->eflags;
vmcb->cs.sel = regs->cs;
vmcb->rip = regs->eip;
+
+ vmcb->ds.sel = regs->ds;
+ vmcb->es.sel = regs->es;
+ vmcb->fs.sel = regs->fs;
+ vmcb->gs.sel = regs->gs;
+
if (regs->eflags & EF_TF)
*intercepts |= EXCEPTION_BITMAP_DB;
else
*intercepts &= ~EXCEPTION_BITMAP_DB;
}
-#else /* (__i386__) */
-void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
-
- /* Write the guest register value into VMCB */
- vmcb->rax = regs->rax;
- vmcb->ss.sel = regs->ss;
- vmcb->rsp = regs->rsp;
- vmcb->rflags = regs->rflags;
- vmcb->cs.sel = regs->cs;
- vmcb->rip = regs->rip;
- if (regs->rflags & EF_TF)
- *intercepts |= EXCEPTION_BITMAP_DB;
- else
- *intercepts &= ~EXCEPTION_BITMAP_DB;
-}
-#endif /* !(__i386__) */

int svm_paging_enabled(struct vcpu *v)
{
@@ -691,6 +684,17 @@ static void svm_ctxt_switch_from(struct

static void svm_ctxt_switch_to(struct vcpu *v)
{
+#if __x86_64__
+ /*
+ * This is required, because VMRUN does consistency check
+ * and some of the DOM0 selectors are pointing to
+ * invalid GDT locations, and cause AMD processors
+ * to shutdown.
+ */
+ set_segment_register(ds, 0);
+ set_segment_register(es, 0);
+ set_segment_register(ss, 0);
+#endif
}

void svm_final_setup_guest(struct vcpu *v)
@@ -735,10 +739,6 @@ static void svm_relinquish_guest_resourc
{
if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
continue;
-#if 0
- /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
- free_host_save_area(v->arch.hvm_svm.host_save_area);
-#endif

destroy_vmcb(&v->arch.hvm_svm);
free_monitor_pagetable(v);
@@ -2821,11 +2821,7 @@ asmlinkage void svm_load_cr2(void)
struct vcpu *v = current;

local_irq_disable();
-#ifdef __i386__
- asm volatile("movl %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
-#else
- asm volatile("movq %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
-#endif
+ asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
}

asmlinkage void svm_asid(void)
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/hvm/svm/vmcb.c Mon May 08 14:46:11 2006 -0600
@@ -36,9 +36,11 @@
#include <xen/kernel.h>
#include <xen/domain_page.h>

+extern struct host_save_area *host_save_area[];
extern int svm_dbg_on;
extern int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current,
int oldcore, int newcore);
+extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm );

#define round_pgdown(_p) ((_p)&PAGE_MASK) /* coped from domain.c */

@@ -309,8 +311,6 @@ int construct_vmcb(struct arch_svm_struc
{
int error;
long rc=0;
- struct host_save_area *hsa = NULL;
- u64 phys_hsa;

memset(arch_svm, 0, sizeof(struct arch_svm_struct));

@@ -320,36 +320,9 @@ int construct_vmcb(struct arch_svm_struc
goto err_out;
}

- /*
- * The following code is for allocating host_save_area.
- * Note: We either allocate a Host Save Area per core or per VCPU.
- * However, we do not want a global data structure
- * for HSA per core, we decided to implement a HSA for each VCPU.
- * It will waste space since VCPU number is larger than core number.
- * But before we find a better place for HSA for each core, we will
- * stay will this solution.
- */
-
- if (!(hsa = alloc_host_save_area()))
- {
- printk("Failed to allocate Host Save Area\n");
- rc = -ENOMEM;
- goto err_out;
- }
-
- phys_hsa = (u64) virt_to_maddr(hsa);
- arch_svm->host_save_area = hsa;
- arch_svm->host_save_pa = phys_hsa;
-
+ /* update the HSA for the current Core */
+ set_hsa_to_guest( arch_svm );
arch_svm->vmcb_pa = (u64) virt_to_maddr(arch_svm->vmcb);
-
- if ((error = load_vmcb(arch_svm, arch_svm->host_save_pa)))
- {
- printk("construct_vmcb: load_vmcb failed: VMCB = %lx\n",
- (unsigned long) arch_svm->host_save_pa);
- rc = -EINVAL;
- goto err_out;
- }

if ((error = construct_vmcb_controls(arch_svm)))
{
@@ -455,21 +428,16 @@ void svm_do_launch(struct vcpu *v)

if (svm_dbg_on)
svm_dump_vmcb(__func__, vmcb);
-}
-
-
-int load_vmcb(struct arch_svm_struct *arch_svm, u64 phys_hsa)
-{
- u32 phys_hsa_lo, phys_hsa_hi;
-
- phys_hsa_lo = (u32) phys_hsa;
- phys_hsa_hi = (u32) (phys_hsa >> 32);
-
- wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
- set_bit(ARCH_SVM_VMCB_LOADED, &arch_svm->flags);
- return 0;
-}
-
+
+ vmcb->tlb_control = 1;
+}
+
+
+void set_hsa_to_guest( struct arch_svm_struct *arch_svm )
+{
+ arch_svm->host_save_area = host_save_area[ smp_processor_id() ];
+ arch_svm->host_save_pa = (u64)virt_to_maddr( arch_svm->host_save_area );
+}

/*
* Resume the guest.
@@ -481,6 +449,9 @@ void svm_do_resume(struct vcpu *v)
struct hvm_time_info *time_info = &vpit->time_info;

svm_stts(v);
+
+ /* make sure the HSA is set for the current core */
+ set_hsa_to_guest( &v->arch.hvm_svm );

/* pick up the elapsed PIT ticks and re-enable pit_timer */
if ( time_info->first_injected ) {
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/io.c Mon May 08 14:46:11 2006 -0600
@@ -166,20 +166,26 @@ asmlinkage void vmx_intr_assist(void)
}

has_ext_irq = cpu_has_pending_irq(v);
+
+ if (unlikely(v->arch.hvm_vmx.vector_injected)) {
+ v->arch.hvm_vmx.vector_injected=0;
+ if (unlikely(has_ext_irq)) enable_irq_window(v);
+ return;
+ }
+
__vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
- if (idtv_info_field & INTR_INFO_VALID_MASK) {
+ if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
__vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);

__vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
- if (inst_len >= 1 && inst_len <= 15)
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
-
- if (idtv_info_field & 0x800) { /* valid error code */
+ __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
+
+ if (unlikely(idtv_info_field & 0x800)) { /* valid error code */
unsigned long error_code;
__vmread(IDT_VECTORING_ERROR_CODE, &error_code);
__vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
}
- if ( has_ext_irq )
+ if (unlikely(has_ext_irq))
enable_irq_window(v);

HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
@@ -187,8 +193,9 @@ asmlinkage void vmx_intr_assist(void)
return;
}

- if ( !has_ext_irq ) return;
- if ( is_interruptibility_state() ) { /* pre-cleared for emulated instruction */
+ if (likely(!has_ext_irq)) return;
+
+ if (unlikely(is_interruptibility_state())) { /* pre-cleared for emulated instruction */
enable_irq_window(v);
HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
return;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon May 08 14:46:11 2006 -0600
@@ -452,17 +452,6 @@ static void vmx_store_cpu_guest_regs(

if ( regs != NULL )
{
-#if defined (__x86_64__)
- __vmread(GUEST_RFLAGS, &regs->rflags);
- __vmread(GUEST_SS_SELECTOR, &regs->ss);
- __vmread(GUEST_CS_SELECTOR, &regs->cs);
- __vmread(GUEST_DS_SELECTOR, &regs->ds);
- __vmread(GUEST_ES_SELECTOR, &regs->es);
- __vmread(GUEST_GS_SELECTOR, &regs->gs);
- __vmread(GUEST_FS_SELECTOR, &regs->fs);
- __vmread(GUEST_RIP, &regs->rip);
- __vmread(GUEST_RSP, &regs->rsp);
-#elif defined (__i386__)
__vmread(GUEST_RFLAGS, &regs->eflags);
__vmread(GUEST_SS_SELECTOR, &regs->ss);
__vmread(GUEST_CS_SELECTOR, &regs->cs);
@@ -472,7 +461,6 @@ static void vmx_store_cpu_guest_regs(
__vmread(GUEST_FS_SELECTOR, &regs->fs);
__vmread(GUEST_RIP, &regs->eip);
__vmread(GUEST_RSP, &regs->esp);
-#endif
}

if ( crs != NULL )
@@ -485,6 +473,45 @@ static void vmx_store_cpu_guest_regs(
/* Reload current VCPU's VMCS if it was temporarily unloaded. */
if ( (v != current) && hvm_guest(current) )
__vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
+}
+
+/*
+ * The VMX spec (section 4.3.1.2, Checks on Guest Segment
+ * Registers) says that virtual-8086 mode guests' segment
+ * base-address fields in the VMCS must be equal to their
+ * corresponding segment selector field shifted right by
+ * four bits upon vmentry.
+ *
+ * This function (called only for VM86-mode guests) fixes
+ * the bases to be consistent with the selectors in regs
+ * if they're not already. Without this, we can fail the
+ * vmentry check mentioned above.
+ */
+static void fixup_vm86_seg_bases(struct cpu_user_regs *regs)
+{
+ int err = 0;
+ unsigned long base;
+
+ err |= __vmread(GUEST_ES_BASE, &base);
+ if (regs->es << 4 != base)
+ err |= __vmwrite(GUEST_ES_BASE, regs->es << 4);
+ err |= __vmread(GUEST_CS_BASE, &base);
+ if (regs->cs << 4 != base)
+ err |= __vmwrite(GUEST_CS_BASE, regs->cs << 4);
+ err |= __vmread(GUEST_SS_BASE, &base);
+ if (regs->ss << 4 != base)
+ err |= __vmwrite(GUEST_SS_BASE, regs->ss << 4);
+ err |= __vmread(GUEST_DS_BASE, &base);
+ if (regs->ds << 4 != base)
+ err |= __vmwrite(GUEST_DS_BASE, regs->ds << 4);
+ err |= __vmread(GUEST_FS_BASE, &base);
+ if (regs->fs << 4 != base)
+ err |= __vmwrite(GUEST_FS_BASE, regs->fs << 4);
+ err |= __vmread(GUEST_GS_BASE, &base);
+ if (regs->gs << 4 != base)
+ err |= __vmwrite(GUEST_GS_BASE, regs->gs << 4);
+
+ BUG_ON(err);
}

void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -510,28 +537,11 @@ void vmx_load_cpu_guest_regs(struct vcpu

ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());

-#if defined (__x86_64__)
__vmwrite(GUEST_SS_SELECTOR, regs->ss);
__vmwrite(GUEST_DS_SELECTOR, regs->ds);
__vmwrite(GUEST_ES_SELECTOR, regs->es);
__vmwrite(GUEST_GS_SELECTOR, regs->gs);
__vmwrite(GUEST_FS_SELECTOR, regs->fs);
- __vmwrite(GUEST_RSP, regs->rsp);
-
- __vmwrite(GUEST_RFLAGS, regs->rflags);
- if (regs->rflags & EF_TF)
- __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
- else
- __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
-
- __vmwrite(GUEST_CS_SELECTOR, regs->cs);
- __vmwrite(GUEST_RIP, regs->rip);
-#elif defined (__i386__)
- __vmwrite(GUEST_SS_SELECTOR, regs->ss);
- __vmwrite(GUEST_DS_SELECTOR, regs->ds);
- __vmwrite(GUEST_ES_SELECTOR, regs->es);
- __vmwrite(GUEST_GS_SELECTOR, regs->gs);
- __vmwrite(GUEST_FS_SELECTOR, regs->fs);

__vmwrite(GUEST_RSP, regs->esp);

@@ -540,10 +550,11 @@ void vmx_load_cpu_guest_regs(struct vcpu
__vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
else
__vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+ if (regs->eflags & EF_VM)
+ fixup_vm86_seg_bases(regs);

__vmwrite(GUEST_CS_SELECTOR, regs->cs);
__vmwrite(GUEST_RIP, regs->eip);
-#endif

/* Reload current VCPU's VMCS if it was temporarily unloaded. */
if ( (v != current) && hvm_guest(current) )
@@ -882,6 +893,20 @@ static void vmx_vmexit_do_cpuid(struct c
#define CASE_GET_REG_P(REG, reg) \
case REG_ ## REG: reg_p = (unsigned long *)&(regs->reg); break

+#ifdef __i386__
+#define CASE_EXTEND_GET_REG_P
+#else
+#define CASE_EXTEND_GET_REG_P \
+ CASE_GET_REG_P(R8, r8); \
+ CASE_GET_REG_P(R9, r9); \
+ CASE_GET_REG_P(R10, r10); \
+ CASE_GET_REG_P(R11, r11); \
+ CASE_GET_REG_P(R12, r12); \
+ CASE_GET_REG_P(R13, r13); \
+ CASE_GET_REG_P(R14, r14); \
+ CASE_GET_REG_P(R15, r15)
+#endif
+
static void vmx_dr_access (unsigned long exit_qualification, struct cpu_user_regs *regs)
{
unsigned int reg;
@@ -897,14 +922,15 @@ static void vmx_dr_access (unsigned long
"vmx_dr_access : eip=%lx, reg=%d, exit_qualification = %lx",
eip, reg, exit_qualification);

- switch(exit_qualification & DEBUG_REG_ACCESS_REG) {
- CASE_GET_REG_P(EAX, eax);
- CASE_GET_REG_P(ECX, ecx);
- CASE_GET_REG_P(EDX, edx);
- CASE_GET_REG_P(EBX, ebx);
- CASE_GET_REG_P(EBP, ebp);
- CASE_GET_REG_P(ESI, esi);
- CASE_GET_REG_P(EDI, edi);
+ switch ( exit_qualification & DEBUG_REG_ACCESS_REG ) {
+ CASE_GET_REG_P(EAX, eax);
+ CASE_GET_REG_P(ECX, ecx);
+ CASE_GET_REG_P(EDX, edx);
+ CASE_GET_REG_P(EBX, ebx);
+ CASE_GET_REG_P(EBP, ebp);
+ CASE_GET_REG_P(ESI, esi);
+ CASE_GET_REG_P(EDI, edi);
+ CASE_EXTEND_GET_REG_P;
case REG_ESP:
break;
default:
@@ -1514,28 +1540,29 @@ static int vmx_set_cr0(unsigned long val
return 1;
}

-#define CASE_GET_REG(REG, reg) \
+#define CASE_SET_REG(REG, reg) \
+ case REG_ ## REG: regs->reg = value; break
+#define CASE_GET_REG(REG, reg) \
case REG_ ## REG: value = regs->reg; break

-#define CASE_EXTEND_SET_REG \
- CASE_EXTEND_REG(S)
-#define CASE_EXTEND_GET_REG \
- CASE_EXTEND_REG(G)
+#define CASE_EXTEND_SET_REG \
+ CASE_EXTEND_REG(S)
+#define CASE_EXTEND_GET_REG \
+ CASE_EXTEND_REG(G)

#ifdef __i386__
#define CASE_EXTEND_REG(T)
#else
-#define CASE_EXTEND_REG(T) \
- CASE_ ## T ## ET_REG(R8, r8); \
- CASE_ ## T ## ET_REG(R9, r9); \
+#define CASE_EXTEND_REG(T) \
+ CASE_ ## T ## ET_REG(R8, r8); \
+ CASE_ ## T ## ET_REG(R9, r9); \
CASE_ ## T ## ET_REG(R10, r10); \
CASE_ ## T ## ET_REG(R11, r11); \
CASE_ ## T ## ET_REG(R12, r12); \
CASE_ ## T ## ET_REG(R13, r13); \
CASE_ ## T ## ET_REG(R14, r14); \
- CASE_ ## T ## ET_REG(R15, r15);
+ CASE_ ## T ## ET_REG(R15, r15)
#endif
-

/*
* Write to control registers
@@ -1546,31 +1573,28 @@ static int mov_to_cr(int gp, int cr, str
unsigned long old_cr;
struct vcpu *v = current;

- switch (gp) {
- CASE_GET_REG(EAX, eax);
- CASE_GET_REG(ECX, ecx);
- CASE_GET_REG(EDX, edx);
- CASE_GET_REG(EBX, ebx);
- CASE_GET_REG(EBP, ebp);
- CASE_GET_REG(ESI, esi);
- CASE_GET_REG(EDI, edi);
- CASE_EXTEND_GET_REG
- case REG_ESP:
- __vmread(GUEST_RSP, &value);
+ switch ( gp ) {
+ CASE_GET_REG(EAX, eax);
+ CASE_GET_REG(ECX, ecx);
+ CASE_GET_REG(EDX, edx);
+ CASE_GET_REG(EBX, ebx);
+ CASE_GET_REG(EBP, ebp);
+ CASE_GET_REG(ESI, esi);
+ CASE_GET_REG(EDI, edi);
+ CASE_EXTEND_GET_REG;
+ case REG_ESP:
+ __vmread(GUEST_RSP, &value);
break;
default:
printk("invalid gp: %d\n", gp);
__hvm_bug(regs);
}

- HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
- HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
-
- switch(cr) {
+ HVM_DBG_LOG(DBG_LEVEL_1, "CR%d, value = %lx", cr, value);
+
+ switch ( cr ) {
case 0:
- {
return vmx_set_cr0(value);
- }
case 3:
{
unsigned long old_base_mfn, mfn;
@@ -1742,11 +1766,6 @@ static int mov_to_cr(int gp, int cr, str
return 1;
}

-#define CASE_SET_REG(REG, reg) \
- case REG_ ## REG: \
- regs->reg = value; \
- break
-
/*
* Read from control registers. CR0 and CR4 are read from the shadow.
*/
@@ -1755,22 +1774,22 @@ static void mov_from_cr(int cr, int gp,
unsigned long value;
struct vcpu *v = current;

- if (cr != 3)
+ if ( cr != 3 )
__hvm_bug(regs);

value = (unsigned long) v->arch.hvm_vmx.cpu_cr3;

- switch (gp) {
- CASE_SET_REG(EAX, eax);
- CASE_SET_REG(ECX, ecx);
- CASE_SET_REG(EDX, edx);
- CASE_SET_REG(EBX, ebx);
- CASE_SET_REG(EBP, ebp);
- CASE_SET_REG(ESI, esi);
- CASE_SET_REG(EDI, edi);
- CASE_EXTEND_SET_REG
- case REG_ESP:
- __vmwrite(GUEST_RSP, value);
+ switch ( gp ) {
+ CASE_SET_REG(EAX, eax);
+ CASE_SET_REG(ECX, ecx);
+ CASE_SET_REG(EDX, edx);
+ CASE_SET_REG(EBX, ebx);
+ CASE_SET_REG(EBP, ebp);
+ CASE_SET_REG(ESI, esi);
+ CASE_SET_REG(EDI, edi);
+ CASE_EXTEND_SET_REG;
+ case REG_ESP:
+ __vmwrite(GUEST_RSP, value);
regs->esp = value;
break;
default:
@@ -1778,7 +1797,7 @@ static void mov_from_cr(int cr, int gp,
__hvm_bug(regs);
}

- HVM_DBG_LOG(DBG_LEVEL_VMMU, "mov_from_cr: CR%d, value = %lx,", cr, value);
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR%d, value = %lx", cr, value);
}

static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs *regs)
@@ -2273,11 +2292,7 @@ asmlinkage void vmx_load_cr2(void)
struct vcpu *v = current;

local_irq_disable();
-#ifdef __i386__
- asm volatile("movl %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2));
-#else
- asm volatile("movq %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2));
-#endif
+ asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2));
}

asmlinkage void vmx_trace_vmentry (void)
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/i387.c
--- a/xen/arch/x86/i387.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/i387.c Mon May 08 14:46:11 2006 -0600
@@ -26,19 +26,54 @@ void save_init_fpu(struct vcpu *v)
void save_init_fpu(struct vcpu *v)
{
unsigned long cr0 = read_cr0();
+ char *fpu_ctxt = v->arch.guest_context.fpu_ctxt.x;

/* This can happen, if a paravirtualised guest OS has set its CR0.TS. */
if ( cr0 & X86_CR0_TS )
clts();

if ( cpu_has_fxsr )
+ {
+#ifdef __i386__
__asm__ __volatile__ (
- "fxsave %0 ; fnclex"
- : "=m" (v->arch.guest_context.fpu_ctxt) );
+ "fxsave %0"
+ : "=m" (*fpu_ctxt) );
+#else /* __x86_64__ */
+ /*
+ * The only way to force fxsaveq on a wide range of gas versions. On
+ * older versions the rex64 prefix works only if we force an addressing
+ * mode that doesn't require extended registers.
+ */
+ __asm__ __volatile__ (
+ "rex64/fxsave (%1)"
+ : "=m" (*fpu_ctxt) : "cdaSDb" (fpu_ctxt) );
+#endif
+
+ /* Clear exception flags if FSW.ES is set. */
+ if ( unlikely(fpu_ctxt[2] & 0x80) )
+ __asm__ __volatile__ ("fnclex");
+
+ /*
+ * AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
+ * is pending. Clear the x87 state here by setting it to fixed
+ * values. The hypervisor data segment can be sometimes 0 and
+ * sometimes new user value. Both should be ok. Use the FPU saved
+ * data block as a safe address because it should be in L1.
+ */
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ {
+ __asm__ __volatile__ (
+ "emms\n\t" /* clear stack tags */
+ "fildl %0" /* load to clear state */
+ : : "m" (*fpu_ctxt) );
+ }
+ }
else
+ {
__asm__ __volatile__ (
"fnsave %0 ; fwait"
- : "=m" (v->arch.guest_context.fpu_ctxt) );
+ : "=m" (*fpu_ctxt) );
+ }

clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
write_cr0(cr0|X86_CR0_TS);
@@ -46,14 +81,22 @@ void save_init_fpu(struct vcpu *v)

void restore_fpu(struct vcpu *v)
{
+ char *fpu_ctxt = v->arch.guest_context.fpu_ctxt.x;
+
/*
* FXRSTOR can fault if passed a corrupted data block. We handle this
* possibility, which may occur if the block was passed to us by control
* tools, by silently clearing the block.
*/
if ( cpu_has_fxsr )
+ {
__asm__ __volatile__ (
+#ifdef __i386__
"1: fxrstor %0 \n"
+#else /* __x86_64__ */
+ /* See above for why the operands/constraints are this way. */
+ "1: rex64/fxrstor (%2) \n"
+#endif
".section .fixup,\"ax\" \n"
"2: push %%"__OP"ax \n"
" push %%"__OP"cx \n"
@@ -72,12 +115,19 @@ void restore_fpu(struct vcpu *v)
" "__FIXUP_WORD" 1b,2b \n"
".previous \n"
:
- : "m" (v->arch.guest_context.fpu_ctxt),
- "i" (sizeof(v->arch.guest_context.fpu_ctxt)/4) );
+ : "m" (*fpu_ctxt),
+ "i" (sizeof(v->arch.guest_context.fpu_ctxt)/4)
+#ifdef __x86_64__
+ ,"cdaSDb" (fpu_ctxt)
+#endif
+ );
+ }
else
+ {
__asm__ __volatile__ (
"frstor %0"
: : "m" (v->arch.guest_context.fpu_ctxt) );
+ }
}

/*
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/i8259.c Mon May 08 14:46:11 2006 -0600
@@ -19,6 +19,7 @@
#include <asm/bitops.h>
#include <xen/delay.h>
#include <asm/apic.h>
+#include <asm/asm_defns.h>
#include <io_ports.h>

/*
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/irq.c Mon May 08 14:46:11 2006 -0600
@@ -293,52 +293,76 @@ static void flush_all_pending_eoi(void *
flush_ready_eoi(NULL);
}

-int pirq_guest_unmask(struct domain *d)
+static void __pirq_guest_eoi(struct domain *d, int irq)
{
irq_desc_t *desc;
irq_guest_action_t *action;
- cpumask_t cpu_eoi_map = CPU_MASK_NONE;
- unsigned int pirq, cpu = smp_processor_id();
- shared_info_t *s = d->shared_info;
-
- for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
- pirq < NR_PIRQS;
- pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
- {
- desc = &irq_desc[irq_to_vector(pirq)];
- action = (irq_guest_action_t *)desc->action;
-
- spin_lock_irq(&desc->lock);
-
- if ( !test_bit(d->pirq_to_evtchn[pirq], s->evtchn_mask) &&
- test_and_clear_bit(pirq, d->pirq_mask) )
- {
- ASSERT(action->ack_type != ACKTYPE_NONE);
- if ( --action->in_flight == 0 )
- {
- if ( action->ack_type == ACKTYPE_UNMASK )
- desc->handler->end(irq_to_vector(pirq));
- cpu_eoi_map = action->cpu_eoi_map;
- }
- }
-
- if ( cpu_test_and_clear(cpu, cpu_eoi_map) )
- {
- __set_eoi_ready(desc);
- spin_unlock(&desc->lock);
- flush_ready_eoi(NULL);
- local_irq_enable();
- }
- else
- {
- spin_unlock_irq(&desc->lock);
- }
-
- if ( !cpus_empty(cpu_eoi_map) )
- {
- on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
- cpu_eoi_map = CPU_MASK_NONE;
- }
+ cpumask_t cpu_eoi_map;
+
+ desc = &irq_desc[irq_to_vector(irq)];
+ action = (irq_guest_action_t *)desc->action;
+
+ spin_lock_irq(&desc->lock);
+
+ ASSERT(!test_bit(irq, d->pirq_mask) ||
+ (action->ack_type != ACKTYPE_NONE));
+
+ if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) ||
+ unlikely(--action->in_flight != 0) )
+ {
+ spin_unlock_irq(&desc->lock);
+ return;
+ }
+
+ if ( action->ack_type == ACKTYPE_UNMASK )
+ {
+ ASSERT(cpus_empty(action->cpu_eoi_map));
+ desc->handler->end(irq_to_vector(irq));
+ spin_unlock_irq(&desc->lock);
+ return;
+ }
+
+ ASSERT(action->ack_type == ACKTYPE_EOI);
+
+ cpu_eoi_map = action->cpu_eoi_map;
+
+ if ( cpu_test_and_clear(smp_processor_id(), cpu_eoi_map) )
+ {
+ __set_eoi_ready(desc);
+ spin_unlock(&desc->lock);
+ flush_ready_eoi(NULL);
+ local_irq_enable();
+ }
+ else
+ {
+ spin_unlock_irq(&desc->lock);
+ }
+
+ if ( !cpus_empty(cpu_eoi_map) )
+ on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
+}
+
+int pirq_guest_eoi(struct domain *d, int irq)
+{
+ if ( (irq < 0) || (irq >= NR_IRQS) )
+ return -EINVAL;
+
+ __pirq_guest_eoi(d, irq);
+
+ return 0;
+}
+
+int pirq_guest_unmask(struct domain *d)
+{
+ unsigned int irq;
+ shared_info_t *s = d->shared_info;
+
+ for ( irq = find_first_bit(d->pirq_mask, NR_IRQS);
+ irq < NR_IRQS;
+ irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
+ {
+ if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) )
+ __pirq_guest_eoi(d, irq);
}

return 0;
@@ -386,9 +410,6 @@ int pirq_guest_bind(struct vcpu *v, int
unsigned long flags;
int rc = 0;
cpumask_t cpumask = CPU_MASK_NONE;
-
- if ( (irq < 0) || (irq >= NR_IRQS) )
- return -EINVAL;

retry:
vector = irq_to_vector(irq);
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/mm.c Mon May 08 14:46:11 2006 -0600
@@ -1757,9 +1757,9 @@ static inline cpumask_t vcpumask_to_pcpu
}

int do_mmuext_op(
- GUEST_HANDLE(mmuext_op_t) uops,
+ XEN_GUEST_HANDLE(mmuext_op_t) uops,
unsigned int count,
- GUEST_HANDLE(uint) pdone,
+ XEN_GUEST_HANDLE(uint) pdone,
unsigned int foreigndom)
{
struct mmuext_op op;
@@ -2007,9 +2007,9 @@ int do_mmuext_op(
}

int do_mmu_update(
- GUEST_HANDLE(mmu_update_t) ureqs,
+ XEN_GUEST_HANDLE(mmu_update_t) ureqs,
unsigned int count,
- GUEST_HANDLE(uint) pdone,
+ XEN_GUEST_HANDLE(uint) pdone,
unsigned int foreigndom)
{
struct mmu_update req;
@@ -2708,7 +2708,7 @@ long set_gdt(struct vcpu *v,
}


-long do_set_gdt(GUEST_HANDLE(ulong) frame_list, unsigned int entries)
+long do_set_gdt(XEN_GUEST_HANDLE(ulong) frame_list, unsigned int entries)
{
int nr_pages = (entries + 511) / 512;
unsigned long frames[16];
@@ -2812,7 +2812,7 @@ long do_update_descriptor(u64 pa, u64 de
}


-long arch_memory_op(int op, GUEST_HANDLE(void) arg)
+long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
{
switch ( op )
{
@@ -2917,7 +2917,7 @@ static inline unsigned int ptwr_eip_stat

static void ptwr_eip_stat_inc(u32 *n)
{
- int i, j;
+ unsigned int i, j;

if ( ++(*n) != 0 )
return;
@@ -2925,14 +2925,14 @@ static void ptwr_eip_stat_inc(u32 *n)
*n = ~0;

/* Re-scale all buckets. */
- for ( i = 0; i <ptwr_eip_buckets; i++ )
+ for ( i = 0; i < ptwr_eip_buckets; i++ )
for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
ptwr_eip_stats[i].val[j] >>= 1;
}

static void ptwr_eip_stat_update(unsigned long eip, domid_t id, int modified)
{
- int i, j, b;
+ unsigned int i, j, b;

i = b = ptwr_eip_stat_hash(eip, id);

@@ -2946,7 +2946,7 @@ static void ptwr_eip_stat_update(unsigne
memset(ptwr_eip_stats[i].val,0, sizeof(ptwr_eip_stats[i].val));
}

- if ( ptwr_eip_stats[i].eip == eip )
+ if ( ptwr_eip_stats[i].eip == eip && ptwr_eip_stats[i].id == id)
{
for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
if ( modified <= ptwr_eip_stat_threshold[j] )
@@ -2975,7 +2975,7 @@ void ptwr_eip_stat_print(void)
{
struct domain *e;
domid_t d;
- int i, j;
+ unsigned int i, j;

for_each_domain( e )
{
@@ -2983,11 +2983,11 @@ void ptwr_eip_stat_print(void)

for ( i = 0; i < ptwr_eip_buckets; i++ )
{
- if ( ptwr_eip_stats[i].eip && ptwr_eip_stats[i].id != d )
+ if ( !ptwr_eip_stats[i].eip || ptwr_eip_stats[i].id != d )
continue;

- printk("D %d eip %08lx ",
- ptwr_eip_stats[i].id, ptwr_eip_stats[i].eip);
+ printk("D %5d eip %p ",
+ ptwr_eip_stats[i].id, (void *)ptwr_eip_stats[i].eip);

for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
printk("<=%u %4u \t",
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/oprofile/xenoprof.c Mon May 08 14:46:11 2006 -0600
@@ -349,7 +349,7 @@ void free_xenoprof_pages(struct domain *
d->xenoprof = NULL;
}

-int xenoprof_op_init(GUEST_HANDLE(void) arg)
+int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_init xenoprof_init;
int is_primary, num_events;
@@ -410,7 +410,7 @@ int xenoprof_op_init(GUEST_HANDLE(void)
|| (op == XENOPROF_release_counters) \
|| (op == XENOPROF_shutdown))

-int do_xenoprof_op(int op, GUEST_HANDLE(void) arg)
+int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg)
{
int ret = 0;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/physdev.c Mon May 08 14:46:11 2006 -0600
@@ -22,90 +22,122 @@ pirq_acktype(
pirq_acktype(
int irq);

-/*
- * Demuxing hypercall.
- */
-long do_physdev_op(GUEST_HANDLE(physdev_op_t) uop)
+long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
- struct physdev_op op;
+ int irq;
long ret;
- int irq;

- if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
- return -EFAULT;
+ switch ( cmd )
+ {
+ case PHYSDEVOP_eoi: {
+ struct physdev_eoi eoi;
+ ret = -EFAULT;
+ if ( copy_from_guest(&eoi, arg, 1) != 0 )
+ break;
+ ret = pirq_guest_eoi(current->domain, eoi.irq);
+ break;
+ }

- switch ( op.cmd )
- {
- case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+ /* Legacy since 0x00030202. */
+ case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
ret = pirq_guest_unmask(current->domain);
break;
+ }

- case PHYSDEVOP_IRQ_STATUS_QUERY:
- irq = op.u.irq_status_query.irq;
+ case PHYSDEVOP_irq_status_query: {
+ struct physdev_irq_status_query irq_status_query;
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+ break;
+ irq = irq_status_query.irq;
ret = -EINVAL;
if ( (irq < 0) || (irq >= NR_IRQS) )
break;
- op.u.irq_status_query.flags = 0;
+ irq_status_query.flags = 0;
if ( pirq_acktype(irq) != 0 )
- op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
- ret = 0;
+ irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+ ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
break;
+ }

- case PHYSDEVOP_APIC_READ:
+ case PHYSDEVOP_apic_read: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = ioapic_guest_read(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- &op.u.apic_op.value);
+ ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+ if ( copy_to_guest(arg, &apic, 1) != 0 )
+ ret = -EFAULT;
break;
+ }

- case PHYSDEVOP_APIC_WRITE:
+ case PHYSDEVOP_apic_write: {
+ struct physdev_apic apic;
+ ret = -EFAULT;
+ if ( copy_from_guest(&apic, arg, 1) != 0 )
+ break;
ret = -EPERM;
if ( !IS_PRIV(current->domain) )
break;
- ret = ioapic_guest_write(
- op.u.apic_op.apic_physbase,
- op.u.apic_op.reg,
- op.u.apic_op.value);
+ ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
break;
+ }

- case PHYSDEVOP_ASSIGN_VECTOR:
+ case PHYSDEVOP_alloc_irq_vector: {
+ struct physdev_irq irq_op;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+ break;
+
+ ret = -EPERM;
if ( !IS_PRIV(current->domain) )
- return -EPERM;
+ break;

- if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
- return -EINVAL;
+ ret = -EINVAL;
+ if ( (irq = irq_op.irq) >= NR_IRQS )
+ break;

- op.u.irq_op.vector = assign_irq_vector(irq);
- ret = 0;
+ irq_op.vector = assign_irq_vector(irq);
+ ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
break;
+ }

- case PHYSDEVOP_SET_IOPL:
+ case PHYSDEVOP_set_iopl: {
+ struct physdev_set_iopl set_iopl;
+ ret = -EFAULT;
+ if ( copy_from_guest(&set_iopl, arg, 1) != 0 )
+ break;
ret = -EINVAL;
- if ( op.u.set_iopl.iopl > 3 )
+ if ( set_iopl.iopl > 3 )
break;
ret = 0;
- current->arch.iopl = op.u.set_iopl.iopl;
+ current->arch.iopl = set_iopl.iopl;
break;
+ }

- case PHYSDEVOP_SET_IOBITMAP:
+ case PHYSDEVOP_set_iobitmap: {
+ struct physdev_set_iobitmap set_iobitmap;
+ ret = -EFAULT;
+ if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 )
+ break;
ret = -EINVAL;
- if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
- (op.u.set_iobitmap.nr_ports > 65536) )
+ if ( !access_ok(set_iobitmap.bitmap, IOBMP_BYTES) ||
+ (set_iobitmap.nr_ports > 65536) )
break;
ret = 0;
- current->arch.iobmp = op.u.set_iobitmap.bitmap;
- current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
+ current->arch.iobmp = set_iobitmap.bitmap;
+ current->arch.iobmp_limit = set_iobitmap.nr_ports;
break;
+ }
+
default:
ret = -EINVAL;
break;
}
-
- if ( copy_to_guest(uop, &op, 1) )
- ret = -EFAULT;

return ret;
}
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/setup.c Mon May 08 14:46:11 2006 -0600
@@ -391,17 +391,17 @@ void __init __start_xen(multiboot_info_t
total_pages = nr_pages;

/* Sanity check for unwanted bloat of dom0_op structure. */
- BUG_ON(sizeof(((struct dom0_op *)0)->u) !=
- sizeof(((struct dom0_op *)0)->u.pad));
-
- BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
- BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
- BUG_ON(sizeof(vcpu_info_t) != 64);
+ BUILD_BUG_ON(sizeof(((struct dom0_op *)0)->u) !=
+ sizeof(((struct dom0_op *)0)->u.pad));
+
+ BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
+ BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
+ BUILD_BUG_ON(sizeof(vcpu_info_t) != 64);

/* __foo are defined in public headers. Check they match internal defs. */
- BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
+ BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
#ifdef HYPERVISOR_VIRT_END
- BUG_ON(__HYPERVISOR_VIRT_END != HYPERVISOR_VIRT_END);
+ BUILD_BUG_ON(__HYPERVISOR_VIRT_END != HYPERVISOR_VIRT_END);
#endif

init_frametable();
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/shutdown.c
--- a/xen/arch/x86/shutdown.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/shutdown.c Mon May 08 14:46:11 2006 -0600
@@ -41,7 +41,7 @@ static inline void kb_wait(void)
break;
}

-void __attribute__((noreturn)) __machine_halt(void *unused)
+static void __attribute__((noreturn)) __machine_halt(void *unused)
{
for ( ; ; )
__asm__ __volatile__ ( "hlt" );
@@ -127,7 +127,7 @@ static const unsigned char jump_to_bios
* specified by the code and length parameters.
* We assume that length will aways be less that MAX_LENGTH!
*/
-void machine_real_restart(const unsigned char *code, unsigned length)
+static void machine_real_restart(const unsigned char *code, unsigned length)
{
local_irq_disable();

@@ -218,7 +218,9 @@ void machine_restart(char * __unused)
/* Ensure we are the boot CPU. */
if ( GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid )
{
- smp_call_function((void *)machine_restart, NULL, 1, 0);
+ /* Send IPI to the boot CPU (logical cpu 0). */
+ on_selected_cpus(cpumask_of_cpu(0), (void *)machine_restart,
+ NULL, 1, 0);
for ( ; ; )
safe_halt();
}
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/smp.c Mon May 08 14:46:11 2006 -0600
@@ -169,6 +169,7 @@ fastcall void smp_invalidate_interrupt(v
{
ack_APIC_irq();
perfc_incrc(ipis);
+ irq_enter();
if ( !__sync_lazy_execstate() )
{
if ( flush_va == FLUSHVA_ALL )
@@ -177,6 +178,7 @@ fastcall void smp_invalidate_interrupt(v
local_flush_tlb_one(flush_va);
}
cpu_clear(smp_processor_id(), flush_cpumask);
+ irq_exit();
}

void __flush_tlb_mask(cpumask_t mask, unsigned long va)
@@ -335,6 +337,8 @@ fastcall void smp_call_function_interrup
if ( !cpu_isset(smp_processor_id(), call_data->selected) )
return;

+ irq_enter();
+
if ( call_data->wait )
{
(*func)(info);
@@ -347,4 +351,6 @@ fastcall void smp_call_function_interrup
atomic_inc(&call_data->started);
(*func)(info);
}
-}
+
+ irq_exit();
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/traps.c Mon May 08 14:46:11 2006 -0600
@@ -674,6 +674,8 @@ asmlinkage int do_page_fault(struct cpu_
unsigned long addr, fixup;
int rc;

+ ASSERT(!in_irq());
+
__asm__ __volatile__ ("mov %%cr2,%0" : "=r" (addr) : );

DEBUGGER_trap_entry(TRAP_page_fault, regs);
@@ -1535,7 +1537,7 @@ void __init trap_init(void)
}


-long do_set_trap_table(GUEST_HANDLE(trap_info_t) traps)
+long do_set_trap_table(XEN_GUEST_HANDLE(trap_info_t) traps)
{
struct trap_info cur;
struct trap_info *dst = current->arch.guest_context.trap_ctxt;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_32/entry.S Mon May 08 14:46:11 2006 -0600
@@ -630,10 +630,10 @@ ENTRY(hypercall_table)
.long do_multicall
.long do_update_va_mapping
.long do_set_timer_op /* 15 */
- .long do_event_channel_op
+ .long do_event_channel_op_compat
.long do_xen_version
.long do_console_io
- .long do_physdev_op
+ .long do_physdev_op_compat
.long do_grant_table_op /* 20 */
.long do_vm_assist
.long do_update_va_mapping_otherdomain
@@ -646,6 +646,8 @@ ENTRY(hypercall_table)
.long do_arch_sched_op
.long do_callback_op /* 30 */
.long do_xenoprof_op
+ .long do_event_channel_op
+ .long do_physdev_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -667,10 +669,10 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_multicall */
.byte 4 /* do_update_va_mapping */
.byte 2 /* do_set_timer_op */ /* 15 */
- .byte 1 /* do_event_channel_op */
+ .byte 1 /* do_event_channel_op_compat */
.byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
- .byte 1 /* do_physdev_op */
+ .byte 1 /* do_physdev_op_compat */
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 5 /* do_update_va_mapping_otherdomain */
@@ -683,6 +685,8 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_arch_sched_op */
.byte 2 /* do_callback_op */ /* 30 */
.byte 2 /* do_xenoprof_op */
+ .byte 2 /* do_event_channel_op */
+ .byte 2 /* do_physdev_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_32/mm.c Mon May 08 14:46:11 2006 -0600
@@ -155,17 +155,10 @@ void subarch_init_memory(void)
* 64-bit operations on them. Also, just for sanity, we assert the size
* of the structure here.
*/
- if ( (offsetof(struct page_info, u.inuse._domain) !=
- (offsetof(struct page_info, count_info) + sizeof(u32))) ||
- ((offsetof(struct page_info, count_info) & 7) != 0) ||
- (sizeof(struct page_info) != 24) )
- {
- printk("Weird page_info layout (%ld,%ld,%d)\n",
- offsetof(struct page_info, count_info),
- offsetof(struct page_info, u.inuse._domain),
- sizeof(struct page_info));
- BUG();
- }
+ BUILD_BUG_ON(offsetof(struct page_info, u.inuse._domain) !=
+ (offsetof(struct page_info, count_info) + sizeof(u32)));
+ BUILD_BUG_ON((offsetof(struct page_info, count_info) & 7) != 0);
+ BUILD_BUG_ON(sizeof(struct page_info) != 24);

/* M2P table is mappable read-only by privileged domains. */
for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
@@ -189,7 +182,7 @@ void subarch_init_memory(void)
}
}

-long subarch_memory_op(int op, GUEST_HANDLE(void) arg)
+long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
{
struct xen_machphys_mfn_list xmml;
unsigned long mfn;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_32/traps.c Mon May 08 14:46:11 2006 -0600
@@ -243,6 +243,7 @@ unsigned long do_iret(void)
return regs->eax;
}

+#include <asm/asm_defns.h>
BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
fastcall void smp_deferred_nmi(struct cpu_user_regs *regs)
{
@@ -387,7 +388,7 @@ static long unregister_guest_callback(st
}


-long do_callback_op(int cmd, GUEST_HANDLE(void) arg)
+long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
long ret;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_64/entry.S Mon May 08 14:46:11 2006 -0600
@@ -538,10 +538,10 @@ ENTRY(hypercall_table)
.quad do_multicall
.quad do_update_va_mapping
.quad do_set_timer_op /* 15 */
- .quad do_event_channel_op
+ .quad do_event_channel_op_compat
.quad do_xen_version
.quad do_console_io
- .quad do_physdev_op
+ .quad do_physdev_op_compat
.quad do_grant_table_op /* 20 */
.quad do_vm_assist
.quad do_update_va_mapping_otherdomain
@@ -554,6 +554,8 @@ ENTRY(hypercall_table)
.quad do_arch_sched_op
.quad do_callback_op /* 30 */
.quad do_xenoprof_op
+ .quad do_event_channel_op
+ .quad do_physdev_op
.rept NR_hypercalls-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
@@ -575,10 +577,10 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_multicall */
.byte 3 /* do_update_va_mapping */
.byte 1 /* do_set_timer_op */ /* 15 */
- .byte 1 /* do_event_channel_op */
+ .byte 1 /* do_event_channel_op_compat */
.byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
- .byte 1 /* do_physdev_op */
+ .byte 1 /* do_physdev_op_compat */
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 4 /* do_update_va_mapping_otherdomain */
@@ -591,6 +593,8 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_arch_sched_op */
.byte 2 /* do_callback_op */ /* 30 */
.byte 2 /* do_xenoprof_op */
+ .byte 2 /* do_event_channel_op */
+ .byte 2 /* do_physdev_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_64/mm.c Mon May 08 14:46:11 2006 -0600
@@ -145,19 +145,11 @@ void subarch_init_memory(void)
* count_info and domain fields must be adjacent, as we perform atomic
* 64-bit operations on them.
*/
- if ( ((offsetof(struct page_info, u.inuse._domain) !=
- (offsetof(struct page_info, count_info) + sizeof(u32)))) ||
- ((offsetof(struct page_info, count_info) & 7) != 0) ||
- (sizeof(struct page_info) !=
- (32 + BITS_TO_LONGS(NR_CPUS)*sizeof(long))) )
- {
- printk("Weird page_info layout (%ld,%ld,%ld,%ld)\n",
- offsetof(struct page_info, count_info),
- offsetof(struct page_info, u.inuse._domain),
- sizeof(struct page_info),
- 32 + BITS_TO_LONGS(NR_CPUS)*sizeof(long));
- for ( ; ; ) ;
- }
+ BUILD_BUG_ON(offsetof(struct page_info, u.inuse._domain) !=
+ (offsetof(struct page_info, count_info) + sizeof(u32)));
+ BUILD_BUG_ON((offsetof(struct page_info, count_info) & 7) != 0);
+ BUILD_BUG_ON(sizeof(struct page_info) !=
+ (32 + BITS_TO_LONGS(NR_CPUS)*sizeof(long)));

/* M2P table is mappable read-only by privileged domains. */
for ( v = RDWR_MPT_VIRT_START;
@@ -181,7 +173,7 @@ void subarch_init_memory(void)
}
}

-long subarch_memory_op(int op, GUEST_HANDLE(void) arg)
+long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
{
struct xen_machphys_mfn_list xmml;
l3_pgentry_t l3e;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/arch/x86/x86_64/traps.c Mon May 08 14:46:11 2006 -0600
@@ -371,7 +371,7 @@ static long unregister_guest_callback(st
}


-long do_callback_op(int cmd, GUEST_HANDLE(void) arg)
+long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
long ret;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/acm_ops.c Mon May 08 14:46:11 2006 -0600
@@ -32,7 +32,7 @@

#ifndef ACM_SECURITY

-long do_acm_op(GUEST_HANDLE(acm_op_t) u_acm_op)
+long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
{
return -ENOSYS;
}
@@ -57,7 +57,7 @@ int acm_authorize_acm_ops(struct domain
return 0;
}

-long do_acm_op(GUEST_HANDLE(acm_op_t) u_acm_op)
+long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
{
long ret = 0;
struct acm_op curop, *op = &curop;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/dom0_ops.c Mon May 08 14:46:11 2006 -0600
@@ -24,7 +24,7 @@
#include <acm/acm_hooks.h>

extern long arch_do_dom0_op(
- struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op);
+ struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op);
extern void arch_getdomaininfo_ctxt(
struct vcpu *, struct vcpu_guest_context *);

@@ -90,7 +90,7 @@ static void getdomaininfo(struct domain
memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
}

-long do_dom0_op(GUEST_HANDLE(dom0_op_t) u_dom0_op)
+long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
{
long ret = 0;
struct dom0_op curop, *op = &curop;
@@ -641,7 +641,7 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t)
unsigned int pirq = op->u.irq_permission.pirq;

ret = -EINVAL;
- if ( pirq >= NR_PIRQS )
+ if ( pirq >= NR_IRQS )
break;

ret = -ESRCH;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/domain.c
--- a/xen/common/domain.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/domain.c Mon May 08 14:46:11 2006 -0600
@@ -408,7 +408,7 @@ int boot_vcpu(struct domain *d, int vcpu
return arch_set_info_guest(v, ctxt);
}

-long do_vcpu_op(int cmd, int vcpuid, GUEST_HANDLE(void) arg)
+long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
{
struct domain *d = current->domain;
struct vcpu *v;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/event_channel.c
--- a/xen/common/event_channel.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/event_channel.c Mon May 08 14:46:11 2006 -0600
@@ -97,7 +97,10 @@ static long evtchn_alloc_unbound(evtchn_
struct domain *d;
int port;
domid_t dom = alloc->dom;
- long rc = 0;
+ long rc;
+
+ if ( (rc = acm_pre_eventchannel_unbound(dom, alloc->remote_dom)) != 0 )
+ return rc;

if ( dom == DOMID_SELF )
dom = current->domain->domain_id;
@@ -134,7 +137,10 @@ static long evtchn_bind_interdomain(evtc
struct domain *ld = current->domain, *rd;
int lport, rport = bind->remote_port;
domid_t rdom = bind->remote_dom;
- long rc = 0;
+ long rc;
+
+ if ( (rc = acm_pre_eventchannel_interdomain(rdom)) != 0 )
+ return rc;

if ( rdom == DOMID_SELF )
rdom = current->domain->domain_id;
@@ -201,13 +207,14 @@ static long evtchn_bind_virq(evtchn_bind
int port, virq = bind->virq, vcpu = bind->vcpu;
long rc = 0;

- if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
+ if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
return -EINVAL;

if ( virq_is_global(virq) && (vcpu != 0) )
return -EINVAL;

- if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
+ if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+ ((v = d->vcpu[vcpu]) == NULL) )
return -ENOENT;

spin_lock(&d->evtchn_lock);
@@ -239,7 +246,8 @@ static long evtchn_bind_ipi(evtchn_bind_
int port, vcpu = bind->vcpu;
long rc = 0;

- if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
+ if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+ (d->vcpu[vcpu] == NULL) )
return -ENOENT;

spin_lock(&d->evtchn_lock);
@@ -267,7 +275,7 @@ static long evtchn_bind_pirq(evtchn_bind
int port, pirq = bind->pirq;
long rc;

- if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
+ if ( (pirq < 0) || (pirq >= ARRAY_SIZE(d->pirq_to_evtchn)) )
return -EINVAL;

if ( !irq_access_permitted(d, pirq) )
@@ -683,70 +691,103 @@ static long evtchn_unmask(evtchn_unmask_
}


-long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop)
+long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
long rc;
- struct evtchn_op op;
-
- if ( copy_from_guest(&op, uop, 1) != 0 )
- return -EFAULT;
-
- if (acm_pre_event_channel(&op))
- return -EACCES;
-
- switch ( op.cmd )
- {
- case EVTCHNOP_alloc_unbound:
- rc = evtchn_alloc_unbound(&op.u.alloc_unbound);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+
+ switch ( cmd )
+ {
+ case EVTCHNOP_alloc_unbound: {
+ struct evtchn_alloc_unbound alloc_unbound;
+ if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_alloc_unbound(&alloc_unbound);
+ if ( (rc == 0) && (copy_to_guest(arg, &alloc_unbound, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
-
- case EVTCHNOP_bind_interdomain:
- rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ }
+
+ case EVTCHNOP_bind_interdomain: {
+ struct evtchn_bind_interdomain bind_interdomain;
+ if ( copy_from_guest(&bind_interdomain, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_interdomain(&bind_interdomain);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_interdomain, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
-
- case EVTCHNOP_bind_virq:
- rc = evtchn_bind_virq(&op.u.bind_virq);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ }
+
+ case EVTCHNOP_bind_virq: {
+ struct evtchn_bind_virq bind_virq;
+ if ( copy_from_guest(&bind_virq, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_virq(&bind_virq);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_virq, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
-
- case EVTCHNOP_bind_ipi:
- rc = evtchn_bind_ipi(&op.u.bind_ipi);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ }
+
+ case EVTCHNOP_bind_ipi: {
+ struct evtchn_bind_ipi bind_ipi;
+ if ( copy_from_guest(&bind_ipi, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_ipi(&bind_ipi);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_ipi, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
-
- case EVTCHNOP_bind_pirq:
- rc = evtchn_bind_pirq(&op.u.bind_pirq);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ }
+
+ case EVTCHNOP_bind_pirq: {
+ struct evtchn_bind_pirq bind_pirq;
+ if ( copy_from_guest(&bind_pirq, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_pirq(&bind_pirq);
+ if ( (rc == 0) && (copy_to_guest(arg, &bind_pirq, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
-
- case EVTCHNOP_close:
- rc = evtchn_close(&op.u.close);
- break;
-
- case EVTCHNOP_send:
- rc = evtchn_send(op.u.send.port);
- break;
-
- case EVTCHNOP_status:
- rc = evtchn_status(&op.u.status);
- if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+ }
+
+ case EVTCHNOP_close: {
+ struct evtchn_close close;
+ if ( copy_from_guest(&close, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_close(&close);
+ break;
+ }
+
+ case EVTCHNOP_send: {
+ struct evtchn_send send;
+ if ( copy_from_guest(&send, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_send(send.port);
+ break;
+ }
+
+ case EVTCHNOP_status: {
+ struct evtchn_status status;
+ if ( copy_from_guest(&status, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_status(&status);
+ if ( (rc == 0) && (copy_to_guest(arg, &status, 1) != 0) )
rc = -EFAULT;
break;
-
- case EVTCHNOP_bind_vcpu:
- rc = evtchn_bind_vcpu(op.u.bind_vcpu.port, op.u.bind_vcpu.vcpu);
- break;
-
- case EVTCHNOP_unmask:
- rc = evtchn_unmask(&op.u.unmask);
- break;
+ }
+
+ case EVTCHNOP_bind_vcpu: {
+ struct evtchn_bind_vcpu bind_vcpu;
+ if ( copy_from_guest(&bind_vcpu, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_bind_vcpu(bind_vcpu.port, bind_vcpu.vcpu);
+ break;
+ }
+
+ case EVTCHNOP_unmask: {
+ struct evtchn_unmask unmask;
+ if ( copy_from_guest(&unmask, arg, 1) != 0 )
+ return -EFAULT;
+ rc = evtchn_unmask(&unmask);
+ break;
+ }

default:
rc = -ENOSYS;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/grant_table.c
--- a/xen/common/grant_table.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/grant_table.c Mon May 08 14:46:11 2006 -0600
@@ -301,7 +301,7 @@ __gnttab_map_grant_ref(

static long
gnttab_map_grant_ref(
- GUEST_HANDLE(gnttab_map_grant_ref_t) uop, unsigned int count)
+ XEN_GUEST_HANDLE(gnttab_map_grant_ref_t) uop, unsigned int count)
{
int i;
struct gnttab_map_grant_ref op;
@@ -438,7 +438,7 @@ __gnttab_unmap_grant_ref(

static long
gnttab_unmap_grant_ref(
- GUEST_HANDLE(gnttab_unmap_grant_ref_t) uop, unsigned int count)
+ XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t) uop, unsigned int count)
{
int i;
struct gnttab_unmap_grant_ref op;
@@ -462,7 +462,7 @@ fault:

static long
gnttab_setup_table(
- GUEST_HANDLE(gnttab_setup_table_t) uop, unsigned int count)
+ XEN_GUEST_HANDLE(gnttab_setup_table_t) uop, unsigned int count)
{
struct gnttab_setup_table op;
struct domain *d;
@@ -598,7 +598,7 @@ gnttab_prepare_for_transfer(

static long
gnttab_transfer(
- GUEST_HANDLE(gnttab_transfer_t) uop, unsigned int count)
+ XEN_GUEST_HANDLE(gnttab_transfer_t) uop, unsigned int count)
{
struct domain *d = current->domain;
struct domain *e;
@@ -711,7 +711,7 @@ gnttab_transfer(

long
do_grant_table_op(
- unsigned int cmd, GUEST_HANDLE(void) uop, unsigned int count)
+ unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count)
{
long rc;
struct domain *d = current->domain;
@@ -728,7 +728,7 @@ do_grant_table_op(
{
case GNTTABOP_map_grant_ref:
{
- GUEST_HANDLE(gnttab_map_grant_ref_t) map =
+ XEN_GUEST_HANDLE(gnttab_map_grant_ref_t) map =
guest_handle_cast(uop, gnttab_map_grant_ref_t);
if ( unlikely(!guest_handle_okay(map, count)) )
goto out;
@@ -737,7 +737,7 @@ do_grant_table_op(
}
case GNTTABOP_unmap_grant_ref:
{
- GUEST_HANDLE(gnttab_unmap_grant_ref_t) unmap =
+ XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t) unmap =
guest_handle_cast(uop, gnttab_unmap_grant_ref_t);
if ( unlikely(!guest_handle_okay(unmap, count)) )
goto out;
@@ -752,7 +752,7 @@ do_grant_table_op(
}
case GNTTABOP_transfer:
{
- GUEST_HANDLE(gnttab_transfer_t) transfer =
+ XEN_GUEST_HANDLE(gnttab_transfer_t) transfer =
guest_handle_cast(uop, gnttab_transfer_t);
if ( unlikely(!guest_handle_okay(transfer, count)) )
goto out;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/kernel.c
--- a/xen/common/kernel.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/kernel.c Mon May 08 14:46:11 2006 -0600
@@ -118,7 +118,7 @@ void add_taint(unsigned flag)
* Simple hypercalls.
*/

-long do_xen_version(int cmd, GUEST_HANDLE(void) arg)
+long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
{
switch ( cmd )
{
@@ -244,7 +244,7 @@ long unregister_guest_nmi_callback(void)
return 0;
}

-long do_nmi_op(unsigned int cmd, GUEST_HANDLE(void) arg)
+long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
{
struct xennmi_callback cb;
long rc = 0;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/memory.c
--- a/xen/common/memory.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/memory.c Mon May 08 14:46:11 2006 -0600
@@ -31,7 +31,7 @@ static long
static long
increase_reservation(
struct domain *d,
- GUEST_HANDLE(ulong) extent_list,
+ XEN_GUEST_HANDLE(ulong) extent_list,
unsigned int nr_extents,
unsigned int extent_order,
unsigned int flags,
@@ -80,7 +80,7 @@ static long
static long
populate_physmap(
struct domain *d,
- GUEST_HANDLE(ulong) extent_list,
+ XEN_GUEST_HANDLE(ulong) extent_list,
unsigned int nr_extents,
unsigned int extent_order,
unsigned int flags,
@@ -177,7 +177,7 @@ static long
static long
decrease_reservation(
struct domain *d,
- GUEST_HANDLE(ulong) extent_list,
+ XEN_GUEST_HANDLE(ulong) extent_list,
unsigned int nr_extents,
unsigned int extent_order,
unsigned int flags,
@@ -211,7 +211,7 @@ decrease_reservation(

static long
translate_gpfn_list(
- GUEST_HANDLE(xen_translate_gpfn_list_t) uop, unsigned long *progress)
+ XEN_GUEST_HANDLE(xen_translate_gpfn_list_t) uop, unsigned long *progress)
{
struct xen_translate_gpfn_list op;
unsigned long i, gpfn, mfn;
@@ -270,7 +270,7 @@ translate_gpfn_list(
return 0;
}

-long do_memory_op(unsigned long cmd, GUEST_HANDLE(void) arg)
+long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg)
{
struct domain *d;
int rc, op, flags = 0, preempted = 0;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/multicall.c
--- a/xen/common/multicall.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/multicall.c Mon May 08 14:46:11 2006 -0600
@@ -18,7 +18,7 @@ struct mc_state mc_state[NR_CPUS];

long
do_multicall(
- GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls)
+ XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls)
{
struct mc_state *mcs = &mc_state[smp_processor_id()];
unsigned int i;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/perfc.c
--- a/xen/common/perfc.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/perfc.c Mon May 08 14:46:11 2006 -0600
@@ -37,7 +37,7 @@ struct perfcounter perfcounters;

void perfc_printall(unsigned char key)
{
- int i, j, sum;
+ unsigned int i, j, sum;
s_time_t now = NOW();
atomic_t *counters = (atomic_t *)&perfcounters;

@@ -59,22 +59,28 @@ void perfc_printall(unsigned char key)
sum = 0;
for_each_online_cpu ( j )
sum += atomic_read(&counters[j]);
- printk("TOTAL[%10d] ", sum);
- for_each_online_cpu ( j )
- printk("CPU%02d[%10d] ", j, atomic_read(&counters[j]));
+ printk("TOTAL[%10u]", sum);
+ if (sum)
+ {
+ for_each_online_cpu ( j )
+ printk(" CPU%02d[%10d]", j, atomic_read(&counters[j]));
+ }
counters += NR_CPUS;
break;
case TYPE_ARRAY:
case TYPE_S_ARRAY:
for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
sum += atomic_read(&counters[j]);
- printk("TOTAL[%10d] ", sum);
-#ifdef PERF_ARRAYS
- for ( j = 0; j < perfc_info[i].nr_elements; j++ )
- {
- if ( (j != 0) && ((j % 4) == 0) )
- printk("\n ");
- printk("ARR%02d[%10d] ", j, atomic_read(&counters[j]));
+ printk("TOTAL[%10u]", sum);
+#ifdef PERF_ARRAYS
+ if (sum)
+ {
+ for ( j = 0; j < perfc_info[i].nr_elements; j++ )
+ {
+ if ( (j % 4) == 0 )
+ printk("\n ");
+ printk(" ARR%02d[%10d]", j, atomic_read(&counters[j]));
+ }
}
#endif
counters += j;
@@ -90,7 +96,7 @@ void perfc_printall(unsigned char key)

void perfc_reset(unsigned char key)
{
- int i, j;
+ unsigned int i, j;
s_time_t now = NOW();
atomic_t *counters = (atomic_t *)&perfcounters;

@@ -116,7 +122,7 @@ void perfc_reset(unsigned char key)
counters += NR_CPUS;
break;
case TYPE_ARRAY:
- for ( j = 0; j < NR_CPUS; j++ )
+ for ( j = 0; j < perfc_info[i].nr_elements; j++ )
atomic_set(&counters[j],0);
case TYPE_S_ARRAY:
counters += perfc_info[i].nr_elements;
@@ -131,7 +137,7 @@ void perfc_reset(unsigned char key)

static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
static int perfc_init = 0;
-static int perfc_copy_info(GUEST_HANDLE(dom0_perfc_desc_t) desc)
+static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc)
{
unsigned int i, j;
atomic_t *counters = (atomic_t *)&perfcounters;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/common/schedule.c
--- a/xen/common/schedule.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/common/schedule.c Mon May 08 14:46:11 2006 -0600
@@ -365,7 +365,7 @@ long do_sched_op_compat(int cmd, unsigne
return ret;
}

-long do_sched_op(int cmd, GUEST_HANDLE(void) arg)
+long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
long ret = 0;

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Mon May 08 13:41:18 2006 -0600
+++ b/xen/drivers/char/console.c Mon May 08 14:46:11 2006 -0600
@@ -221,7 +221,7 @@ static void putchar_console_ring(int c)
conringc = conringp - CONRING_SIZE;
}

-long read_console_ring(GUEST_HANDLE(char) str, u32 *pcount, int clear)
+long read_console_ring(XEN_GUEST_HANDLE(char) str, u32 *pcount, int clear)
{
unsigned int idx, len, max, sofar, c;
unsigned long flags;
@@ -319,7 +319,7 @@ static void serial_rx(char c, struct cpu
__serial_rx(c, regs);
}

-static long guest_console_write(GUEST_HANDLE(char) buffer, int count)
+static long guest_console_write(XEN_GUEST_HANDLE(char) buffer, int count)
{
char kbuf[128], *kptr;
int kcount;
@@ -355,7 +355,7 @@ static long guest_console_write(GUEST_HA
return 0;
}

-long do_console_io(int cmd, int count, GUEST_HANDLE(char) buffer)
+long do_console_io(int cmd, int count, XEN_GUEST_HANDLE(char) buffer)
{
long rc;
unsigned int idx, len;
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/acm/acm_hooks.h Mon May 08 14:46:11 2006 -0600
@@ -135,7 +135,9 @@ static inline void acm_post_dom0_op(stru
{ return; }
static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid)
{ return; }
-static inline int acm_pre_event_channel(struct evtchn_op *op)
+static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
+{ return 0; }
+static inline int acm_pre_eventchannel_interdomain(domid_t id)
{ return 0; }
static inline int acm_pre_grant_map_ref(domid_t id)
{ return 0; }
@@ -289,26 +291,6 @@ static inline void acm_fail_dom0_op(stru
}
}

-static inline int acm_pre_event_channel(struct evtchn_op *op)
-{
- int ret = -EACCES;
-
- switch(op->cmd) {
- case EVTCHNOP_alloc_unbound:
- ret = acm_pre_eventchannel_unbound(
- op->u.alloc_unbound.dom,
- op->u.alloc_unbound.remote_dom);
- break;
- case EVTCHNOP_bind_interdomain:
- ret = acm_pre_eventchannel_interdomain(
- op->u.bind_interdomain.remote_dom);
- break;
- default:
- ret = 0; /* ok */
- }
- return ret;
-}
-
static inline int acm_pre_grant_map_ref(domid_t id)
{
if ( (acm_primary_ops->pre_grant_map_ref != NULL) &&
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-ia64/config.h Mon May 08 14:46:11 2006 -0600
@@ -79,8 +79,6 @@ extern char _end[]; /* standard ELF symb
extern char _end[]; /* standard ELF symbol */

// linux/include/linux/compiler.h
-#define __attribute_const__
-#define __user
//#define __kernel
//#define __safe
#define __force
@@ -98,7 +96,6 @@ extern char _end[]; /* standard ELF symb
// xen/include/asm/config.h
//#define HZ 1000
// FIXME SMP: leave SMP for a later time
-#define barrier() __asm__ __volatile__("": : :"memory")

///////////////////////////////////////////////////////////////
// xen/include/asm/config.h
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-ia64/guest_access.h
--- a/xen/include/asm-ia64/guest_access.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-ia64/guest_access.h Mon May 08 14:46:11 2006 -0600
@@ -18,10 +18,10 @@
/* Cast a guest handle to the specified type of handle. */
#define guest_handle_cast(hnd, type) ({ \
type *_x = (hnd).p; \
- (GUEST_HANDLE(type)) { _x }; \
+ (XEN_GUEST_HANDLE(type)) { _x }; \
})

-#define guest_handle_from_ptr(ptr, type) ((GUEST_HANDLE(type)) { (type *)ptr })
+#define guest_handle_from_ptr(ptr, type) ((XEN_GUEST_HANDLE(type)) { (type *)ptr })

/*
* Copy an array of objects to guest context via a guest handle,
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-ia64/hypercall.h
--- a/xen/include/asm-ia64/hypercall.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-ia64/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -9,6 +9,10 @@
#include <asm/types.h>
#include <asm/vcpu.h>

+extern long
+do_event_channel_op_compat(
+ XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
extern int
vmx_do_mmu_update(
mmu_update_t *ureqs,
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/config.h Mon May 08 14:46:11 2006 -0600
@@ -63,10 +63,8 @@
name:
#endif

-#define barrier() __asm__ __volatile__("": : :"memory")
-
/* A power-of-two value greater than or equal to number of hypercalls. */
-#define NR_hypercalls 32
+#define NR_hypercalls 64

#if NR_hypercalls & (NR_hypercalls - 1)
#error "NR_hypercalls must be a power-of-two value"
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/guest_access.h
--- a/xen/include/asm-x86/guest_access.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/guest_access.h Mon May 08 14:46:11 2006 -0600
@@ -18,7 +18,7 @@
/* Cast a guest handle to the specified type of handle. */
#define guest_handle_cast(hnd, type) ({ \
type *_x = (hnd).p; \
- (GUEST_HANDLE(type)) { _x }; \
+ (XEN_GUEST_HANDLE(type)) { _x }; \
})

/*
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/support.h Mon May 08 14:46:11 2006 -0600
@@ -94,8 +94,7 @@ enum hval_bitmaps {
#else
#define MONITOR_DEFAULT_EXCEPTION_BITMAP \
( EXCEPTION_BITMAP_PG | \
- EXCEPTION_BITMAP_BP | \
- EXCEPTION_BITMAP_GP )
+ EXCEPTION_BITMAP_BP )
#endif

#define PC_DEBUG_PORT 0x80
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Mon May 08 14:46:11 2006 -0600
@@ -68,6 +68,7 @@ struct arch_vmx_struct {
struct vmcs_struct *vmcs; /* VMCS pointer in virtual. */
unsigned int launch_cpu; /* VMCS is valid on this CPU. */
u32 exec_control; /* cache of cpu execution control */
+ u32 vector_injected; /* if there is vector installed in the INTR_INFO_FIELD */
unsigned long flags; /* VMCS flags */
unsigned long cpu_cr0; /* copy of guest CR0 */
unsigned long cpu_shadow_cr0; /* copy of guest read shadow CR0 */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Mon May 08 14:46:11 2006 -0600
@@ -444,6 +444,7 @@ static inline int __vmx_inject_exception

static inline int vmx_inject_exception(struct vcpu *v, int trap, int error_code)
{
+ v->arch.hvm_vmx.vector_injected = 1;
return __vmx_inject_exception(v, trap, INTR_TYPE_EXCEPTION, error_code);
}

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/hypercall.h
--- a/xen/include/asm-x86/hypercall.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -8,19 +8,27 @@
#include <public/physdev.h>

extern long
+do_event_channel_op_compat(
+ XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
+extern long
+do_physdev_op_compat(
+ XEN_GUEST_HANDLE(physdev_op_t) uop);
+
+extern long
do_set_trap_table(
- GUEST_HANDLE(trap_info_t) traps);
+ XEN_GUEST_HANDLE(trap_info_t) traps);

extern int
do_mmu_update(
- GUEST_HANDLE(mmu_update_t) ureqs,
+ XEN_GUEST_HANDLE(mmu_update_t) ureqs,
unsigned int count,
- GUEST_HANDLE(uint) pdone,
+ XEN_GUEST_HANDLE(uint) pdone,
unsigned int foreigndom);

extern long
do_set_gdt(
- GUEST_HANDLE(ulong) frame_list,
+ XEN_GUEST_HANDLE(ulong) frame_list,
unsigned int entries);

extern long
@@ -54,7 +62,7 @@ do_update_va_mapping(

extern long
do_physdev_op(
- GUEST_HANDLE(physdev_op_t) uop);
+ int cmd, XEN_GUEST_HANDLE(void) arg);

extern int
do_update_va_mapping_otherdomain(
@@ -65,9 +73,9 @@ do_update_va_mapping_otherdomain(

extern int
do_mmuext_op(
- GUEST_HANDLE(mmuext_op_t) uops,
+ XEN_GUEST_HANDLE(mmuext_op_t) uops,
unsigned int count,
- GUEST_HANDLE(uint) pdone,
+ XEN_GUEST_HANDLE(uint) pdone,
unsigned int foreigndom);

extern unsigned long
@@ -77,7 +85,7 @@ struct vcpu;
struct vcpu;
extern long
arch_do_vcpu_op(
- int cmd, struct vcpu *v, GUEST_HANDLE(void) arg);
+ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg);

#ifdef __x86_64__

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/irq.h Mon May 08 14:46:11 2006 -0600
@@ -5,7 +5,6 @@

#include <xen/config.h>
#include <asm/atomic.h>
-#include <asm/asm_defns.h>
#include <irq_vectors.h>

#define IO_APIC_IRQ(irq) (((irq) >= 16) || ((1<<(irq)) & io_apic_irqs))
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/mm.h Mon May 08 14:46:11 2006 -0600
@@ -274,6 +274,8 @@ int check_descriptor(struct desc_struct
* been used by the read-only MPT map.
*/
#define phys_to_machine_mapping ((unsigned long *)RO_MPT_VIRT_START)
+#define NR_P2M_TABLE_ENTRIES ((unsigned long *)RO_MPT_VIRT_END \
+ - phys_to_machine_mapping)
#define INVALID_MFN (~0UL)
#define VALID_MFN(_mfn) (!((_mfn) & (1U<<31)))

@@ -282,7 +284,9 @@ static inline unsigned long get_mfn_from
{
unsigned long mfn;

- if ( __copy_from_user(&mfn, &phys_to_machine_mapping[pfn], sizeof(mfn)) )
+ if ( unlikely(pfn >= NR_P2M_TABLE_ENTRIES) ||
+ unlikely(__copy_from_user(&mfn, &phys_to_machine_mapping[pfn],
+ sizeof(mfn))) )
mfn = INVALID_MFN;

return mfn;
@@ -382,7 +386,7 @@ int __sync_lazy_execstate(void);
int __sync_lazy_execstate(void);

/* Arch-specific portion of memory_op hypercall. */
-long arch_memory_op(int op, GUEST_HANDLE(void) arg);
-long subarch_memory_op(int op, GUEST_HANDLE(void) arg);
+long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
+long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);

#endif /* __ASM_X86_MM_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/asm-x86/uaccess.h
--- a/xen/include/asm-x86/uaccess.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/asm-x86/uaccess.h Mon May 08 14:46:11 2006 -0600
@@ -7,8 +7,6 @@
#include <xen/errno.h>
#include <xen/prefetch.h>
#include <asm/page.h>
-
-#define __user

#ifdef __x86_64__
#include <asm/x86_64/uaccess.h>
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/acm_ops.h Mon May 08 14:46:11 2006 -0600
@@ -83,7 +83,7 @@ typedef struct acm_op {
struct acm_getdecision getdecision;
} u;
} acm_op_t;
-DEFINE_GUEST_HANDLE(acm_op_t);
+DEFINE_XEN_GUEST_HANDLE(acm_op_t);

#endif /* __XEN_PUBLIC_ACM_OPS_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/arch-ia64.h Mon May 08 14:46:11 2006 -0600
@@ -7,27 +7,29 @@
#ifndef __HYPERVISOR_IF_IA64_H__
#define __HYPERVISOR_IF_IA64_H__

-#ifdef __XEN__
-#define __DEFINE_GUEST_HANDLE(name, type) \
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
typedef struct { type *p; } __guest_handle_ ## name
-#else
-#define __DEFINE_GUEST_HANDLE(name, type) \
- typedef type * __guest_handle_ ## name
+
+#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
+#define XEN_GUEST_HANDLE(name) __guest_handle_ ## name
+#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
+#ifdef __XEN_TOOLS__
+#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
#endif
-
-#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
-#define GUEST_HANDLE(name) __guest_handle_ ## name

#ifndef __ASSEMBLY__
/* Guest handles for primitive C types. */
-__DEFINE_GUEST_HANDLE(uchar, unsigned char);
-__DEFINE_GUEST_HANDLE(uint, unsigned int);
-__DEFINE_GUEST_HANDLE(ulong, unsigned long);
-DEFINE_GUEST_HANDLE(char);
-DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(long);
-DEFINE_GUEST_HANDLE(void);
+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int);
+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_XEN_GUEST_HANDLE(char);
+DEFINE_XEN_GUEST_HANDLE(int);
+DEFINE_XEN_GUEST_HANDLE(long);
+DEFINE_XEN_GUEST_HANDLE(void);
#endif
+
+/* Arch specific VIRQs definition */
+#define VIRQ_ITC VIRQ_ARCH_0 /* V. Virtual itc timer */

/* Maximum number of virtual CPUs in multi-processor guests. */
/* WARNING: before changing this, check that shared_info fits on a page */
@@ -324,7 +326,7 @@ typedef struct vcpu_guest_context {
arch_initrd_info_t initrd;
char cmdline[IA64_COMMAND_LINE_SIZE];
} vcpu_guest_context_t;
-DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

// dom0 vp op
#define __HYPERVISOR_ia64_dom0vp_op 256 // XXX sufficient large
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/arch-x86_32.h Mon May 08 14:46:11 2006 -0600
@@ -9,26 +9,25 @@
#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
#define __XEN_PUBLIC_ARCH_X86_32_H__

-#ifdef __XEN__
-#define __DEFINE_GUEST_HANDLE(name, type) \
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
typedef struct { type *p; } __guest_handle_ ## name
-#else
-#define __DEFINE_GUEST_HANDLE(name, type) \
- typedef type * __guest_handle_ ## name
+
+#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
+#define XEN_GUEST_HANDLE(name) __guest_handle_ ## name
+#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
+#ifdef __XEN_TOOLS__
+#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
#endif
-
-#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
-#define GUEST_HANDLE(name) __guest_handle_ ## name

#ifndef __ASSEMBLY__
/* Guest handles for primitive C types. */
-__DEFINE_GUEST_HANDLE(uchar, unsigned char);
-__DEFINE_GUEST_HANDLE(uint, unsigned int);
-__DEFINE_GUEST_HANDLE(ulong, unsigned long);
-DEFINE_GUEST_HANDLE(char);
-DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(long);
-DEFINE_GUEST_HANDLE(void);
+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int);
+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_XEN_GUEST_HANDLE(char);
+DEFINE_XEN_GUEST_HANDLE(int);
+DEFINE_XEN_GUEST_HANDLE(long);
+DEFINE_XEN_GUEST_HANDLE(void);
#endif

/*
@@ -102,7 +101,7 @@ typedef struct trap_info {
uint16_t cs; /* code selector */
unsigned long address; /* code offset */
} trap_info_t;
-DEFINE_GUEST_HANDLE(trap_info_t);
+DEFINE_XEN_GUEST_HANDLE(trap_info_t);

typedef struct cpu_user_regs {
uint32_t ebx;
@@ -126,7 +125,7 @@ typedef struct cpu_user_regs {
uint16_t fs, _pad4;
uint16_t gs, _pad5;
} cpu_user_regs_t;
-DEFINE_GUEST_HANDLE(cpu_user_regs_t);
+DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);

typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */

@@ -154,7 +153,7 @@ typedef struct vcpu_guest_context {
unsigned long failsafe_callback_eip;
unsigned long vm_assist; /* VMASST_TYPE_* bitmap */
} vcpu_guest_context_t;
-DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

typedef struct arch_shared_info {
unsigned long max_pfn; /* max pfn that appears in table */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/arch-x86_64.h Mon May 08 14:46:11 2006 -0600
@@ -9,26 +9,25 @@
#ifndef __XEN_PUBLIC_ARCH_X86_64_H__
#define __XEN_PUBLIC_ARCH_X86_64_H__

-#ifdef __XEN__
-#define __DEFINE_GUEST_HANDLE(name, type) \
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
typedef struct { type *p; } __guest_handle_ ## name
-#else
-#define __DEFINE_GUEST_HANDLE(name, type) \
- typedef type * __guest_handle_ ## name
-#endif
-
-#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
-#define GUEST_HANDLE(name) __guest_handle_ ## name
+
+#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
+#define XEN_GUEST_HANDLE(name) __guest_handle_ ## name
+#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
+#ifdef __XEN_TOOLS__
+#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
+#endif

#ifndef __ASSEMBLY__
/* Guest handles for primitive C types. */
-__DEFINE_GUEST_HANDLE(uchar, unsigned char);
-__DEFINE_GUEST_HANDLE(uint, unsigned int);
-__DEFINE_GUEST_HANDLE(ulong, unsigned long);
-DEFINE_GUEST_HANDLE(char);
-DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(long);
-DEFINE_GUEST_HANDLE(void);
+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int);
+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_XEN_GUEST_HANDLE(char);
+DEFINE_XEN_GUEST_HANDLE(int);
+DEFINE_XEN_GUEST_HANDLE(long);
+DEFINE_XEN_GUEST_HANDLE(void);
#endif

/*
@@ -157,7 +156,7 @@ typedef struct trap_info {
uint16_t cs; /* code selector */
unsigned long address; /* code offset */
} trap_info_t;
-DEFINE_GUEST_HANDLE(trap_info_t);
+DEFINE_XEN_GUEST_HANDLE(trap_info_t);

#ifdef __GNUC__
/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
@@ -197,7 +196,7 @@ typedef struct cpu_user_regs {
uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */
uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
} cpu_user_regs_t;
-DEFINE_GUEST_HANDLE(cpu_user_regs_t);
+DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);

#undef __DECL_REG

@@ -230,7 +229,7 @@ typedef struct vcpu_guest_context {
uint64_t gs_base_kernel;
uint64_t gs_base_user;
} vcpu_guest_context_t;
-DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

typedef struct arch_shared_info {
unsigned long max_pfn; /* max pfn that appears in table */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/callback.h
--- a/xen/include/public/callback.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/callback.h Mon May 08 14:46:11 2006 -0600
@@ -36,7 +36,7 @@ typedef struct callback_register {
int type;
xen_callback_t address;
} callback_register_t;
-DEFINE_GUEST_HANDLE(callback_register_t);
+DEFINE_XEN_GUEST_HANDLE(callback_register_t);

/*
* Unregister a callback.
@@ -48,7 +48,7 @@ typedef struct callback_unregister {
typedef struct callback_unregister {
int type;
} callback_unregister_t;
-DEFINE_GUEST_HANDLE(callback_unregister_t);
+DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);

#endif /* __XEN_PUBLIC_CALLBACK_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/dom0_ops.h Mon May 08 14:46:11 2006 -0600
@@ -28,21 +28,21 @@ typedef struct dom0_getmemlist {
/* IN variables. */
domid_t domain;
unsigned long max_pfns;
- GUEST_HANDLE(ulong) buffer;
+ XEN_GUEST_HANDLE(ulong) buffer;
/* OUT variables. */
unsigned long num_pfns;
} dom0_getmemlist_t;
-DEFINE_GUEST_HANDLE(dom0_getmemlist_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getmemlist_t);

#define DOM0_SCHEDCTL 6
/* struct sched_ctl_cmd is from sched-ctl.h */
typedef struct sched_ctl_cmd dom0_schedctl_t;
-DEFINE_GUEST_HANDLE(dom0_schedctl_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_schedctl_t);

#define DOM0_ADJUSTDOM 7
/* struct sched_adjdom_cmd is from sched-ctl.h */
typedef struct sched_adjdom_cmd dom0_adjustdom_t;
-DEFINE_GUEST_HANDLE(dom0_adjustdom_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_adjustdom_t);

#define DOM0_CREATEDOMAIN 8
typedef struct dom0_createdomain {
@@ -53,28 +53,28 @@ typedef struct dom0_createdomain {
/* Identifier for new domain (auto-allocate if zero is specified). */
domid_t domain;
} dom0_createdomain_t;
-DEFINE_GUEST_HANDLE(dom0_createdomain_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_createdomain_t);

#define DOM0_DESTROYDOMAIN 9
typedef struct dom0_destroydomain {
/* IN variables. */
domid_t domain;
} dom0_destroydomain_t;
-DEFINE_GUEST_HANDLE(dom0_destroydomain_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_destroydomain_t);

#define DOM0_PAUSEDOMAIN 10
typedef struct dom0_pausedomain {
/* IN parameters. */
domid_t domain;
} dom0_pausedomain_t;
-DEFINE_GUEST_HANDLE(dom0_pausedomain_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_pausedomain_t);

#define DOM0_UNPAUSEDOMAIN 11
typedef struct dom0_unpausedomain {
/* IN parameters. */
domid_t domain;
} dom0_unpausedomain_t;
-DEFINE_GUEST_HANDLE(dom0_unpausedomain_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_unpausedomain_t);

#define DOM0_GETDOMAININFO 12
typedef struct dom0_getdomaininfo {
@@ -100,7 +100,7 @@ typedef struct dom0_getdomaininfo {
uint32_t ssidref;
xen_domain_handle_t handle;
} dom0_getdomaininfo_t;
-DEFINE_GUEST_HANDLE(dom0_getdomaininfo_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfo_t);

#define DOM0_SETVCPUCONTEXT 13
typedef struct dom0_setvcpucontext {
@@ -108,9 +108,9 @@ typedef struct dom0_setvcpucontext {
domid_t domain;
uint32_t vcpu;
/* IN/OUT parameters */
- GUEST_HANDLE(vcpu_guest_context_t) ctxt;
+ XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt;
} dom0_setvcpucontext_t;
-DEFINE_GUEST_HANDLE(dom0_setvcpucontext_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_setvcpucontext_t);

#define DOM0_MSR 15
typedef struct dom0_msr {
@@ -124,7 +124,7 @@ typedef struct dom0_msr {
uint32_t out1;
uint32_t out2;
} dom0_msr_t;
-DEFINE_GUEST_HANDLE(dom0_msr_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_msr_t);

/*
* Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
@@ -137,7 +137,7 @@ typedef struct dom0_settime {
uint32_t nsecs;
uint64_t system_time;
} dom0_settime_t;
-DEFINE_GUEST_HANDLE(dom0_settime_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_settime_t);

#define DOM0_GETPAGEFRAMEINFO 18
#define LTAB_SHIFT 28
@@ -159,7 +159,7 @@ typedef struct dom0_getpageframeinfo {
/* Is the page PINNED to a type? */
uint32_t type; /* see above type defs */
} dom0_getpageframeinfo_t;
-DEFINE_GUEST_HANDLE(dom0_getpageframeinfo_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo_t);

/*
* Read console content from Xen buffer ring.
@@ -169,10 +169,10 @@ typedef struct dom0_readconsole {
/* IN variables. */
uint32_t clear; /* Non-zero -> clear after reading. */
/* IN/OUT variables. */
- GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
+ XEN_GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
uint32_t count; /* In: Buffer size; Out: Used buffer size */
} dom0_readconsole_t;
-DEFINE_GUEST_HANDLE(dom0_readconsole_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_readconsole_t);

/*
* Set which physical cpus a vcpu can execute on.
@@ -184,7 +184,7 @@ typedef struct dom0_setvcpuaffinity {
uint32_t vcpu;
cpumap_t cpumap;
} dom0_setvcpuaffinity_t;
-DEFINE_GUEST_HANDLE(dom0_setvcpuaffinity_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_setvcpuaffinity_t);

/* Get trace buffers machine base address */
#define DOM0_TBUFCONTROL 21
@@ -204,7 +204,7 @@ typedef struct dom0_tbufcontrol {
unsigned long buffer_mfn;
uint32_t size;
} dom0_tbufcontrol_t;
-DEFINE_GUEST_HANDLE(dom0_tbufcontrol_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_tbufcontrol_t);

/*
* Get physical information about the host machine
@@ -220,7 +220,7 @@ typedef struct dom0_physinfo {
unsigned long free_pages;
uint32_t hw_cap[8];
} dom0_physinfo_t;
-DEFINE_GUEST_HANDLE(dom0_physinfo_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_physinfo_t);

/*
* Get the ID of the current scheduler.
@@ -230,7 +230,7 @@ typedef struct dom0_sched_id {
/* OUT variable */
uint32_t sched_id;
} dom0_sched_id_t;
-DEFINE_GUEST_HANDLE(dom0_sched_id_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_sched_id_t);

/*
* Control shadow pagetables operation
@@ -252,19 +252,19 @@ typedef struct dom0_shadow_control_stats
uint32_t dirty_net_count;
uint32_t dirty_block_count;
} dom0_shadow_control_stats_t;
-DEFINE_GUEST_HANDLE(dom0_shadow_control_stats_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t);

typedef struct dom0_shadow_control {
/* IN variables. */
domid_t domain;
uint32_t op;
- GUEST_HANDLE(ulong) dirty_bitmap;
+ XEN_GUEST_HANDLE(ulong) dirty_bitmap;
/* IN/OUT variables. */
unsigned long pages; /* size of buffer, updated with actual size */
/* OUT variables. */
dom0_shadow_control_stats_t stats;
} dom0_shadow_control_t;
-DEFINE_GUEST_HANDLE(dom0_shadow_control_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_t);

#define DOM0_SETDOMAINMAXMEM 28
typedef struct dom0_setdomainmaxmem {
@@ -272,7 +272,7 @@ typedef struct dom0_setdomainmaxmem {
domid_t domain;
unsigned long max_memkb;
} dom0_setdomainmaxmem_t;
-DEFINE_GUEST_HANDLE(dom0_setdomainmaxmem_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_setdomainmaxmem_t);

#define DOM0_GETPAGEFRAMEINFO2 29 /* batched interface */
typedef struct dom0_getpageframeinfo2 {
@@ -280,9 +280,9 @@ typedef struct dom0_getpageframeinfo2 {
domid_t domain;
unsigned long num;
/* IN/OUT variables. */
- GUEST_HANDLE(ulong) array;
+ XEN_GUEST_HANDLE(ulong) array;
} dom0_getpageframeinfo2_t;
-DEFINE_GUEST_HANDLE(dom0_getpageframeinfo2_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo2_t);

/*
* Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
@@ -301,7 +301,7 @@ typedef struct dom0_add_memtype {
uint32_t handle;
uint32_t reg;
} dom0_add_memtype_t;
-DEFINE_GUEST_HANDLE(dom0_add_memtype_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_add_memtype_t);

/*
* Tear down an existing memory-range type. If @handle is remembered then it
@@ -316,7 +316,7 @@ typedef struct dom0_del_memtype {
uint32_t handle;
uint32_t reg;
} dom0_del_memtype_t;
-DEFINE_GUEST_HANDLE(dom0_del_memtype_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_del_memtype_t);

/* Read current type of an MTRR (x86-specific). */
#define DOM0_READ_MEMTYPE 33
@@ -328,7 +328,7 @@ typedef struct dom0_read_memtype {
unsigned long nr_mfns;
uint32_t type;
} dom0_read_memtype_t;
-DEFINE_GUEST_HANDLE(dom0_read_memtype_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_read_memtype_t);

/* Interface for controlling Xen software performance counters. */
#define DOM0_PERFCCONTROL 34
@@ -340,23 +340,23 @@ typedef struct dom0_perfc_desc {
uint32_t nr_vals; /* number of values for this counter */
uint32_t vals[64]; /* array of values */
} dom0_perfc_desc_t;
-DEFINE_GUEST_HANDLE(dom0_perfc_desc_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t);
typedef struct dom0_perfccontrol {
/* IN variables. */
uint32_t op; /* DOM0_PERFCCONTROL_OP_??? */
/* OUT variables. */
uint32_t nr_counters; /* number of counters */
- GUEST_HANDLE(dom0_perfc_desc_t) desc; /* counter information (or NULL) */
+ XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /* counter information (or NULL) */
} dom0_perfccontrol_t;
-DEFINE_GUEST_HANDLE(dom0_perfccontrol_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t);

#define DOM0_MICROCODE 35
typedef struct dom0_microcode {
/* IN variables. */
- GUEST_HANDLE(void) data; /* Pointer to microcode data */
+ XEN_GUEST_HANDLE(void) data; /* Pointer to microcode data */
uint32_t length; /* Length of microcode data. */
} dom0_microcode_t;
-DEFINE_GUEST_HANDLE(dom0_microcode_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_microcode_t);

#define DOM0_IOPORT_PERMISSION 36
typedef struct dom0_ioport_permission {
@@ -365,7 +365,7 @@ typedef struct dom0_ioport_permission {
uint32_t nr_ports; /* size of port range */
uint8_t allow_access; /* allow or deny access to range? */
} dom0_ioport_permission_t;
-DEFINE_GUEST_HANDLE(dom0_ioport_permission_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_ioport_permission_t);

#define DOM0_GETVCPUCONTEXT 37
typedef struct dom0_getvcpucontext {
@@ -373,9 +373,9 @@ typedef struct dom0_getvcpucontext {
domid_t domain; /* domain to be affected */
uint32_t vcpu; /* vcpu # */
/* OUT variables. */
- GUEST_HANDLE(vcpu_guest_context_t) ctxt;
+ XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt;
} dom0_getvcpucontext_t;
-DEFINE_GUEST_HANDLE(dom0_getvcpucontext_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getvcpucontext_t);

#define DOM0_GETVCPUINFO 43
typedef struct dom0_getvcpuinfo {
@@ -390,18 +390,18 @@ typedef struct dom0_getvcpuinfo {
uint32_t cpu; /* current mapping */
cpumap_t cpumap; /* allowable mapping */
} dom0_getvcpuinfo_t;
-DEFINE_GUEST_HANDLE(dom0_getvcpuinfo_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getvcpuinfo_t);

#define DOM0_GETDOMAININFOLIST 38
typedef struct dom0_getdomaininfolist {
/* IN variables. */
domid_t first_domain;
uint32_t max_domains;
- GUEST_HANDLE(dom0_getdomaininfo_t) buffer;
+ XEN_GUEST_HANDLE(dom0_getdomaininfo_t) buffer;
/* OUT variables. */
uint32_t num_domains;
} dom0_getdomaininfolist_t;
-DEFINE_GUEST_HANDLE(dom0_getdomaininfolist_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfolist_t);

#define DOM0_PLATFORM_QUIRK 39
#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */
@@ -411,7 +411,7 @@ typedef struct dom0_platform_quirk {
/* IN variables. */
uint32_t quirk_id;
} dom0_platform_quirk_t;
-DEFINE_GUEST_HANDLE(dom0_platform_quirk_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_platform_quirk_t);

#define DOM0_PHYSICAL_MEMORY_MAP 40
typedef struct dom0_memory_map_entry {
@@ -419,36 +419,36 @@ typedef struct dom0_memory_map_entry {
uint32_t flags; /* reserved */
uint8_t is_ram;
} dom0_memory_map_entry_t;
-DEFINE_GUEST_HANDLE(dom0_memory_map_entry_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_memory_map_entry_t);
typedef struct dom0_physical_memory_map {
/* IN variables. */
uint32_t max_map_entries;
/* OUT variables. */
uint32_t nr_map_entries;
- GUEST_HANDLE(dom0_memory_map_entry_t) memory_map;
+ XEN_GUEST_HANDLE(dom0_memory_map_entry_t) memory_map;
} dom0_physical_memory_map_t;
-DEFINE_GUEST_HANDLE(dom0_physical_memory_map_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_physical_memory_map_t);

#define DOM0_MAX_VCPUS 41
typedef struct dom0_max_vcpus {
domid_t domain; /* domain to be affected */
uint32_t max; /* maximum number of vcpus */
} dom0_max_vcpus_t;
-DEFINE_GUEST_HANDLE(dom0_max_vcpus_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_max_vcpus_t);

#define DOM0_SETDOMAINHANDLE 44
typedef struct dom0_setdomainhandle {
domid_t domain;
xen_domain_handle_t handle;
} dom0_setdomainhandle_t;
-DEFINE_GUEST_HANDLE(dom0_setdomainhandle_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_setdomainhandle_t);

#define DOM0_SETDEBUGGING 45
typedef struct dom0_setdebugging {
domid_t domain;
uint8_t enable;
} dom0_setdebugging_t;
-DEFINE_GUEST_HANDLE(dom0_setdebugging_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_setdebugging_t);

#define DOM0_IRQ_PERMISSION 46
typedef struct dom0_irq_permission {
@@ -456,7 +456,7 @@ typedef struct dom0_irq_permission {
uint8_t pirq;
uint8_t allow_access; /* flag to specify enable/disable of IRQ access */
} dom0_irq_permission_t;
-DEFINE_GUEST_HANDLE(dom0_irq_permission_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_irq_permission_t);

#define DOM0_IOMEM_PERMISSION 47
typedef struct dom0_iomem_permission {
@@ -465,14 +465,14 @@ typedef struct dom0_iomem_permission {
unsigned long nr_mfns; /* number of pages in range (>0) */
uint8_t allow_access; /* allow (!0) or deny (0) access to range? */
} dom0_iomem_permission_t;
-DEFINE_GUEST_HANDLE(dom0_iomem_permission_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_iomem_permission_t);

#define DOM0_HYPERCALL_INIT 48
typedef struct dom0_hypercall_init {
domid_t domain; /* domain to be affected */
unsigned long mfn; /* machine frame to be initialised */
} dom0_hypercall_init_t;
-DEFINE_GUEST_HANDLE(dom0_hypercall_init_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_hypercall_init_t);

typedef struct dom0_op {
uint32_t cmd;
@@ -518,7 +518,7 @@ typedef struct dom0_op {
uint8_t pad[128];
} u;
} dom0_op_t;
-DEFINE_GUEST_HANDLE(dom0_op_t);
+DEFINE_XEN_GUEST_HANDLE(dom0_op_t);

#endif /* __XEN_PUBLIC_DOM0_OPS_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/event_channel.h Mon May 08 14:46:11 2006 -0600
@@ -9,8 +9,15 @@
#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
#define __XEN_PUBLIC_EVENT_CHANNEL_H__

+/*
+ * Prototype for this hypercall is:
+ * int event_channel_op(int cmd, void *args)
+ * @cmd == EVTCHNOP_??? (event-channel operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
typedef uint32_t evtchn_port_t;
-DEFINE_GUEST_HANDLE(evtchn_port_t);
+DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);

/*
* EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
@@ -181,6 +188,10 @@ typedef struct evtchn_unmask {
evtchn_port_t port;
} evtchn_unmask_t;

+/*
+ * Argument to event_channel_op_compat() hypercall. Superceded by new
+ * event_channel_op() hypercall since 0x00030202.
+ */
typedef struct evtchn_op {
uint32_t cmd; /* EVTCHNOP_* */
union {
@@ -196,7 +207,7 @@ typedef struct evtchn_op {
evtchn_unmask_t unmask;
} u;
} evtchn_op_t;
-DEFINE_GUEST_HANDLE(evtchn_op_t);
+DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);

#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/grant_table.h Mon May 08 14:46:11 2006 -0600
@@ -167,7 +167,7 @@ typedef struct gnttab_map_grant_ref {
grant_handle_t handle;
uint64_t dev_bus_addr;
} gnttab_map_grant_ref_t;
-DEFINE_GUEST_HANDLE(gnttab_map_grant_ref_t);
+DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);

/*
* GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
@@ -189,7 +189,7 @@ typedef struct gnttab_unmap_grant_ref {
/* OUT parameters. */
int16_t status; /* GNTST_* */
} gnttab_unmap_grant_ref_t;
-DEFINE_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
+DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);

/*
* GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least
@@ -207,9 +207,9 @@ typedef struct gnttab_setup_table {
uint32_t nr_frames;
/* OUT parameters. */
int16_t status; /* GNTST_* */
- GUEST_HANDLE(ulong) frame_list;
+ XEN_GUEST_HANDLE(ulong) frame_list;
} gnttab_setup_table_t;
-DEFINE_GUEST_HANDLE(gnttab_setup_table_t);
+DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t);

/*
* GNTTABOP_dump_table: Dump the contents of the grant table to the
@@ -222,7 +222,7 @@ typedef struct gnttab_dump_table {
/* OUT parameters. */
int16_t status; /* GNTST_* */
} gnttab_dump_table_t;
-DEFINE_GUEST_HANDLE(gnttab_dump_table_t);
+DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);

/*
* GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
@@ -241,7 +241,7 @@ typedef struct gnttab_transfer {
/* OUT parameters. */
int16_t status;
} gnttab_transfer_t;
-DEFINE_GUEST_HANDLE(gnttab_transfer_t);
+DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);

/*
* Bitfield values for update_pin_status.flags.
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/memory.h
--- a/xen/include/public/memory.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/memory.h Mon May 08 14:46:11 2006 -0600
@@ -29,7 +29,7 @@ typedef struct xen_memory_reservation {
* OUT: GMFN bases of extents that were allocated
* (NB. This command also updates the mach_to_phys translation table)
*/
- GUEST_HANDLE(ulong) extent_start;
+ XEN_GUEST_HANDLE(ulong) extent_start;

/* Number of extents, and size/alignment of each (2^extent_order pages). */
unsigned long nr_extents;
@@ -50,7 +50,7 @@ typedef struct xen_memory_reservation {
domid_t domid;

} xen_memory_reservation_t;
-DEFINE_GUEST_HANDLE(xen_memory_reservation_t);
+DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);

/*
* Returns the maximum machine frame number of mapped RAM in this system.
@@ -86,7 +86,7 @@ typedef struct xen_machphys_mfn_list {
* any large discontiguities in the machine address space, 2MB gaps in
* the machphys table will be represented by an MFN base of zero.
*/
- GUEST_HANDLE(ulong) extent_start;
+ XEN_GUEST_HANDLE(ulong) extent_start;

/*
* Number of extents written to the above array. This will be smaller
@@ -94,7 +94,7 @@ typedef struct xen_machphys_mfn_list {
*/
unsigned int nr_extents;
} xen_machphys_mfn_list_t;
-DEFINE_GUEST_HANDLE(xen_machphys_mfn_list_t);
+DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);

/*
* Sets the GPFN at which a particular page appears in the specified guest's
@@ -117,7 +117,7 @@ typedef struct xen_add_to_physmap {
/* GPFN where the source mapping page should appear. */
unsigned long gpfn;
} xen_add_to_physmap_t;
-DEFINE_GUEST_HANDLE(xen_add_to_physmap_t);
+DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);

/*
* Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
@@ -132,15 +132,15 @@ typedef struct xen_translate_gpfn_list {
unsigned long nr_gpfns;

/* List of GPFNs to translate. */
- GUEST_HANDLE(ulong) gpfn_list;
+ XEN_GUEST_HANDLE(ulong) gpfn_list;

/*
* Output list to contain MFN translations. May be the same as the input
* list (in which case each input GPFN is overwritten with the output MFN).
*/
- GUEST_HANDLE(ulong) mfn_list;
+ XEN_GUEST_HANDLE(ulong) mfn_list;
} xen_translate_gpfn_list_t;
-DEFINE_GUEST_HANDLE(xen_translate_gpfn_list_t);
+DEFINE_XEN_GUEST_HANDLE(xen_translate_gpfn_list_t);

#endif /* __XEN_PUBLIC_MEMORY_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/nmi.h
--- a/xen/include/public/nmi.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/nmi.h Mon May 08 14:46:11 2006 -0600
@@ -38,7 +38,7 @@ typedef struct xennmi_callback {
unsigned long handler_address;
unsigned long pad;
} xennmi_callback_t;
-DEFINE_GUEST_HANDLE(xennmi_callback_t);
+DEFINE_XEN_GUEST_HANDLE(xennmi_callback_t);

/*
* Deregister NMI callback for this (calling) VCPU.
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/physdev.h Mon May 08 14:46:11 2006 -0600
@@ -2,61 +2,127 @@
#ifndef __XEN_PUBLIC_PHYSDEV_H__
#define __XEN_PUBLIC_PHYSDEV_H__

-/* Commands to HYPERVISOR_physdev_op() */
-#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
-#define PHYSDEVOP_IRQ_STATUS_QUERY 5
-#define PHYSDEVOP_SET_IOPL 6
-#define PHYSDEVOP_SET_IOBITMAP 7
-#define PHYSDEVOP_APIC_READ 8
-#define PHYSDEVOP_APIC_WRITE 9
-#define PHYSDEVOP_ASSIGN_VECTOR 10
+/*
+ * Prototype for this hypercall is:
+ * int physdev_op(int cmd, void *args)
+ * @cmd == PHYSDEVOP_??? (physdev operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */

-typedef struct physdevop_irq_status_query {
+/*
+ * Notify end-of-interrupt (EOI) for the specified IRQ.
+ * @arg == pointer to physdev_eoi structure.
+ */
+#define PHYSDEVOP_eoi 12
+typedef struct physdev_eoi {
+ /* IN */
+ uint32_t irq;
+} physdev_eoi_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
+
+/*
+ * Query the status of an IRQ line.
+ * @arg == pointer to physdev_irq_status_query structure.
+ */
+#define PHYSDEVOP_irq_status_query 5
+typedef struct physdev_irq_status_query {
/* IN */
uint32_t irq;
/* OUT */
-/* Need to call PHYSDEVOP_IRQ_UNMASK_NOTIFY when the IRQ has been serviced? */
-#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY (1<<0)
- uint32_t flags;
-} physdevop_irq_status_query_t;
+ uint32_t flags; /* XENIRQSTAT_* */
+} physdev_irq_status_query_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);

-typedef struct physdevop_set_iopl {
+/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
+#define _XENIRQSTAT_needs_eoi (0)
+#define XENIRQSTAT_needs_eoi (1<<_XENIRQSTAT_needs_eoi)
+
+/*
+ * Set the current VCPU's I/O privilege level.
+ * @arg == pointer to physdev_set_iopl structure.
+ */
+#define PHYSDEVOP_set_iopl 6
+typedef struct physdev_set_iopl {
/* IN */
uint32_t iopl;
-} physdevop_set_iopl_t;
+} physdev_set_iopl_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);

-typedef struct physdevop_set_iobitmap {
+/*
+ * Set the current VCPU's I/O-port permissions bitmap.
+ * @arg == pointer to physdev_set_iobitmap structure.
+ */
+#define PHYSDEVOP_set_iobitmap 7
+typedef struct physdev_set_iobitmap {
/* IN */
uint8_t *bitmap;
uint32_t nr_ports;
-} physdevop_set_iobitmap_t;
+} physdev_set_iobitmap_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);

-typedef struct physdevop_apic {
+/*
+ * Read or write an IO-APIC register.
+ * @arg == pointer to physdev_apic structure.
+ */
+#define PHYSDEVOP_apic_read 8
+#define PHYSDEVOP_apic_write 9
+typedef struct physdev_apic {
/* IN */
unsigned long apic_physbase;
uint32_t reg;
/* IN or OUT */
uint32_t value;
-} physdevop_apic_t;
+} physdev_apic_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);

-typedef struct physdevop_irq {
+/*
+ * Allocate or free a physical upcall vector for the specified IRQ line.
+ * @arg == pointer to physdev_irq structure.
+ */
+#define PHYSDEVOP_alloc_irq_vector 10
+#define PHYSDEVOP_free_irq_vector 11
+typedef struct physdev_irq {
/* IN */
uint32_t irq;
- /* OUT */
+ /* IN or OUT */
uint32_t vector;
-} physdevop_irq_t;
+} physdev_irq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);

+/*
+ * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
+ * hypercall since 0x00030202.
+ */
typedef struct physdev_op {
uint32_t cmd;
union {
- physdevop_irq_status_query_t irq_status_query;
- physdevop_set_iopl_t set_iopl;
- physdevop_set_iobitmap_t set_iobitmap;
- physdevop_apic_t apic_op;
- physdevop_irq_t irq_op;
+ physdev_irq_status_query_t irq_status_query;
+ physdev_set_iopl_t set_iopl;
+ physdev_set_iobitmap_t set_iobitmap;
+ physdev_apic_t apic_op;
+ physdev_irq_t irq_op;
} u;
} physdev_op_t;
-DEFINE_GUEST_HANDLE(physdev_op_t);
+DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
+
+/*
+ * Notify that some PIRQ-bound event channels have been unmasked.
+ * ** This command is obsolete since interface version 0x00030202 and is **
+ * ** unsupported by newer versions of Xen. **
+ */
+#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
+
+/*
+ * These all-capitals physdev operation names are superceded by the new names
+ * (defined above) since interface version 0x00030202.
+ */
+#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
+#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
+#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
+#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
+#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
+#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
+#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi

#endif /* __XEN_PUBLIC_PHYSDEV_H__ */

diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/sched.h
--- a/xen/include/public/sched.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/sched.h Mon May 08 14:46:11 2006 -0600
@@ -49,7 +49,7 @@ typedef struct sched_shutdown {
typedef struct sched_shutdown {
unsigned int reason; /* SHUTDOWN_* */
} sched_shutdown_t;
-DEFINE_GUEST_HANDLE(sched_shutdown_t);
+DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);

/*
* Poll a set of event-channel ports. Return when one or more are pending. An
@@ -58,11 +58,11 @@ DEFINE_GUEST_HANDLE(sched_shutdown_t);
*/
#define SCHEDOP_poll 3
typedef struct sched_poll {
- GUEST_HANDLE(evtchn_port_t) ports;
+ XEN_GUEST_HANDLE(evtchn_port_t) ports;
unsigned int nr_ports;
uint64_t timeout;
} sched_poll_t;
-DEFINE_GUEST_HANDLE(sched_poll_t);
+DEFINE_XEN_GUEST_HANDLE(sched_poll_t);

/*
* Declare a shutdown for another domain. The main use of this function is
@@ -75,7 +75,7 @@ typedef struct sched_remote_shutdown {
domid_t domain_id; /* Remote domain ID */
unsigned int reason; /* SHUTDOWN_xxx reason */
} sched_remote_shutdown_t;
-DEFINE_GUEST_HANDLE(sched_remote_shutdown_t);
+DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);

/*
* Reason codes for SCHEDOP_shutdown. These may be interpreted by control
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/xen-compat.h
--- a/xen/include/public/xen-compat.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/xen-compat.h Mon May 08 14:46:11 2006 -0600
@@ -9,9 +9,9 @@
#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
#define __XEN_PUBLIC_XEN_COMPAT_H__

-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030101
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030202

-#if defined(__XEN__)
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
/* Xen is built with matching headers and implements the latest interface. */
#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__
#elif !defined(__XEN_INTERFACE_VERSION__)
@@ -23,9 +23,25 @@
#error "These header files do not support the requested interface version."
#endif

+/* New sched_op hypercall introduced in 0x00030101. */
#if __XEN_INTERFACE_VERSION__ < 0x00030101
#undef __HYPERVISOR_sched_op
#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
#endif

+/* Structural guest handles introduced in 0x00030201. */
+#if __XEN_INTERFACE_VERSION__ < 0x00030201
+#undef __DEFINE_XEN_GUEST_HANDLE
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
+ typedef type * __guest_handle_ ## name
+#endif
+
+/* New event-channel and physdev hypercalls introduced in 0x00030202. */
+#if __XEN_INTERFACE_VERSION__ < 0x00030202
+#undef __HYPERVISOR_event_channel_op
+#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
+#undef __HYPERVISOR_physdev_op
+#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
+#endif
+
#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/xen.h
--- a/xen/include/public/xen.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/xen.h Mon May 08 14:46:11 2006 -0600
@@ -37,7 +37,7 @@
#define __HYPERVISOR_stack_switch 3
#define __HYPERVISOR_set_callbacks 4
#define __HYPERVISOR_fpu_taskswitch 5
-#define __HYPERVISOR_sched_op_compat 6 /* compat as of 0x00030101 */
+#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */
#define __HYPERVISOR_dom0_op 7
#define __HYPERVISOR_set_debugreg 8
#define __HYPERVISOR_get_debugreg 9
@@ -46,10 +46,10 @@
#define __HYPERVISOR_multicall 13
#define __HYPERVISOR_update_va_mapping 14
#define __HYPERVISOR_set_timer_op 15
-#define __HYPERVISOR_event_channel_op 16
+#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
#define __HYPERVISOR_xen_version 17
#define __HYPERVISOR_console_io 18
-#define __HYPERVISOR_physdev_op 19
+#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */
#define __HYPERVISOR_grant_table_op 20
#define __HYPERVISOR_vm_assist 21
#define __HYPERVISOR_update_va_mapping_otherdomain 22
@@ -62,6 +62,18 @@
#define __HYPERVISOR_sched_op 29
#define __HYPERVISOR_callback_op 30
#define __HYPERVISOR_xenoprof_op 31
+#define __HYPERVISOR_event_channel_op 32
+#define __HYPERVISOR_physdev_op 33
+
+/* Architecture-specific hypercall definitions. */
+#define __HYPERVISOR_arch_0 48
+#define __HYPERVISOR_arch_1 49
+#define __HYPERVISOR_arch_2 50
+#define __HYPERVISOR_arch_3 51
+#define __HYPERVISOR_arch_4 52
+#define __HYPERVISOR_arch_5 53
+#define __HYPERVISOR_arch_6 54
+#define __HYPERVISOR_arch_7 55

/*
* VIRTUAL INTERRUPTS
@@ -80,7 +92,18 @@
#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */
#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */
#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
-#define NR_VIRQS 8
+
+/* Architecture-specific VIRQ definitions. */
+#define VIRQ_ARCH_0 16
+#define VIRQ_ARCH_1 17
+#define VIRQ_ARCH_2 18
+#define VIRQ_ARCH_3 19
+#define VIRQ_ARCH_4 20
+#define VIRQ_ARCH_5 21
+#define VIRQ_ARCH_6 22
+#define VIRQ_ARCH_7 23
+
+#define NR_VIRQS 24

/*
* MMU-UPDATE REQUESTS
@@ -185,7 +208,7 @@ typedef struct mmuext_op {
void *vcpumask;
} arg2;
} mmuext_op_t;
-DEFINE_GUEST_HANDLE(mmuext_op_t);
+DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
#endif

/* These are passed as 'flags' to update_va_mapping. They can be ORed. */
@@ -252,7 +275,7 @@ typedef struct mmu_update {
uint64_t ptr; /* Machine address of PTE. */
uint64_t val; /* New contents of PTE. */
} mmu_update_t;
-DEFINE_GUEST_HANDLE(mmu_update_t);
+DEFINE_XEN_GUEST_HANDLE(mmu_update_t);

/*
* Send an array of these to HYPERVISOR_multicall().
@@ -262,7 +285,7 @@ typedef struct multicall_entry {
unsigned long op, result;
unsigned long args[6];
} multicall_entry_t;
-DEFINE_GUEST_HANDLE(multicall_entry_t);
+DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);

/*
* Event channel endpoints per domain:
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/public/xenoprof.h Mon May 08 14:46:11 2006 -0600
@@ -52,7 +52,7 @@ typedef struct xenoprof_buf {
uint64_t lost_samples;
struct event_log event_log[1];
} xenoprof_buf_t;
-DEFINE_GUEST_HANDLE(xenoprof_buf_t);
+DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);

typedef struct xenoprof_init {
int32_t max_samples;
@@ -63,7 +63,7 @@ typedef struct xenoprof_init {
uint64_t buf_maddr;
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
} xenoprof_init_t;
-DEFINE_GUEST_HANDLE(xenoprof_init_t);
+DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);

typedef struct xenoprof_counter {
uint32_t ind;
@@ -75,7 +75,7 @@ typedef struct xenoprof_counter {
uint32_t user;
uint64_t unit_mask;
} xenoprof_counter_t;
-DEFINE_GUEST_HANDLE(xenoprof_counter_t);
+DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);


#endif /* __XEN_PUBLIC_XENOPROF_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/compiler.h
--- a/xen/include/xen/compiler.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/compiler.h Mon May 08 14:46:11 2006 -0600
@@ -1,17 +1,21 @@
#ifndef __LINUX_COMPILER_H
#define __LINUX_COMPILER_H

-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
- a mechanism by which the user can annotate likely branch directions and
- expect the blocks to be reordered appropriately. Define __builtin_expect
- to nothing for earlier compilers. */
-
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
+#if !defined(__GNUC__) || (__GNUC__ < 3)
+#error Sorry, your compiler is too old/not recognized.
#endif

-#define likely(x) __builtin_expect((x),1)
-#define unlikely(x) __builtin_expect((x),0)
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+#define likely(x) __builtin_expect((x),1)
+#define unlikely(x) __builtin_expect((x),0)
+
+#define inline __inline__
+#define always_inline __inline__ __attribute__ ((always_inline))
+#define noinline __attribute__((noinline))
+
+#define __attribute_pure__ __attribute__((pure))
+#define __attribute_const__ __attribute__((__const__))

#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
#define __attribute_used__ __attribute__((__used__))
@@ -23,6 +27,12 @@
#define __must_check __attribute__((warn_unused_result))
#else
#define __must_check
+#endif
+
+#if __GNUC__ > 3
+#define offsetof(a,b) __builtin_offsetof(a,b)
+#else
+#define offsetof(a,b) ((unsigned long)&(((a *)0)->b))
#endif

/* This macro obfuscates arithmetic on a variable address so that gcc
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/config.h
--- a/xen/include/xen/config.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/config.h Mon May 08 14:46:11 2006 -0600
@@ -10,10 +10,7 @@
#include <asm/config.h>

#define EXPORT_SYMBOL(var)
-#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define always_inline __inline__ __attribute__ ((always_inline))

/* Linux syslog levels. */
#define KERN_NOTICE ""
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/console.h
--- a/xen/include/xen/console.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/console.h Mon May 08 14:46:11 2006 -0600
@@ -14,7 +14,7 @@ extern spinlock_t console_lock;

void set_printk_prefix(const char *prefix);

-long read_console_ring(GUEST_HANDLE(char), u32 *, int);
+long read_console_ring(XEN_GUEST_HANDLE(char), u32 *, int);

void init_console(void);
void console_endboot(int disable_vga);
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/hypercall.h Mon May 08 14:46:11 2006 -0600
@@ -9,6 +9,7 @@
#include <xen/types.h>
#include <xen/time.h>
#include <public/xen.h>
+#include <public/dom0_ops.h>
#include <public/acm_ops.h>
#include <public/event_channel.h>
#include <asm/hypercall.h>
@@ -25,20 +26,20 @@ extern long
extern long
do_sched_op(
int cmd,
- GUEST_HANDLE(void) arg);
+ XEN_GUEST_HANDLE(void) arg);

extern long
do_dom0_op(
- GUEST_HANDLE(dom0_op_t) u_dom0_op);
+ XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op);

extern long
do_memory_op(
int cmd,
- GUEST_HANDLE(void) arg);
+ XEN_GUEST_HANDLE(void) arg);

extern long
do_multicall(
- GUEST_HANDLE(multicall_entry_t) call_list,
+ XEN_GUEST_HANDLE(multicall_entry_t) call_list,
unsigned int nr_calls);

extern long
@@ -47,23 +48,23 @@ do_set_timer_op(

extern long
do_event_channel_op(
- GUEST_HANDLE(evtchn_op_t) uop);
+ int cmd, XEN_GUEST_HANDLE(void) arg);

extern long
do_xen_version(
int cmd,
- GUEST_HANDLE(void) arg);
+ XEN_GUEST_HANDLE(void) arg);

extern long
do_console_io(
int cmd,
int count,
- GUEST_HANDLE(char) buffer);
+ XEN_GUEST_HANDLE(char) buffer);

extern long
do_grant_table_op(
unsigned int cmd,
- GUEST_HANDLE(void) uop,
+ XEN_GUEST_HANDLE(void) uop,
unsigned int count);

extern long
@@ -75,15 +76,15 @@ do_vcpu_op(
do_vcpu_op(
int cmd,
int vcpuid,
- GUEST_HANDLE(void) arg);
+ XEN_GUEST_HANDLE(void) arg);

extern long
do_acm_op(
- GUEST_HANDLE(acm_op_t) u_acm_op);
+ XEN_GUEST_HANDLE(acm_op_t) u_acm_op);

extern long
do_nmi_op(
unsigned int cmd,
- GUEST_HANDLE(void) arg);
+ XEN_GUEST_HANDLE(void) arg);

#endif /* __XEN_HYPERCALL_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/irq.h
--- a/xen/include/xen/irq.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/irq.h Mon May 08 14:46:11 2006 -0600
@@ -68,8 +68,9 @@ extern void no_action(int cpl, void *dev

struct domain;
struct vcpu;
-extern int pirq_guest_unmask(struct domain *p);
-extern int pirq_guest_bind(struct vcpu *p, int irq, int will_share);
-extern int pirq_guest_unbind(struct domain *p, int irq);
+extern int pirq_guest_eoi(struct domain *d, int irq);
+extern int pirq_guest_unmask(struct domain *d);
+extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share);
+extern int pirq_guest_unbind(struct domain *d, int irq);

#endif /* __XEN_IRQ_H__ */
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/lib.h Mon May 08 14:46:11 2006 -0600
@@ -15,6 +15,9 @@
} while ( 0 )

#define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
+
+/* Force a compilation error if condition is true */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))

#ifndef NDEBUG
#define ASSERT(_p) { if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__); BUG(); } }
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon May 08 13:41:18 2006 -0600
+++ b/xen/include/xen/sched.h Mon May 08 14:46:11 2006 -0600
@@ -15,6 +15,7 @@
#include <xen/rangeset.h>
#include <asm/domain.h>
#include <xen/xenoprof.h>
+#include <xen/irq.h>

extern unsigned long volatile jiffies;
extern rwlock_t domlist_lock;
@@ -132,9 +133,8 @@ struct domain
* domain's event-channel spinlock. Read accesses can also synchronise on
* the lock, but races don't usually matter.
*/
-#define NR_PIRQS 256 /* Put this somewhere sane! */
- u16 pirq_to_evtchn[NR_PIRQS];
- DECLARE_BITMAP(pirq_mask, NR_PIRQS);
+ u16 pirq_to_evtchn[NR_IRQS];
+ DECLARE_BITMAP(pirq_mask, NR_IRQS);

/* I/O capabilities (access to IRQs and memory-mapped I/O). */
struct rangeset *iomem_caps;
@@ -316,7 +316,7 @@ void startup_cpu_idle_loop(void);
* It contains one character per argument as follows:
* 'i' [unsigned] {char, int}
* 'l' [unsigned] long
- * 'h' guest handle (GUEST_HANDLE(foo))
+ * 'h' guest handle (XEN_GUEST_HANDLE(foo))
*/
unsigned long hypercall_create_continuation(
unsigned int op, const char *format, ...);
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Authors:
+ * Stefan Berger <stefanb@us.ibm.com>
+ *
+ * Generic device driver part for device drivers in a virtualized
+ * environment.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include "tpm.h"
+#include "tpm_vtpm.h"
+
+/* read status bits */
+enum {
+ STATUS_BUSY = 0x01,
+ STATUS_DATA_AVAIL = 0x02,
+ STATUS_READY = 0x04
+};
+
+#define MIN(x,y) ((x) < (y)) ? (x) : (y)
+
+struct transmission {
+ struct list_head next;
+
+ unsigned char *request;
+ size_t request_len;
+ size_t request_buflen;
+
+ unsigned char *response;
+ size_t response_len;
+ size_t response_buflen;
+
+ unsigned int flags;
+};
+
+enum {
+ TRANSMISSION_FLAG_WAS_QUEUED = 0x1
+};
+
+struct vtpm_state {
+ struct transmission *current_request;
+ spinlock_t req_list_lock;
+ wait_queue_head_t req_wait_queue;
+
+ struct list_head queued_requests;
+
+ struct transmission *current_response;
+ spinlock_t resp_list_lock;
+ wait_queue_head_t resp_wait_queue; // processes waiting for responses
+
+ struct transmission *req_cancelled; // if a cancellation was encounterd
+
+ u8 vd_status;
+ u8 flags;
+
+ unsigned long disconnect_time;
+
+ struct tpm_virtual_device *tpmvd;
+};
+
+enum {
+ DATAEX_FLAG_QUEUED_ONLY = 0x1
+};
+
+
+/* local variables */
+static struct vtpm_state *vtpms;
+
+/* local function prototypes */
+static int _vtpm_send_queued(struct tpm_chip *chip);
+
+
+/* =============================================================
+ * Some utility functions
+ * =============================================================
+ */
+static void vtpm_state_init(struct vtpm_state *vtpms)
+{
+ vtpms->current_request = NULL;
+ spin_lock_init(&vtpms->req_list_lock);
+ init_waitqueue_head(&vtpms->req_wait_queue);
+ INIT_LIST_HEAD(&vtpms->queued_requests);
+
+ vtpms->current_response = NULL;
+ spin_lock_init(&vtpms->resp_list_lock);
+ init_waitqueue_head(&vtpms->resp_wait_queue);
+
+ vtpms->disconnect_time = jiffies;
+}
+
+
+static inline struct transmission *transmission_alloc(void)
+{
+ return kzalloc(sizeof(struct transmission), GFP_ATOMIC);
+}
+
+static unsigned char *
+transmission_set_req_buffer(struct transmission *t,
+ unsigned char *buffer, size_t len)
+{
+ if (t->request_buflen < len) {
+ kfree(t->request);
+ t->request = kmalloc(len, GFP_KERNEL);
+ if (!t->request) {
+ t->request_buflen = 0;
+ return NULL;
+ }
+ t->request_buflen = len;
+ }
+
+ memcpy(t->request, buffer, len);
+ t->request_len = len;
+
+ return t->request;
+}
+
+static unsigned char *
+transmission_set_res_buffer(struct transmission *t,
+ const unsigned char *buffer, size_t len)
+{
+ if (t->response_buflen < len) {
+ kfree(t->response);
+ t->response = kmalloc(len, GFP_ATOMIC);
+ if (!t->response) {
+ t->response_buflen = 0;
+ return NULL;
+ }
+ t->response_buflen = len;
+ }
+
+ memcpy(t->response, buffer, len);
+ t->response_len = len;
+
+ return t->response;
+}
+
+static inline void transmission_free(struct transmission *t)
+{
+ kfree(t->request);
+ kfree(t->response);
+ kfree(t);
+}
+
+/* =============================================================
+ * Interface with the lower layer driver
+ * =============================================================
+ */
+/*
+ * Lower layer uses this function to make a response available.
+ */
+int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
+{
+ unsigned long flags;
+ int ret_size = 0;
+ struct transmission *t;
+
+ /*
+ * The list with requests must contain one request
+ * only and the element there must be the one that
+ * was passed to me from the front-end.
+ */
+ spin_lock_irqsave(&vtpms->resp_list_lock, flags);
+ if (vtpms->current_request != ptr) {
+ printk("WARNING: The request pointer is different than the "
+ "pointer the shared memory driver returned to me. "
+ "%p != %p\n",
+ vtpms->current_request, ptr);
+ }
+
+ /*
+ * If the request has been cancelled, just quit here
+ */
+ if (vtpms->req_cancelled == (struct transmission *)ptr) {
+ if (vtpms->current_request == vtpms->req_cancelled) {
+ vtpms->current_request = NULL;
+ }
+ transmission_free(vtpms->req_cancelled);
+ vtpms->req_cancelled = NULL;
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ return 0;
+ }
+
+ if (NULL != (t = vtpms->current_request)) {
+ transmission_free(t);
+ vtpms->current_request = NULL;
+ }
+
+ t = transmission_alloc();
+ if (t) {
+ if (!transmission_set_res_buffer(t, buffer, count)) {
+ transmission_free(t);
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ return -ENOMEM;
+ }
+ ret_size = count;
+ vtpms->current_response = t;
+ wake_up_interruptible(&vtpms->resp_wait_queue);
+ }
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+
+ return ret_size;
+}
+
+
+/*
+ * Lower layer indicates its status (connected/disconnected)
+ */
+void vtpm_vd_status(u8 vd_status)
+{
+ vtpms->vd_status = vd_status;
+ if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
+ vtpms->disconnect_time = jiffies;
+ }
+}
+
+/* =============================================================
+ * Interface with the generic TPM driver
+ * =============================================================
+ */
+static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ int rc = 0;
+ unsigned long flags;
+
+ /*
+ * Check if the previous operation only queued the command
+ * In this case there won't be a response, so I just
+ * return from here and reset that flag. In any other
+ * case I should receive a response from the back-end.
+ */
+ spin_lock_irqsave(&vtpms->resp_list_lock, flags);
+ if ((vtpms->flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
+ vtpms->flags &= ~DATAEX_FLAG_QUEUED_ONLY;
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ /*
+ * The first few commands (measurements) must be
+ * queued since it might not be possible to talk to the
+ * TPM, yet.
+ * Return a response of up to 30 '0's.
+ */
+
+ count = MIN(count, 30);
+ memset(buf, 0x0, count);
+ return count;
+ }
+ /*
+ * Check whether something is in the responselist and if
+ * there's nothing in the list wait for something to appear.
+ */
+
+ if (!vtpms->current_response) {
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ interruptible_sleep_on_timeout(&vtpms->resp_wait_queue,
+ 1000);
+ spin_lock_irqsave(&vtpms->resp_list_lock ,flags);
+ }
+
+ if (vtpms->current_response) {
+ struct transmission *t = vtpms->current_response;
+ vtpms->current_response = NULL;
+ rc = MIN(count, t->response_len);
+ memcpy(buf, t->response, rc);
+ transmission_free(t);
+ }
+
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ return rc;
+}
+
+static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ int rc = 0;
+ unsigned long flags;
+ struct transmission *t = transmission_alloc();
+
+ if (!t)
+ return -ENOMEM;
+ /*
+ * If there's a current request, it must be the
+ * previous request that has timed out.
+ */
+ spin_lock_irqsave(&vtpms->req_list_lock, flags);
+ if (vtpms->current_request != NULL) {
+ printk("WARNING: Sending although there is a request outstanding.\n"
+ " Previous request must have timed out.\n");
+ transmission_free(vtpms->current_request);
+ vtpms->current_request = NULL;
+ }
+ spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
+
+ /*
+ * Queue the packet if the driver below is not
+ * ready, yet, or there is any packet already
+ * in the queue.
+ * If the driver below is ready, unqueue all
+ * packets first before sending our current
+ * packet.
+ * For each unqueued packet, except for the
+ * last (=current) packet, call the function
+ * tpm_xen_recv to wait for the response to come
+ * back.
+ */
+ if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
+ if (time_after(jiffies,
+ vtpms->disconnect_time + HZ * 10)) {
+ rc = -ENOENT;
+ } else {
+ goto queue_it;
+ }
+ } else {
+ /*
+ * Send all queued packets.
+ */
+ if (_vtpm_send_queued(chip) == 0) {
+
+ vtpms->current_request = t;
+
+ rc = vtpm_vd_send(chip,
+ vtpms->tpmvd->tpm_private,
+ buf,
+ count,
+ t);
+ /*
+ * The generic TPM driver will call
+ * the function to receive the response.
+ */
+ if (rc < 0) {
+ vtpms->current_request = NULL;
+ goto queue_it;
+ }
+ } else {
+queue_it:
+ if (!transmission_set_req_buffer(t, buf, count)) {
+ transmission_free(t);
+ rc = -ENOMEM;
+ goto exit;
+ }
+ /*
+ * An error occurred. Don't event try
+ * to send the current request. Just
+ * queue it.
+ */
+ spin_lock_irqsave(&vtpms->req_list_lock, flags);
+ vtpms->flags |= DATAEX_FLAG_QUEUED_ONLY;
+ list_add_tail(&t->next, &vtpms->queued_requests);
+ spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
+ }
+ }
+
+exit:
+ return rc;
+}
+
+
+/*
+ * Send all queued requests.
+ */
+static int _vtpm_send_queued(struct tpm_chip *chip)
+{
+ int rc;
+ int error = 0;
+ long flags;
+ unsigned char buffer[1];
+
+ spin_lock_irqsave(&vtpms->req_list_lock, flags);
+
+ while (!list_empty(&vtpms->queued_requests)) {
+ /*
+ * Need to dequeue them.
+ * Read the result into a dummy buffer.
+ */
+ struct transmission *qt = (struct transmission *)
+ vtpms->queued_requests.next;
+ list_del(&qt->next);
+ vtpms->current_request = qt;
+ spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
+
+ rc = vtpm_vd_send(chip,
+ vtpms->tpmvd->tpm_private,
+ qt->request,
+ qt->request_len,
+ qt);
+
+ if (rc < 0) {
+ spin_lock_irqsave(&vtpms->req_list_lock, flags);
+ if ((qt = vtpms->current_request) != NULL) {
+ /*
+ * requeue it at the beginning
+ * of the list
+ */
+ list_add(&qt->next,
+ &vtpms->queued_requests);
+ }
+ vtpms->current_request = NULL;
+ error = 1;
+ break;
+ }
+ /*
+ * After this point qt is not valid anymore!
+ * It is freed when the front-end is delivering
+ * the data by calling tpm_recv
+ */
+ /*
+ * Receive response into provided dummy buffer
+ */
+ rc = vtpm_recv(chip, buffer, sizeof(buffer));
+ spin_lock_irqsave(&vtpms->req_list_lock, flags);
+ }
+
+ spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
+
+ return error;
+}
+
+static void vtpm_cancel(struct tpm_chip *chip)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&vtpms->resp_list_lock,flags);
+
+ vtpms->req_cancelled = vtpms->current_request;
+
+ spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
+}
+
+static u8 vtpm_status(struct tpm_chip *chip)
+{
+ u8 rc = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vtpms->resp_list_lock, flags);
+ /*
+ * Data are available if:
+ * - there's a current response
+ * - the last packet was queued only (this is fake, but necessary to
+ * get the generic TPM layer to call the receive function.)
+ */
+ if (vtpms->current_response ||
+ 0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
+ rc = STATUS_DATA_AVAIL;
+ }
+ spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+ return rc;
+}
+
+static struct file_operations vtpm_ops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = tpm_open,
+ .read = tpm_read,
+ .write = tpm_write,
+ .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute *vtpm_attrs[] = {
+ &dev_attr_pubek.attr,
+ &dev_attr_pcrs.attr,
+ &dev_attr_caps.attr,
+ &dev_attr_cancel.attr,
+ NULL,
+};
+
+static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
+
+static struct tpm_vendor_specific tpm_vtpm = {
+ .recv = vtpm_recv,
+ .send = vtpm_send,
+ .cancel = vtpm_cancel,
+ .status = vtpm_status,
+ .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
+ .req_complete_val = STATUS_DATA_AVAIL,
+ .req_canceled = STATUS_READY,
+ .base = 0,
+ .attr_group = &vtpm_attr_grp,
+ .miscdev = {
+ .fops = &vtpm_ops,
+ },
+};
+
+static struct platform_device *pdev;
+
+int __init init_vtpm(struct tpm_virtual_device *tvd)
+{
+ int rc;
+
+ /* vtpms is global - only allow one user */
+ if (vtpms)
+ return -EBUSY;
+
+ vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
+ if (!vtpms)
+ return -ENOMEM;
+
+ vtpm_state_init(vtpms);
+ vtpms->tpmvd = tvd;
+
+ pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ rc = PTR_ERR(pdev);
+ goto err_free_mem;
+ }
+
+ if (tvd)
+ tpm_vtpm.buffersize = tvd->max_tx_size;
+
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
+ goto err_unreg_pdev;
+ }
+
+ return 0;
+
+err_unreg_pdev:
+ platform_device_unregister(pdev);
+err_free_mem:
+ kfree(vtpms);
+ vtpms = NULL;
+
+ return rc;
+}
+
+void __exit cleanup_vtpm(void)
+{
+ struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+ if (chip) {
+ tpm_remove_hardware(chip->dev);
+ platform_device_unregister(pdev);
+ }
+ kfree(vtpms);
+ vtpms = NULL;
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,38 @@
+#ifndef TPM_VTPM_H
+#define TPM_VTPM_H
+
+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;
+ /*
+ * The following is a private structure of the underlying
+ * driver. It is passed as parameter in the send function.
+ */
+ struct tpm_private *tpm_private;
+};
+
+enum vdev_status {
+ TPM_VD_STATUS_DISCONNECTED = 0x0,
+ TPM_VD_STATUS_CONNECTED = 0x1
+};
+
+/* this function is called from tpm_vtpm.c */
+int vtpm_vd_send(struct tpm_chip *tc,
+ struct tpm_private * tp,
+ const u8 * buf, size_t count, void *ptr);
+
+/* these functions are offered by tpm_vtpm.c */
+int __init init_vtpm(struct tpm_virtual_device *);
+void __exit cleanup_vtpm(void);
+int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
+void vtpm_vd_status(u8 status);
+
+#endif
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,71 @@
+/*
+ * PCI Backend - Handles the virtual fields found on the capability lists
+ * in the configuration space.
+ *
+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include "pciback.h"
+#include "conf_space.h"
+#include "conf_space_capability.h"
+
+static LIST_HEAD(capabilities);
+
+static struct config_field caplist_header[] = {
+ {
+ .offset = PCI_CAP_LIST_ID,
+ .size = 2, /* encompass PCI_CAP_LIST_ID & PCI_CAP_LIST_NEXT */
+ .u.w.read = pciback_read_config_word,
+ .u.w.write = NULL,
+ },
+ {
+ .size = 0,
+ },
+};
+
+static inline void register_capability(struct pciback_config_capability *cap)
+{
+ list_add_tail(&cap->cap_list, &capabilities);
+}
+
+int pciback_config_capability_add_fields(struct pci_dev *dev)
+{
+ int err = 0;
+ struct pciback_config_capability *cap;
+ int cap_offset;
+
+ list_for_each_entry(cap, &capabilities, cap_list) {
+ cap_offset = pci_find_capability(dev, cap->capability);
+ if (cap_offset) {
+ dev_dbg(&dev->dev, "Found capability 0x%x at 0x%x\n",
+ cap->capability, cap_offset);
+
+ err = pciback_config_add_fields_offset(dev,
+ caplist_header,
+ cap_offset);
+ if (err)
+ goto out;
+ err = pciback_config_add_fields_offset(dev,
+ cap->fields,
+ cap_offset);
+ if (err)
+ goto out;
+ }
+ }
+
+ out:
+ return err;
+}
+
+extern struct pciback_config_capability pciback_config_capability_vpd;
+extern struct pciback_config_capability pciback_config_capability_pm;
+
+int pciback_config_capability_init(void)
+{
+ register_capability(&pciback_config_capability_vpd);
+ register_capability(&pciback_config_capability_pm);
+
+ return 0;
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.h Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,23 @@
+/*
+ * PCI Backend - Data structures for special overlays for structures on
+ * the capability list.
+ *
+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
+ */
+
+#ifndef __PCIBACK_CONFIG_CAPABILITY_H__
+#define __PCIBACK_CONFIG_CAPABILITY_H__
+
+#include <linux/pci.h>
+#include <linux/list.h>
+
+struct pciback_config_capability {
+ struct list_head cap_list;
+
+ int capability;
+
+ /* If the device has the capability found above, add these fields */
+ struct config_field *fields;
+};
+
+#endif
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,113 @@
+/*
+ * PCI Backend - Configuration space overlay for power management
+ *
+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
+ */
+
+#include <linux/pci.h>
+#include "conf_space.h"
+#include "conf_space_capability.h"
+
+static int pm_caps_read(struct pci_dev *dev, int offset, u16 *value,
+ void *data)
+{
+ int err;
+ u16 real_value;
+
+ err = pci_read_config_word(dev, offset, &real_value);
+ if (err)
+ goto out;
+
+ *value = real_value & ~PCI_PM_CAP_PME_MASK;
+
+ out:
+ return err;
+}
+
+/* PM_OK_BITS specifies the bits that the driver domain is allowed to change.
+ * Can't allow driver domain to enable PMEs - they're shared */
+#define PM_OK_BITS (PCI_PM_CTRL_PME_STATUS|PCI_PM_CTRL_DATA_SEL_MASK)
+
+static int pm_ctrl_write(struct pci_dev *dev, int offset, u16 new_value,
+ void *data)
+{
+ int err;
+ u16 cur_value;
+ pci_power_t new_state;
+
+ /* Handle setting power state separately */
+ new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
+
+ err = pci_read_config_word(dev, offset, &cur_value);
+ if (err)
+ goto out;
+
+ new_value &= PM_OK_BITS;
+ if ((cur_value & PM_OK_BITS) != new_value) {
+ new_value = (cur_value & ~PM_OK_BITS) | new_value;
+ err = pci_write_config_word(dev, offset, new_value);
+ if (err)
+ goto out;
+ }
+
+ /* Let pci core handle the power management change */
+ dev_dbg(&dev->dev, "set power state to %x\n", new_state);
+ err = pci_set_power_state(dev, new_state);
+ if (err)
+ err = PCIBIOS_SET_FAILED;
+
+ out:
+ return err;
+}
+
+/* Ensure PMEs are disabled */
+static void *pm_ctrl_init(struct pci_dev *dev, int offset)
+{
+ int err;
+ u16 value;
+
+ err = pci_read_config_word(dev, offset, &value);
+ if (err)
+ goto out;
+
+ if (value & PCI_PM_CTRL_PME_ENABLE) {
+ value &= ~PCI_PM_CTRL_PME_ENABLE;
+ err = pci_write_config_word(dev, offset, value);
+ }
+
+ out:
+ return ERR_PTR(err);
+}
+
+static struct config_field caplist_pm[] = {
+ {
+ .offset = PCI_PM_PMC,
+ .size = 2,
+ .u.w.read = pm_caps_read,
+ },
+ {
+ .offset = PCI_PM_CTRL,
+ .size = 2,
+ .init = pm_ctrl_init,
+ .u.w.read = pciback_read_config_word,
+ .u.w.write = pm_ctrl_write,
+ },
+ {
+ .offset = PCI_PM_PPB_EXTENSIONS,
+ .size = 1,
+ .u.b.read = pciback_read_config_byte,
+ },
+ {
+ .offset = PCI_PM_DATA_REGISTER,
+ .size = 1,
+ .u.b.read = pciback_read_config_byte,
+ },
+ {
+ .size = 0,
+ },
+};
+
+struct pciback_config_capability pciback_config_capability_pm = {
+ .capability = PCI_CAP_ID_PM,
+ .fields = caplist_pm,
+};
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_vpd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_vpd.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,42 @@
+/*
+ * PCI Backend - Configuration space overlay for Vital Product Data
+ *
+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
+ */
+
+#include <linux/pci.h>
+#include "conf_space.h"
+#include "conf_space_capability.h"
+
+static int vpd_address_write(struct pci_dev *dev, int offset, u16 value,
+ void *data)
+{
+ /* Disallow writes to the vital product data */
+ if (value & PCI_VPD_ADDR_F)
+ return PCIBIOS_SET_FAILED;
+ else
+ return pci_write_config_word(dev, offset, value);
+}
+
+static struct config_field caplist_vpd[] = {
+ {
+ .offset = PCI_VPD_ADDR,
+ .size = 2,
+ .u.w.read = pciback_read_config_word,
+ .u.w.write = vpd_address_write,
+ },
+ {
+ .offset = PCI_VPD_DATA,
+ .size = 4,
+ .u.dw.read = pciback_read_config_dword,
+ .u.dw.write = NULL,
+ },
+ {
+ .size = 0,
+ },
+};
+
+struct pciback_config_capability pciback_config_capability_vpd = {
+ .capability = PCI_CAP_ID_VPD,
+ .fields = caplist_vpd,
+};
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/device_bind.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/device_bind.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,15 @@
+diff -pruN ../pristine-linux-2.6.16.13/drivers/base/bus.c ./drivers/base/bus.c
+--- ../pristine-linux-2.6.16.13/drivers/base/bus.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/base/bus.c 2006-05-04 17:41:30.000000000 +0100
+@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
+ up(&dev->sem);
+ if (dev->parent)
+ up(&dev->parent->sem);
++
++ if (err > 0) /* success */
++ err = count;
++ else if (err == 0) /* driver didn't accept device */
++ err = -ENODEV;
+ }
+ put_device(dev);
+ put_bus(bus);
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,45 @@
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/traps.c 2006-05-04 17:41:34.000000000 +0100
+@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
+
+ static void io_check_error(unsigned char reason, struct pt_regs * regs)
+ {
+- unsigned long i;
+-
+ printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
+ show_registers(regs);
+
+ /* Re-enable the IOCK line, wait for a few seconds */
+- reason = (reason & 0xf) | 8;
+- outb(reason, 0x61);
+- i = 2000;
+- while (--i) udelay(1000);
+- reason &= ~8;
+- outb(reason, 0x61);
++ clear_io_check_error(reason);
+ }
+
+ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/mach-default/mach_traps.h 2006-05-04 17:41:34.000000000 +0100
+@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
+ outb(reason, 0x61);
+ }
+
++static inline void clear_io_check_error(unsigned char reason)
++{
++ unsigned long i;
++
++ reason = (reason & 0xf) | 8;
++ outb(reason, 0x61);
++ i = 2000;
++ while (--i) udelay(1000);
++ reason &= ~8;
++ outb(reason, 0x61);
++}
++
+ static inline unsigned char get_nmi_reason(void)
+ {
+ return inb(0x61);
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/net-csum.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/net-csum.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,64 @@
+diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
+--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-02 22:38:44.000000000 +0100
++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-04 17:41:37.000000000 +0100
+@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
+ if (hdrsize < sizeof(*hdr))
+ return 1;
+
+- hdr->check = ip_nat_cheat_check(~oldip, newip,
++ if ((*pskb)->proto_csum_blank) {
++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
++ } else {
++ hdr->check = ip_nat_cheat_check(~oldip, newip,
+ ip_nat_cheat_check(oldport ^ 0xFFFF,
+ newport,
+ hdr->check));
++ }
+ return 1;
+ }
+
+diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
+--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-02 22:38:44.000000000 +0100
++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-04 17:41:37.000000000 +0100
+@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
+ newport = tuple->dst.u.udp.port;
+ portptr = &hdr->dest;
+ }
+- if (hdr->check) /* 0 is a special case meaning no checksum */
+- hdr->check = ip_nat_cheat_check(~oldip, newip,
++ if (hdr->check) { /* 0 is a special case meaning no checksum */
++ if ((*pskb)->proto_csum_blank) {
++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
++ } else {
++ hdr->check = ip_nat_cheat_check(~oldip, newip,
+ ip_nat_cheat_check(*portptr ^ 0xFFFF,
+ newport,
+ hdr->check));
++ }
++ }
+ *portptr = newport;
+ return 1;
+ }
+diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
+--- ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c 2006-05-02 22:38:44.000000000 +0100
++++ ./net/ipv4/xfrm4_output.c 2006-05-04 17:41:37.000000000 +0100
+@@ -17,6 +17,8 @@
+ #include <net/xfrm.h>
+ #include <net/icmp.h>
+
++extern int skb_checksum_setup(struct sk_buff *skb);
++
+ /* Add encapsulation header.
+ *
+ * In transport mode, the IP header will be moved forward to make space
+@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
+ struct xfrm_state *x = dst->xfrm;
+ int err;
+
++ err = skb_checksum_setup(skb);
++ if (err)
++ goto error_nolock;
++
+ if (skb->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(skb, 0);
+ if (err)
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/pmd-shared.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/pmd-shared.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,111 @@
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
+--- ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/mm/pageattr.c 2006-05-04 17:41:40.000000000 +0100
+@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
+ unsigned long flags;
+
+ set_pte_atomic(kpte, pte); /* change init_mm */
+- if (PTRS_PER_PMD > 1)
++ if (HAVE_SHARED_KERNEL_PMD)
+ return;
+
+ spin_lock_irqsave(&pgd_lock, flags);
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
+--- ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/mm/pgtable.c 2006-05-04 17:41:40.000000000 +0100
+@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
+ spin_lock_irqsave(&pgd_lock, flags);
+ }
+
+- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
+- swapper_pg_dir + USER_PTRS_PER_PGD,
+- KERNEL_PGD_PTRS);
++ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
++ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
++ swapper_pg_dir + USER_PTRS_PER_PGD,
++ KERNEL_PGD_PTRS);
+ if (PTRS_PER_PMD > 1)
+ return;
+
+@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+ goto out_oom;
+ set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
+ }
++
++ if (!HAVE_SHARED_KERNEL_PMD) {
++ unsigned long flags;
++
++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++ if (!pmd)
++ goto out_oom;
++ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
++ }
++
++ spin_lock_irqsave(&pgd_lock, flags);
++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++ unsigned long v = (unsigned long)i << PGDIR_SHIFT;
++ pgd_t *kpgd = pgd_offset_k(v);
++ pud_t *kpud = pud_offset(kpgd, v);
++ pmd_t *kpmd = pmd_offset(kpud, v);
++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
++ memcpy(pmd, kpmd, PAGE_SIZE);
++ }
++ pgd_list_add(pgd);
++ spin_unlock_irqrestore(&pgd_lock, flags);
++ }
++
+ return pgd;
+
+ out_oom:
+@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
+ int i;
+
+ /* in the PAE case user pgd entries are overwritten before usage */
+- if (PTRS_PER_PMD > 1)
+- for (i = 0; i < USER_PTRS_PER_PGD; ++i)
+- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
++ if (PTRS_PER_PMD > 1) {
++ for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
++ kmem_cache_free(pmd_cache, pmd);
++ }
++ if (!HAVE_SHARED_KERNEL_PMD) {
++ unsigned long flags;
++ spin_lock_irqsave(&pgd_lock, flags);
++ pgd_list_del(pgd);
++ spin_unlock_irqrestore(&pgd_lock, flags);
++ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
++ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
++ kmem_cache_free(pmd_cache, pmd);
++ }
++ }
++ }
+ /* in the non-PAE case, free_pgtables() clears user pgd entries */
+ kmem_cache_free(pgd_cache, pgd);
+ }
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/pgtable-2level-defs.h 2006-05-04 17:41:40.000000000 +0100
+@@ -1,6 +1,8 @@
+ #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
+ #define _I386_PGTABLE_2LEVEL_DEFS_H
+
++#define HAVE_SHARED_KERNEL_PMD 0
++
+ /*
+ * traditional i386 two-level paging structure:
+ */
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/pgtable-3level-defs.h 2006-05-04 17:41:40.000000000 +0100
+@@ -1,6 +1,8 @@
+ #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
+ #define _I386_PGTABLE_3LEVEL_DEFS_H
+
++#define HAVE_SHARED_KERNEL_PMD 1
++
+ /*
+ * PGDIR_SHIFT determines what a top-level page table entry can map
+ */
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,30 @@
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/entry.S 2006-05-04 17:41:44.000000000 +0100
+@@ -177,7 +177,7 @@ need_resched:
+
+ # sysenter call handler stub
+ ENTRY(sysenter_entry)
+- movl TSS_sysenter_esp0(%esp),%esp
++ movl SYSENTER_stack_esp0(%esp),%esp
+ sysenter_past_esp:
+ sti
+ pushl $(__USER_DS)
+@@ -492,7 +492,7 @@ device_not_available_emulate:
+ * that sets up the real kernel stack. Check here, since we can't
+ * allow the wrong stack to be used.
+ *
+- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
++ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
+ * already pushed 3 words if it hits on the sysenter instruction:
+ * eflags, cs and eip.
+ *
+@@ -504,7 +504,7 @@ device_not_available_emulate:
+ cmpw $__KERNEL_CS,4(%esp); \
+ jne ok; \
+ label: \
+- movl TSS_sysenter_esp0+offset(%esp),%esp; \
++ movl SYSENTER_stack_esp0+offset(%esp),%esp; \
+ pushfl; \
+ pushl $__KERNEL_CS; \
+ pushl $sysenter_past_esp
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/smp-alts.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/smp-alts.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,591 @@
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/Kconfig ./arch/i386/Kconfig
+--- ../pristine-linux-2.6.16.13/arch/i386/Kconfig 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/Kconfig 2006-05-04 17:41:45.000000000 +0100
+@@ -202,6 +202,19 @@ config SMP
+
+ If you don't know what to do here, say N.
+
++config SMP_ALTERNATIVES
++ bool "SMP alternatives support (EXPERIMENTAL)"
++ depends on SMP && EXPERIMENTAL
++ help
++ Try to reduce the overhead of running an SMP kernel on a uniprocessor
++ host slightly by replacing certain key instruction sequences
++ according to whether we currently have more than one CPU available.
++ This should provide a noticeable boost to performance when
++ running SMP kernels on UP machines, and have negligible impact
++ when running on an true SMP host.
++
++ If unsure, say N.
++
+ config NR_CPUS
+ int "Maximum number of CPUs (2-255)"
+ range 2 255
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/Makefile 2006-05-04 17:41:45.000000000 +0100
+@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o
+ obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
+ obj-$(CONFIG_VM86) += vm86.o
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
++obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o
+
+ EXTRA_AFLAGS := -traditional
+
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100
++++ ./arch/i386/kernel/smpalts.c 2006-05-04 17:41:45.000000000 +0100
+@@ -0,0 +1,85 @@
++#include <linux/kernel.h>
++#include <asm/system.h>
++#include <asm/smp_alt.h>
++#include <asm/processor.h>
++#include <asm/string.h>
++
++struct smp_replacement_record {
++ unsigned char targ_size;
++ unsigned char smp1_size;
++ unsigned char smp2_size;
++ unsigned char up_size;
++ unsigned char feature;
++ unsigned char data[0];
++};
++
++struct smp_alternative_record {
++ void *targ_start;
++ struct smp_replacement_record *repl;
++};
++
++extern struct smp_alternative_record __start_smp_alternatives_table,
++ __stop_smp_alternatives_table;
++extern unsigned long __init_begin, __init_end;
++
++void prepare_for_smp(void)
++{
++ struct smp_alternative_record *r;
++ printk(KERN_INFO "Enabling SMP...\n");
++ for (r = &__start_smp_alternatives_table;
++ r != &__stop_smp_alternatives_table;
++ r++) {
++ BUG_ON(r->repl->targ_size < r->repl->smp1_size);
++ BUG_ON(r->repl->targ_size < r->repl->smp2_size);
++ BUG_ON(r->repl->targ_size < r->repl->up_size);
++ if (system_state == SYSTEM_RUNNING &&
++ r->targ_start >= (void *)&__init_begin &&
++ r->targ_start < (void *)&__init_end)
++ continue;
++ if (r->repl->feature != (unsigned char)-1 &&
++ boot_cpu_has(r->repl->feature)) {
++ memcpy(r->targ_start,
++ r->repl->data + r->repl->smp1_size,
++ r->repl->smp2_size);
++ memset(r->targ_start + r->repl->smp2_size,
++ 0x90,
++ r->repl->targ_size - r->repl->smp2_size);
++ } else {
++ memcpy(r->targ_start,
++ r->repl->data,
++ r->repl->smp1_size);
++ memset(r->targ_start + r->repl->smp1_size,
++ 0x90,
++ r->repl->targ_size - r->repl->smp1_size);
++ }
++ }
++ /* Paranoia */
++ asm volatile ("jmp 1f\n1:");
++ mb();
++}
++
++void unprepare_for_smp(void)
++{
++ struct smp_alternative_record *r;
++ printk(KERN_INFO "Disabling SMP...\n");
++ for (r = &__start_smp_alternatives_table;
++ r != &__stop_smp_alternatives_table;
++ r++) {
++ BUG_ON(r->repl->targ_size < r->repl->smp1_size);
++ BUG_ON(r->repl->targ_size < r->repl->smp2_size);
++ BUG_ON(r->repl->targ_size < r->repl->up_size);
++ if (system_state == SYSTEM_RUNNING &&
++ r->targ_start >= (void *)&__init_begin &&
++ r->targ_start < (void *)&__init_end)
++ continue;
++ memcpy(r->targ_start,
++ r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
++ r->repl->up_size);
++ memset(r->targ_start + r->repl->up_size,
++ 0x90,
++ r->repl->targ_size - r->repl->up_size);
++ }
++ /* Paranoia */
++ asm volatile ("jmp 1f\n1:");
++ mb();
++}
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/smpboot.c 2006-05-04 17:41:45.000000000 +0100
+@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
+ if (max_cpus <= cpucount+1)
+ continue;
+
++#ifdef CONFIG_SMP_ALTERNATIVES
++ if (kicked == 1)
++ prepare_for_smp();
++#endif
++
+ if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
+ printk("CPU #%d not responding - cannot use it.\n",
+ apicid);
+@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
+ return -EIO;
+ }
+
++#ifdef CONFIG_SMP_ALTERNATIVES
++ if (num_online_cpus() == 1)
++ prepare_for_smp();
++#endif
++
+ local_irq_enable();
+ per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+ /* Unleash the CPU! */
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/vmlinux.lds.S 2006-05-04 17:41:45.000000000 +0100
+@@ -34,6 +34,13 @@ SECTIONS
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
+ __stop___ex_table = .;
+
++ . = ALIGN(16);
++ __start_smp_alternatives_table = .;
++ __smp_alternatives : { *(__smp_alternatives) }
++ __stop_smp_alternatives_table = .;
++
++ __smp_replacements : { *(__smp_replacements) }
++
+ RODATA
+
+ /* writeable */
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/atomic.h 2006-05-04 17:41:45.000000000 +0100
+@@ -4,18 +4,13 @@
+ #include <linux/config.h>
+ #include <linux/compiler.h>
+ #include <asm/processor.h>
++#include <asm/smp_alt.h>
+
+ /*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+-#ifdef CONFIG_SMP
+-#define LOCK "lock ; "
+-#else
+-#define LOCK ""
+-#endif
+-
+ /*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/bitops.h 2006-05-04 17:41:45.000000000 +0100
+@@ -7,6 +7,7 @@
+
+ #include <linux/config.h>
+ #include <linux/compiler.h>
++#include <asm/smp_alt.h>
+
+ /*
+ * These have to be done with inline assembly: that way the bit-setting
+@@ -16,12 +17,6 @@
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+-#ifdef CONFIG_SMP
+-#define LOCK_PREFIX "lock ; "
+-#else
+-#define LOCK_PREFIX ""
+-#endif
+-
+ #define ADDR (*(volatile long *) addr)
+
+ /**
+@@ -41,7 +36,7 @@
+ */
+ static inline void set_bit(int nr, volatile unsigned long * addr)
+ {
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btsl %1,%0"
+ :"+m" (ADDR)
+ :"Ir" (nr));
+@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
+ */
+ static inline void clear_bit(int nr, volatile unsigned long * addr)
+ {
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btrl %1,%0"
+ :"+m" (ADDR)
+ :"Ir" (nr));
+@@ -121,7 +116,7 @@ static inline void __change_bit(int nr,
+ */
+ static inline void change_bit(int nr, volatile unsigned long * addr)
+ {
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btcl %1,%0"
+ :"+m" (ADDR)
+ :"Ir" (nr));
+@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
+ {
+ int oldbit;
+
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btsl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"+m" (ADDR)
+ :"Ir" (nr) : "memory");
+@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
+ {
+ int oldbit;
+
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btrl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"+m" (ADDR)
+ :"Ir" (nr) : "memory");
+@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
+ {
+ int oldbit;
+
+- __asm__ __volatile__( LOCK_PREFIX
++ __asm__ __volatile__( LOCK
+ "btcl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"+m" (ADDR)
+ :"Ir" (nr) : "memory");
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/futex.h ./include/asm-i386/futex.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/futex.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/futex.h 2006-05-04 17:41:45.000000000 +0100
+@@ -28,7 +28,7 @@
+ "1: movl %2, %0\n\
+ movl %0, %3\n" \
+ insn "\n" \
+-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
++"2: " LOCK "cmpxchgl %3, %2\n\
+ jnz 1b\n\
+ 3: .section .fixup,\"ax\"\n\
+ 4: mov %5, %1\n\
+@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op,
+ #endif
+ switch (op) {
+ case FUTEX_OP_ADD:
+- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
++ __futex_atomic_op1(LOCK "xaddl %0, %2", ret,
+ oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/rwsem.h 2006-05-04 17:41:45.000000000 +0100
+@@ -40,6 +40,7 @@
+
+ #include <linux/list.h>
+ #include <linux/spinlock.h>
++#include <asm/smp_alt.h>
+
+ struct rwsem_waiter;
+
+@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
+ {
+ __asm__ __volatile__(
+ "# beginning down_read\n\t"
+-LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */
++LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */
+ " js 2f\n\t" /* jump if we weren't granted the lock */
+ "1:\n\t"
+ LOCK_SECTION_START("")
+@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
+ " movl %1,%2\n\t"
+ " addl %3,%2\n\t"
+ " jle 2f\n\t"
+-LOCK_PREFIX " cmpxchgl %2,%0\n\t"
++LOCK " cmpxchgl %2,%0\n\t"
+ " jnz 1b\n\t"
+ "2:\n\t"
+ "# ending __down_read_trylock\n\t"
+@@ -150,7 +151,7 @@ static inline void __down_write(struct r
+ tmp = RWSEM_ACTIVE_WRITE_BIAS;
+ __asm__ __volatile__(
+ "# beginning down_write\n\t"
+-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
++LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
+ " testl %%edx,%%edx\n\t" /* was the count 0 before? */
+ " jnz 2f\n\t" /* jump if we weren't granted the lock */
+ "1:\n\t"
+@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
+ __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
+ __asm__ __volatile__(
+ "# beginning __up_read\n\t"
+-LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
++LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
+ " js 2f\n\t" /* jump if the lock is being waited upon */
+ "1:\n\t"
+ LOCK_SECTION_START("")
+@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
+ __asm__ __volatile__(
+ "# beginning __up_write\n\t"
+ " movl %2,%%edx\n\t"
+-LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
++LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
+ " jnz 2f\n\t" /* jump if the lock is being waited upon */
+ "1:\n\t"
+ LOCK_SECTION_START("")
+@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
+ {
+ __asm__ __volatile__(
+ "# beginning __downgrade_write\n\t"
+-LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
++LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
+ " js 2f\n\t" /* jump if the lock is being waited upon */
+ "1:\n\t"
+ LOCK_SECTION_START("")
+@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t"
+ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+ {
+ __asm__ __volatile__(
+-LOCK_PREFIX "addl %1,%0"
++LOCK "addl %1,%0"
+ : "=m"(sem->count)
+ : "ir"(delta), "m"(sem->count));
+ }
+@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
+ int tmp = delta;
+
+ __asm__ __volatile__(
+-LOCK_PREFIX "xadd %0,(%2)"
++LOCK "xadd %0,(%2)"
+ : "+r"(tmp), "=m"(sem->count)
+ : "r"(sem), "m"(sem->count)
+ : "memory");
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100
++++ ./include/asm-i386/smp_alt.h 2006-05-04 17:41:45.000000000 +0100
+@@ -0,0 +1,32 @@
++#ifndef __ASM_SMP_ALT_H__
++#define __ASM_SMP_ALT_H__
++
++#include <linux/config.h>
++
++#ifdef CONFIG_SMP
++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
++#define LOCK \
++ "6677: nop\n" \
++ ".section __smp_alternatives,\"a\"\n" \
++ ".long 6677b\n" \
++ ".long 6678f\n" \
++ ".previous\n" \
++ ".section __smp_replacements,\"a\"\n" \
++ "6678: .byte 1\n" \
++ ".byte 1\n" \
++ ".byte 0\n" \
++ ".byte 1\n" \
++ ".byte -1\n" \
++ "lock\n" \
++ "nop\n" \
++ ".previous\n"
++void prepare_for_smp(void);
++void unprepare_for_smp(void);
++#else
++#define LOCK "lock ; "
++#endif
++#else
++#define LOCK ""
++#endif
++
++#endif /* __ASM_SMP_ALT_H__ */
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/spinlock.h 2006-05-04 17:41:45.000000000 +0100
+@@ -6,6 +6,7 @@
+ #include <asm/page.h>
+ #include <linux/config.h>
+ #include <linux/compiler.h>
++#include <asm/smp_alt.h>
+
+ /*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+@@ -23,7 +24,8 @@
+
+ #define __raw_spin_lock_string \
+ "\n1:\t" \
+- "lock ; decb %0\n\t" \
++ LOCK \
++ "decb %0\n\t" \
+ "jns 3f\n" \
+ "2:\t" \
+ "rep;nop\n\t" \
+@@ -34,7 +36,8 @@
+
+ #define __raw_spin_lock_string_flags \
+ "\n1:\t" \
+- "lock ; decb %0\n\t" \
++ LOCK \
++ "decb %0\n\t" \
+ "jns 4f\n\t" \
+ "2:\t" \
+ "testl $0x200, %1\n\t" \
+@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
+ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+ {
+ char oldval;
++#ifdef CONFIG_SMP_ALTERNATIVES
+ __asm__ __volatile__(
+- "xchgb %b0,%1"
++ "1:movb %1,%b0\n"
++ "movb $0,%1\n"
++ "2:"
++ ".section __smp_alternatives,\"a\"\n"
++ ".long 1b\n"
++ ".long 3f\n"
++ ".previous\n"
++ ".section __smp_replacements,\"a\"\n"
++ "3: .byte 2b - 1b\n"
++ ".byte 5f-4f\n"
++ ".byte 0\n"
++ ".byte 6f-5f\n"
++ ".byte -1\n"
++ "4: xchgb %b0,%1\n"
++ "5: movb %1,%b0\n"
++ "movb $0,%1\n"
++ "6:\n"
++ ".previous\n"
+ :"=q" (oldval), "=m" (lock->slock)
+ :"0" (0) : "memory");
++#else
++ __asm__ __volatile__(
++ "xchgb %b0,%1\n"
++ :"=q" (oldval), "=m" (lock->slock)
++ :"0" (0) : "memory");
++#endif
+ return oldval > 0;
+ }
+
+@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
+
+ static inline void __raw_read_unlock(raw_rwlock_t *rw)
+ {
+- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
++ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
+ }
+
+ static inline void __raw_write_unlock(raw_rwlock_t *rw)
+ {
+- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
++ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
+ : "=m" (rw->lock) : : "memory");
+ }
+
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/system.h ./include/asm-i386/system.h
+--- ../pristine-linux-2.6.16.13/include/asm-i386/system.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-i386/system.h 2006-05-04 17:41:45.000000000 +0100
+@@ -5,7 +5,7 @@
+ #include <linux/kernel.h>
+ #include <asm/segment.h>
+ #include <asm/cpufeature.h>
+-#include <linux/bitops.h> /* for LOCK_PREFIX */
++#include <asm/smp_alt.h>
+
+ #ifdef __KERNEL__
+
+@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
+ unsigned long prev;
+ switch (size) {
+ case 1:
+- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
++ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
++ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
++ __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
+ unsigned long long new)
+ {
+ unsigned long long prev;
+- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
++ __asm__ __volatile__(LOCK "cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+@@ -503,11 +503,55 @@ struct alt_instr {
+ #endif
+
+ #ifdef CONFIG_SMP
++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
++#define smp_alt_mb(instr) \
++__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
++ ".section __smp_alternatives,\"a\"\n" \
++ ".long 6667b\n" \
++ ".long 6673f\n" \
++ ".previous\n" \
++ ".section __smp_replacements,\"a\"\n" \
++ "6673:.byte 6668b-6667b\n" \
++ ".byte 6670f-6669f\n" \
++ ".byte 6671f-6670f\n" \
++ ".byte 0\n" \
++ ".byte %c0\n" \
++ "6669:lock;addl $0,0(%%esp)\n" \
++ "6670:" instr "\n" \
++ "6671:\n" \
++ ".previous\n" \
++ : \
++ : "i" (X86_FEATURE_XMM2) \
++ : "memory")
++#define smp_rmb() smp_alt_mb("lfence")
++#define smp_mb() smp_alt_mb("mfence")
++#define set_mb(var, value) do { \
++unsigned long __set_mb_temp; \
++__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \
++ ".section __smp_alternatives,\"a\"\n" \
++ ".long 6667b\n" \
++ ".long 6673f\n" \
++ ".previous\n" \
++ ".section __smp_replacements,\"a\"\n" \
++ "6673: .byte 6668b-6667b\n" \
++ ".byte 6670f-6669f\n" \
++ ".byte 0\n" \
++ ".byte 6671f-6670f\n" \
++ ".byte -1\n" \
++ "6669: xchg %1, %0\n" \
++ "6670:movl %1, %0\n" \
++ "6671:\n" \
++ ".previous\n" \
++ : "=m" (var), "=r" (__set_mb_temp) \
++ : "1" (value) \
++ : "memory"); } while (0)
++#else
+ #define smp_mb() mb()
+ #define smp_rmb() rmb()
++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
++#endif
+ #define smp_wmb() wmb()
+ #define smp_read_barrier_depends() read_barrier_depends()
+-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
+ #else
+ #define smp_mb() barrier()
+ #define smp_rmb() barrier()
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,89 @@
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/entry.S 2006-05-04 17:41:49.000000000 +0100
+@@ -406,7 +406,7 @@ vector=0
+ ENTRY(irq_entries_start)
+ .rept NR_IRQS
+ ALIGN
+-1: pushl $vector-256
++1: pushl $~(vector)
+ jmp common_interrupt
+ .data
+ .long 1b
+@@ -423,7 +423,7 @@ common_interrupt:
+
+ #define BUILD_INTERRUPT(name, nr) \
+ ENTRY(name) \
+- pushl $nr-256; \
++ pushl $~(nr); \
+ SAVE_ALL \
+ movl %esp,%eax; \
+ call smp_/**/name; \
+diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c ./arch/i386/kernel/irq.c
+--- ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/i386/kernel/irq.c 2006-05-04 17:41:49.000000000 +0100
+@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[.NR_CPU
+ */
+ fastcall unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- int irq = regs->orig_eax & 0xff;
++ /* high bit used in ret_from_ code */
++ int irq = ~regs->orig_eax;
+ #ifdef CONFIG_4KSTACKS
+ union irq_ctx *curctx, *irqctx;
+ u32 *isp;
+diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S ./arch/x86_64/kernel/entry.S
+--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/x86_64/kernel/entry.S 2006-05-04 17:41:49.000000000 +0100
+@@ -601,7 +601,7 @@ retint_kernel:
+ */
+ .macro apicinterrupt num,func
+ INTR_FRAME
+- pushq $\num-256
++ pushq $~(\num)
+ CFI_ADJUST_CFA_OFFSET 8
+ interrupt \func
+ jmp ret_from_intr
+diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c ./arch/x86_64/kernel/irq.c
+--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/x86_64/kernel/irq.c 2006-05-04 17:41:49.000000000 +0100
+@@ -96,8 +96,8 @@ skip:
+ */
+ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- unsigned irq = regs->orig_rax & 0xff;
++ /* high bit used in ret_from_ code */
++ unsigned irq = ~regs->orig_rax;
+
+ exit_idle();
+ irq_enter();
+diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c ./arch/x86_64/kernel/smp.c
+--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c 2006-05-02 22:38:44.000000000 +0100
++++ ./arch/x86_64/kernel/smp.c 2006-05-04 17:41:49.000000000 +0100
+@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
+
+ cpu = smp_processor_id();
+ /*
+- * orig_rax contains the interrupt vector - 256.
++ * orig_rax contains the negated interrupt vector.
+ * Use that to determine where the sender put the data.
+ */
+- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
++ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
+ f = &per_cpu(flush_state, sender);
+
+ if (!cpu_isset(cpu, f->flush_cpumask))
+diff -pruN ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h ./include/asm-x86_64/hw_irq.h
+--- ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/asm-x86_64/hw_irq.h 2006-05-04 17:41:49.000000000 +0100
+@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \
+ __asm__( \
+ "\n.p2align\n" \
+ "IRQ" #nr "_interrupt:\n\t" \
+- "push $" #nr "-256 ; " \
++ "push $~(" #nr ") ; " \
+ "jmp common_interrupt");
+
+ #if defined(CONFIG_X86_IO_APIC)
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16.13/xenoprof-generic.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,384 @@
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/buffer_sync.c 2006-05-04 17:41:51.000000000 +0100
+@@ -6,6 +6,10 @@
+ *
+ * @author John Levon <levon@movementarian.org>
+ *
++ * Modified by Aravind Menon for Xen
++ * These modifications are:
++ * Copyright (C) 2005 Hewlett-Packard Co.
++ *
+ * This is the core of the buffer management. Each
+ * CPU buffer is processed and entered into the
+ * global event buffer. Such processing is necessary
+@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
+ last_cookie = INVALID_COOKIE;
+ }
+
+-static void add_kernel_ctx_switch(unsigned int in_kernel)
++static void add_cpu_mode_switch(unsigned int cpu_mode)
+ {
+ add_event_entry(ESCAPE_CODE);
+- if (in_kernel)
+- add_event_entry(KERNEL_ENTER_SWITCH_CODE);
+- else
+- add_event_entry(KERNEL_EXIT_SWITCH_CODE);
++ switch (cpu_mode) {
++ case CPU_MODE_USER:
++ add_event_entry(USER_ENTER_SWITCH_CODE);
++ break;
++ case CPU_MODE_KERNEL:
++ add_event_entry(KERNEL_ENTER_SWITCH_CODE);
++ break;
++ case CPU_MODE_XEN:
++ add_event_entry(XEN_ENTER_SWITCH_CODE);
++ break;
++ default:
++ break;
++ }
+ }
+-
++
+ static void
+ add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
+ {
+@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
+ * for later lookup from userspace.
+ */
+ static int
+-add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
++add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
+ {
+- if (in_kernel) {
++ if (cpu_mode >= CPU_MODE_KERNEL) {
+ add_sample_entry(s->eip, s->event);
+ return 1;
+ } else if (mm) {
+@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
+ struct mm_struct *mm = NULL;
+ struct task_struct * new;
+ unsigned long cookie = 0;
+- int in_kernel = 1;
++ int cpu_mode = 1;
+ unsigned int i;
+ sync_buffer_state state = sb_buffer_start;
+ unsigned long available;
+@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
+ struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
+
+ if (is_code(s->eip)) {
+- if (s->event <= CPU_IS_KERNEL) {
++ if (s->event <= CPU_MODE_XEN) {
+ /* kernel/userspace switch */
+- in_kernel = s->event;
++ cpu_mode = s->event;
+ if (state == sb_buffer_start)
+ state = sb_sample_start;
+- add_kernel_ctx_switch(s->event);
++ add_cpu_mode_switch(s->event);
+ } else if (s->event == CPU_TRACE_BEGIN) {
+ state = sb_bt_start;
+ add_trace_begin();
+@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
+ }
+ } else {
+ if (state >= sb_bt_start &&
+- !add_sample(mm, s, in_kernel)) {
++ !add_sample(mm, s, cpu_mode)) {
+ if (state == sb_bt_start) {
+ state = sb_bt_ignore;
+ atomic_inc(&oprofile_stats.bt_lost_no_mapping);
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/cpu_buffer.c 2006-05-04 17:41:51.000000000 +0100
+@@ -6,6 +6,10 @@
+ *
+ * @author John Levon <levon@movementarian.org>
+ *
++ * Modified by Aravind Menon for Xen
++ * These modifications are:
++ * Copyright (C) 2005 Hewlett-Packard Co.
++ *
+ * Each CPU has a local buffer that stores PC value/event
+ * pairs. We also log context switches when we notice them.
+ * Eventually each CPU's buffer is processed into the global
+@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
+ goto fail;
+
+ b->last_task = NULL;
+- b->last_is_kernel = -1;
++ b->last_cpu_mode = -1;
+ b->tracing = 0;
+ b->buffer_size = buffer_size;
+ b->tail_pos = 0;
+@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
+ * collected will populate the buffer with proper
+ * values to initialize the buffer
+ */
+- cpu_buf->last_is_kernel = -1;
++ cpu_buf->last_cpu_mode = -1;
+ cpu_buf->last_task = NULL;
+ }
+
+@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
+ * because of the head/tail separation of the writer and reader
+ * of the CPU buffer.
+ *
+- * is_kernel is needed because on some architectures you cannot
++ * cpu_mode is needed because on some architectures you cannot
+ * tell if you are in kernel or user space simply by looking at
+- * pc. We tag this in the buffer by generating kernel enter/exit
+- * events whenever is_kernel changes
++ * pc. We tag this in the buffer by generating kernel/user (and xen)
++ * enter events whenever cpu_mode changes
+ */
+ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
+- int is_kernel, unsigned long event)
++ int cpu_mode, unsigned long event)
+ {
+ struct task_struct * task;
+
+@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
+ return 0;
+ }
+
+- is_kernel = !!is_kernel;
++ WARN_ON(cpu_mode > CPU_MODE_XEN);
+
+ task = current;
+
+ /* notice a switch from user->kernel or vice versa */
+- if (cpu_buf->last_is_kernel != is_kernel) {
+- cpu_buf->last_is_kernel = is_kernel;
+- add_code(cpu_buf, is_kernel);
++ if (cpu_buf->last_cpu_mode != cpu_mode) {
++ cpu_buf->last_cpu_mode = cpu_mode;
++ add_code(cpu_buf, cpu_mode);
+ }
+-
++
+ /* notice a task switch */
+ if (cpu_buf->last_task != task) {
+ cpu_buf->last_task = task;
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/cpu_buffer.h 2006-05-04 17:41:51.000000000 +0100
+@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
+ volatile unsigned long tail_pos;
+ unsigned long buffer_size;
+ struct task_struct * last_task;
+- int last_is_kernel;
++ int last_cpu_mode;
+ int tracing;
+ struct op_sample * buffer;
+ unsigned long sample_received;
+@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
+ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
+
+ /* transient events for the CPU buffer -> event buffer */
+-#define CPU_IS_KERNEL 1
+-#define CPU_TRACE_BEGIN 2
++#define CPU_MODE_USER 0
++#define CPU_MODE_KERNEL 1
++#define CPU_MODE_XEN 2
++#define CPU_TRACE_BEGIN 3
+
+ #endif /* OPROFILE_CPU_BUFFER_H */
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/event_buffer.h 2006-05-04 17:41:51.000000000 +0100
+@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
+ #define CPU_SWITCH_CODE 2
+ #define COOKIE_SWITCH_CODE 3
+ #define KERNEL_ENTER_SWITCH_CODE 4
+-#define KERNEL_EXIT_SWITCH_CODE 5
++#define USER_ENTER_SWITCH_CODE 5
+ #define MODULE_LOADED_CODE 6
+ #define CTX_TGID_CODE 7
+ #define TRACE_BEGIN_CODE 8
+ #define TRACE_END_CODE 9
++#define XEN_ENTER_SWITCH_CODE 10
+
+ #define INVALID_COOKIE ~0UL
+ #define NO_COOKIE 0UL
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100
+@@ -5,6 +5,10 @@
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
++ *
++ * Modified by Aravind Menon for Xen
++ * These modifications are:
++ * Copyright (C) 2005 Hewlett-Packard Co.
+ */
+
+ #include <linux/kernel.h>
+@@ -19,7 +23,7 @@
+ #include "cpu_buffer.h"
+ #include "buffer_sync.h"
+ #include "oprofile_stats.h"
+-
++
+ struct oprofile_operations oprofile_ops;
+
+ unsigned long oprofile_started;
+@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
+ */
+ static int timer = 0;
+
++extern unsigned int adomains;
++extern int active_domains[MAX_OPROF_DOMAINS];
++
++int oprofile_set_active(void)
++{
++ if (oprofile_ops.set_active)
++ return oprofile_ops.set_active(active_domains, adomains);
++
++ return -EINVAL;
++}
++
+ int oprofile_setup(void)
+ {
+ int err;
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100
+@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
+ void oprofile_timer_init(struct oprofile_operations * ops);
+
+ int oprofile_set_backtrace(unsigned long depth);
++
++int oprofile_set_active(void);
+
+ #endif /* OPROF_H */
+diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/oprofile/oprofile_files.c 2006-05-04 17:41:51.000000000 +0100
+@@ -5,15 +5,21 @@
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
++ *
++ * Modified by Aravind Menon for Xen
++ * These modifications are:
++ * Copyright (C) 2005 Hewlett-Packard Co.
+ */
+
+ #include <linux/fs.h>
+ #include <linux/oprofile.h>
++#include <asm/uaccess.h>
++#include <linux/ctype.h>
+
+ #include "event_buffer.h"
+ #include "oprofile_stats.h"
+ #include "oprof.h"
+-
++
+ unsigned long fs_buffer_size = 131072;
+ unsigned long fs_cpu_buffer_size = 8192;
+ unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
+@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file *
+ static struct file_operations dump_fops = {
+ .write = dump_write,
+ };
+-
++
++#define TMPBUFSIZE 512
++
++unsigned int adomains = 0;
++long active_domains[MAX_OPROF_DOMAINS];
++
++static ssize_t adomain_write(struct file * file, char const __user * buf,
++ size_t count, loff_t * offset)
++{
++ char tmpbuf[TMPBUFSIZE];
++ char * startp = tmpbuf;
++ char * endp = tmpbuf;
++ int i;
++ unsigned long val;
++
++ if (*offset)
++ return -EINVAL;
++ if (!count)
++ return 0;
++ if (count > TMPBUFSIZE - 1)
++ return -EINVAL;
++
++ memset(tmpbuf, 0x0, TMPBUFSIZE);
++
++ if (copy_from_user(tmpbuf, buf, count))
++ return -EFAULT;
++
++ for (i = 0; i < MAX_OPROF_DOMAINS; i++)
++ active_domains[i] = -1;
++ adomains = 0;
++
++ while (1) {
++ val = simple_strtol(startp, &endp, 0);
++ if (endp == startp)
++ break;
++ while (ispunct(*endp))
++ endp++;
++ active_domains[adomains++] = val;
++ if (adomains >= MAX_OPROF_DOMAINS)
++ break;
++ startp = endp;
++ }
++ if (oprofile_set_active())
++ return -EINVAL;
++ return count;
++}
++
++static ssize_t adomain_read(struct file * file, char __user * buf,
++ size_t count, loff_t * offset)
++{
++ char tmpbuf[TMPBUFSIZE];
++ size_t len = 0;
++ int i;
++ /* This is all screwed up if we run out of space */
++ for (i = 0; i < adomains; i++)
++ len += snprintf(tmpbuf + len, TMPBUFSIZE - len,
++ "%u ", (unsigned int)active_domains[i]);
++ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
++ return simple_read_from_buffer((void __user *)buf, count,
++ offset, tmpbuf, len);
++}
++
++
++static struct file_operations active_domain_ops = {
++ .read = adomain_read,
++ .write = adomain_write,
++};
++
+ void oprofile_create_files(struct super_block * sb, struct dentry * root)
+ {
+ oprofilefs_create_file(sb, root, "enable", &enable_fops);
+ oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
++ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
+ oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
+ oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
+ oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
+diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h
+--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-02 22:38:44.000000000 +0100
++++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100
+@@ -16,6 +16,8 @@
+ #include <linux/types.h>
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
++
++#include <xen/interface/xenoprof.h>
+
+ struct super_block;
+ struct dentry;
+@@ -27,6 +29,8 @@ struct oprofile_operations {
+ /* create any necessary configuration files in the oprofile fs.
+ * Optional. */
+ int (*create_files)(struct super_block * sb, struct dentry * root);
++ /* setup active domains with Xen */
++ int (*set_active)(int *active_domains, unsigned int adomains);
+ /* Do any necessary interrupt setup. Optional. */
+ int (*setup)(void);
+ /* Do any necessary interrupt shutdown. Optional. */
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_acm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_acm.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "xc_private.h"
+
+int xc_acm_op(int xc_handle, struct acm_op *op)
+{
+ int ret = -1;
+ DECLARE_HYPERCALL;
+
+ op->interface_version = ACM_INTERFACE_VERSION;
+
+ hypercall.op = __HYPERVISOR_acm_op;
+ hypercall.arg[0] = (unsigned long) op;
+
+ if (mlock(op, sizeof(*op)) != 0) {
+ PERROR("Could not lock memory for Xen policy hypercall");
+ goto out1;
+ }
+
+ ret = do_xen_hypercall(xc_handle, &hypercall);
+ ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
+ if (ret < 0) {
+ goto out2;
+ }
+ out2:
+ safe_munlock(op, sizeof(*op));
+ out1:
+ return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/libxc/xc_linux.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_linux.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "xc_private.h"
+
+#include <xen/memory.h>
+#include <xen/sys/evtchn.h>
+
+int xc_interface_open(void)
+{
+ int fd = open("/proc/xen/privcmd", O_RDWR);
+ if ( fd == -1 )
+ PERROR("Could not obtain handle on privileged command interface");
+ return fd;
+}
+
+int xc_interface_close(int xc_handle)
+{
+ return close(xc_handle);
+}
+
+void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+ unsigned long *arr, int num)
+{
+ privcmd_mmapbatch_t ioctlx;
+ void *addr;
+ addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
+ if ( addr == MAP_FAILED )
+ return NULL;
+
+ ioctlx.num=num;
+ ioctlx.dom=dom;
+ ioctlx.addr=(unsigned long)addr;
+ ioctlx.arr=arr;
+ if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
+ {
+ int saved_errno = errno;
+ perror("XXXXXXXX");
+ (void)munmap(addr, num*PAGE_SIZE);
+ errno = saved_errno;
+ return NULL;
+ }
+ return addr;
+
+}
+
+void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+ int size, int prot,
+ unsigned long mfn)
+{
+ privcmd_mmap_t ioctlx;
+ privcmd_mmap_entry_t entry;
+ void *addr;
+ addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
+ if ( addr == MAP_FAILED )
+ return NULL;
+
+ ioctlx.num=1;
+ ioctlx.dom=dom;
+ ioctlx.entry=&entry;
+ entry.va=(unsigned long) addr;
+ entry.mfn=mfn;
+ entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
+ if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
+ {
+ int saved_errno = errno;
+ (void)munmap(addr, size);
+ errno = saved_errno;
+ return NULL;
+ }
+ return addr;
+}
+
+int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+ privcmd_mmap_entry_t *entries, int nr)
+{
+ privcmd_mmap_t ioctlx;
+
+ ioctlx.num = nr;
+ ioctlx.dom = dom;
+ ioctlx.entry = entries;
+
+ return ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
+}
+
+static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
+{
+ return ioctl(xc_handle, cmd, data);
+}
+
+int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+{
+ return do_privcmd(xc_handle,
+ IOCTL_PRIVCMD_HYPERCALL,
+ (unsigned long)hypercall);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/Writing_Tests_HOWTO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/Writing_Tests_HOWTO Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,134 @@
+
+Writing Tests HOWTO
+===================
+
+One goal for xm-test is to make test writing very easy. Xm-test includes
+a library in lib/XmTestLib that contains all the necessary methods for
+creating and shutting down domains. Include the library in your test by
+importing it:
+
+ from XmTestLib import *
+
+
+Guidelines
+==========
+
+1. Tests should be short and single purposed. This means testing as
+ little as possible in a single test. Do not overload tests. The more
+ that's in a test the more difficult it is to track down what failed.
+
+2. Tests should report as much information as possible when calling
+ FAIL() or SKIP().
+
+3. A test should report SKIP() only if it cannot be run on the current
+ machine or it makes no sense to run it. SMP tests on an UP system,
+ for example, may not make sense. Or, there are some tests for
+ para-virtualized guests that won't work on a fully virtualized
+ guest.
+
+4. Use the traceCommand() function to run commands on Domain0, the
+ Xen management domain. This function logs everything, which is useful
+ in case of failure.
+
+5. Use the domain's console.runCmd method to run commands on a guest
+ domain. This ensures logging and consistency. Please see 'Creating
+ and Using Domains' below for an example.
+
+6. Tests need to capture and handle libary exceptions such as:
+
+ - ConsoleError can be raised when sending a command to a console.
+ - DomainError can be raised when a domain is started, indicating
+ a possible configuration error.
+ - TimeoutError can be raised when the traceCommand() method is used.
+
+7. Tests shouldn't depend on where the test is being run from or the
+ system on which it is run.
+
+8. Please use the existing tests for a guide, especially:
+
+ - create/01_create_basic_pos.py
+ - create/13_create_multinic_pos.py
+ - memset/01_memset_basic_pos.py
+ - reboot/01_reboot_basic_pos.py
+ - migrate/01_migrate_localhost_pos.py
+
+
+Creating and Using Domains
+==========================
+
+Xen domains, both full and para virtualized, are represented by the
+XmTestDomain class. The class contains methods for starting a Xen domain,
+shutting it down, or destroying it. Consoles, used to execute commands
+on guest test domains, are opened and closed through the XmTestDomain
+class. Devices, which are represented by the XenDevice class, are also
+added and removed using XmTestDomain methods.
+
+Here's a simple example for creating a domain, opening a console, running
+a command, and then shutting down the domain:
+
+1) Create a domain:
+
+ domain = XmTestDomain()
+
+2) Start the domain and grab a console:
+
+ try:
+ console = domain.start()
+ except DomainError, e:
+ if verbose:
+ print "Failed to create test domain because:"
+ print e.extra
+ FAIL(str(e))
+
+3) Run a command inside the new domain using the console, saving the
+ console log if an error is encountered:
+
+ try:
+ # Run 'ls'
+ run = console.runCmd("ls")
+ except ConsoleError, e:
+ saveLog(console.getHistory())
+ FAIL(str(e))
+
+4) Stop the domain, which nicely shuts it down:
+
+ domain.stop()
+
+
+Writing Tests with Networking
+=============================
+
+The xm-test suite includes the ability to test networking for domains.
+Networking is configured at configuration time. While testing NAT and
+routing environments in the future, the current xm-test only supports
+a bridging environment. Xm-test currently only supports a range of
+IPs, the dhcp feature will be added soon.
+
+The network tests will need to know what IPs to use. IPs are configured
+when you build xm-test. Xm-test uses the zeroconf address range by
+default, 169.254.0.1-169.254.255.255. If you'd like to set a new range,
+do so at configure time, a netmask and network address must also be defined:
+
+ # ./configure --with-net-ip-range=192.168.1.1-192.168.1.100 --with-network-address=192.168.1.0 --with-netmask=255.255.255.0
+
+The tests will not need to set network information, this is done by
+the library once it's configured.
+
+As mentioned above, xm-test's goal is to make writing tests easy. Creating
+domains with networking should also be easy. To create a domain with
+a single network interface, tests can use a XmTestNetDomain object. It
+creates a XenNetDevice for the domain automatically using the pre-configured
+IP information. Otherwise, a network interface can be added to a domain
+prior to starting it (the ability to attach devices will be added):
+
+ domain = XmTestDomain()
+ domain.newDevice(XenNetDevice, "eth0")
+ domain.newDevice(XenNetDevice, "eth1")
+
+Here, the domain is created and then the XenDomain factory newDevice
+is called to create a new device of class XenNetDevice to the domain.
+The xm-test library will automatically assign an IP from the configured
+list, execute ifconfig on the guest domain console, and create an
+alias on Domain0.
+
+
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/NetConfig.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/NetConfig.py Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,264 @@
+#!/usr/bin/python
+"""
+ Copyright (C) International Business Machines Corp., 2005, 2006
+ Authors: Dan Smith <danms@us.ibm.com>
+ Daniel Stekloff <dsteklof@us.ibm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; under version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+
+import sys
+import commands
+import os
+import re
+import time
+import random
+from xen.xend.sxp import Parser
+
+from Xm import *
+from Test import *
+from config import *
+
+class NetworkError(Exception):
+ def __init__(self, msg):
+ self.errMsg = msg
+
+ def __str__(self):
+ return str(self.errMsg)
+
+def getXendNetConfig():
+ # Find out what environment we're in: bridge, nat, or route
+ xconfig = os.getenv("XEND_CONFIG")
+ if not xconfig:
+ xconfig = "/etc/xen/xend-config.sxp"
+
+ configfile = open(xconfig, 'r')
+ S = configfile.read()
+ pin = Parser()
+ pin.input(S)
+ pin.input_eof()
+ val = pin.get_val()
+ while val[0] != 'network-script':
+ val = pin.get_val()
+
+ if val[1] == "network-bridge":
+ netenv = "bridge"
+ elif val[1] == "network-route":
+ netenv = "route"
+ elif val[1] == "network-nat":
+ netenv = "nat"
+ else:
+ raise NetworkError("Failed to get network env from xend config")
+
+ configfile.close()
+ return netenv
+
+def checkZeroconfAddresses():
+ # Make sure there aren't existing zeroconf addresses.
+ rc, out = traceCommand("ip addr show |grep \"inet 169.254\" | grep -v vif")
+ if rc == 0:
+ raise NetworkError("Zeroconf addresses already used: %s" % out)
+
+class NetConfig:
+
+ def __init__(self):
+ self.netenv = getXendNetConfig()
+ self.used_ips = {}
+ self.free_oct_ips = [ 0, 0, 0, 0 ]
+ self.total_ips = 0
+
+ if NETWORK_IP_RANGE == 'dhcp':
+ self.netmask = NETWORK_IP_RANGE
+ self.network = NETWORK_IP_RANGE
+ self.max_ip = NETWORK_IP_RANGE
+ self.min_ip = NETWORK_IP_RANGE
+ else:
+ self.netmask = NETMASK
+ self.network = NETWORK
+ s_ip = ''
+
+ # Get starting ip and max ip from configured ip range
+ s_ip = NETWORK_IP_RANGE
+ ips = s_ip.split("-")
+ self.max_ip = ips[1]
+ self.min_ip = ips[0]
+
+ self.__setMaxNumberIPs()
+
+ if self.network == "169.254.0.0":
+ checkZeroconfAddresses()
+
+ # Clean out any aliases in the network range for vif0.0. If
+ # an alias exists, a test xendevice add command could fail.
+ if NETWORK_IP_RANGE != "dhcp":
+ self.__cleanDom0Aliases()
+
+ def __setMaxNumberIPs(self):
+ # Count the number of IPs available, to help tests know whether they
+ # have enough to run or not
+ masko = self.netmask.split('.')
+ maxo = self.max_ip.split('.')
+ mino = self.min_ip.split('.')
+ ips = 0
+
+ # Last octet
+ self.free_oct_ips[3] = (int(maxo[3]) - int(mino[3])) + 1
+
+ # 3rd octet
+ self.free_oct_ips[2] = (int(maxo[2]) - int(mino[2])) + 1
+
+ # 2nd octet
+ self.free_oct_ips[1] = (int(maxo[1]) - int(mino[1])) + 1
+
+ # 1st octet
+ self.free_oct_ips[0] = (int(maxo[0]) - int(mino[0])) + 1
+
+ self.total_ips = self.free_oct_ips[3]
+ if self.free_oct_ips[2] > 1:
+ self.total_ips = (self.total_ips * self.free_oct_ips[2])
+ if self.free_oct_ips[1] > 1:
+ self.total_ips = (self.total_ips * self.free_oct_ips[1])
+ if self.free_oct_ips[0] > 1:
+ self.total_ips = (self.total_ips * self.free_oct_ips[0])
+
+ def __cleanDom0Aliases(self):
+ # Remove any aliases within the supplied network IP range on dom0
+ scmd = 'ip addr show dev vif0.0'
+
+ status, output = traceCommand(scmd)
+ if status:
+ raise NetworkError("Failed to show vif0.0 aliases: %d" % status)
+
+ lines = output.split("\n")
+ for line in lines:
+ ip = re.search('(\d+\.\d+\.\d+\.\d+)', line)
+ if ip and self.isIPInRange(ip.group(1)) == True:
+ dcmd = 'ip addr del %s dev vif0.0' % ip.group(1)
+ dstatus, doutput = traceCommand(dcmd)
+ if dstatus:
+ raise NetworkError("Failed to remove vif0.0 aliases: %d" % status)
+
+ def getNetEnv(self):
+ return self.netenv
+
+ def setUsedIP(self, domname, interface, ip):
+ self.used_ips['%s:%s' % (domname, interface)] = ip
+
+ def __findFirstOctetIP(self, prefix, min, max):
+ for i in range(min, max):
+ ip = '%s%s' % (prefix, str(i))
+ found = False
+ for k in self.used_ips.keys():
+ if self.used_ips[k] == ip:
+ found = True
+ if found == False:
+ return ip
+
+ if found == True:
+ return None
+
+ def getFreeIP(self, domname, interface):
+ # Get a free IP. It uses the starting ip octets and then the
+ # total number of allowed numbers for that octet. It only
+ # calculates ips for the last two octets, we shouldn't need more
+ start_octets = self.min_ip.split(".")
+ ip = None
+
+ # Only working with ips from last two octets, shouldn't need more
+ max = int(start_octets[2]) + self.free_oct_ips[2]
+ for i in range(int(start_octets[2]), max):
+ prefix = '%s.%s.%s.' % (start_octets[0], start_octets[1], str(i))
+ ip = self.__findFirstOctetIP(prefix, int(start_octets[3]), self.free_oct_ips[3])
+ if ip:
+ break
+
+ if not ip:
+ raise NetworkError("Ran out of configured addresses.")
+
+ self.setUsedIP(domname, interface, ip)
+ return ip
+
+ def getNetMask(self):
+ return self.netmask
+
+ def getNetwork(self):
+ return self.network
+
+ def getIP(self, domname, interface):
+ # Depending on environment, set an IP. Uses the configured range
+ # of IPs, network address, and netmask
+ if NETWORK_IP_RANGE == "dhcp":
+ return None
+
+ # Make sure domain and interface aren't already assigned an IP
+ if self.used_ips.has_key('%s:%s' % (domname, interface)):
+ raise NetworkError("Domain %s interface %s is already has IP"
+ % (domname, interface))
+
+ return self.getFreeIP(domname, interface)
+
+ def setIP(self, domname, interface, ip):
+ # Make sure domain and interface aren't already assigned an IP
+ if self.used_ips.has_key('%s:%s' % (domname, interface)):
+ raise NetworkError("Domain %s interface %s is already has IP"
+ % (domname, interface))
+
+ self.setUsedIP(domname, interface, ip)
+
+ def releaseIP(self, domname, interface, ip):
+ if self.used_ips.has_key('%s:%s' % (domname, interface)):
+ del self.used_ips['%s:%s' % (domname, interface)]
+
+ def getNumberAllowedIPs(self):
+ return self.total_ips
+
+ def canRunNetTest(self, ips):
+ # Check to see if a test can run, returns true or false. Input is
+ # number of ips needed.
+ if NETWORK_IP_RANGE == "dhcp":
+ return True
+
+ if self.total_ips >= ips:
+ return True
+
+ return False
+
+ def isIPInRange(self, ip):
+ # Checks to see if supplied ip is in the range of allowed ips
+ maxo = self.max_ip.split('.')
+ mino = self.min_ip.split('.')
+ ipo = ip.split('.')
+
+ if int(ipo[0]) < int(mino[0]):
+ return False
+ elif int(ipo[0]) > int(maxo[0]):
+ return False
+
+ if int(ipo[1]) < int(mino[1]):
+ return False
+ elif int(ipo[1]) > int(maxo[1]):
+ return False
+
+ if int(ipo[2]) < int(mino[2]):
+ return False
+ elif int(ipo[2]) > int(maxo[2]):
+ return False
+
+ if int(ipo[3]) < int(mino[3]):
+ return False
+ elif int(ipo[3]) > int(maxo[3]):
+ return False
+
+ return True
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/XenDevice.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/XenDevice.py Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,271 @@
+#!/usr/bin/python
+"""
+ Copyright (C) International Business Machines Corp., 2005, 2006
+ Authors: Dan Smith <danms@us.ibm.com>
+ Daniel Stekloff <dsteklof@us.ibm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; under version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+
+import sys
+import commands
+import os
+import re
+import time
+
+from Xm import *
+from Test import *
+from config import *
+from XenDomain import *
+from NetConfig import *
+from XmTestLib import *
+from __init__ import *
+
+class XenNetDevCmd:
+
+ def __init__(self, netDevice, addCmd, removeCmd):
+ """Object representing a network device command"""
+ self.addcmd = addCmd
+ self.removecmd = removeCmd
+ self.addhasrun = False
+ self.rmvhasrun = False
+ self.netdevice = netDevice
+
+ def getAddCmd(self):
+ return self.addcmd
+
+ def getRemoveCmd(self):
+ return self.removecmd
+
+ def hasAddRun(self):
+ return self.addhasrun
+
+ def hasRemoveRun(self):
+ self.rmvhasrun
+
+ def runAddCmd(self, runOnDom0=False):
+ # Defaults running command on dom0, if console then will run there
+ if runOnDom0 == False:
+ dom = self.netdevice.getDomain()
+ console = dom.getConsole()
+ console.runCmd(self.addcmd)
+ else:
+ status, output = traceCommand(self.addcmd)
+ if status:
+ raise NetworkError("Device add cmd failed: %s Status: %d"
+ % (self.addcmd, status))
+ self.addhasrun = True
+
+ def runRemoveCmd(self, runOnDom0=False):
+ # Defaults running command on dom0, if console then will run there
+ if runOnDom0 == False:
+ dom = self.netdevice.getDomain()
+ console = dom.getConsole()
+ console.runCmd(self.removecmd)
+ else:
+ status, output = traceCommand(self.removecmd)
+ if status:
+ raise NetworkError("Device remove cmd failed: %s Status: %d"
+ % (self.removecmd, status))
+ self.removehasrun = True
+
+class XenDevice:
+
+ def __init__(self, domain, id, devConfig=None):
+ """An object to represent Xen Devices like network and block
+ @param domain: Domain the device will be added to
+ @param id: Device identifier
+ @param devConfig: Initial configuration dictionary for XenDevice
+ """
+ if config:
+ self.config = devConfig
+ else:
+ self.config = {}
+
+ self.id = id
+ self.domain = domain
+ self.configNode = None
+ # Commands run when domain is started or devices added and removed.
+ self.dom0_cmds = []
+ self.domU_cmds = []
+
+ def __str__(self):
+ """Convert device config to XenConfig node compatible string"""
+ confstr = ''
+ for k, v in self.config.items():
+ if len(confstr) > 0:
+ confstr += ', '
+ if isinstance(v, int):
+ confstr += "%s=%i" % (k, v)
+ elif isinstance(v, list) and v:
+ confstr += "%s=%s" % (k, v)
+ elif isinstance(v, str) and v:
+ confstr += "%s=%s" % (k, v)
+
+ return confstr
+
+ def execAddCmds(self):
+ # Cmds for when a device is added to the system
+ if len(self.dom0_cmds) > 0:
+ for i in range(0, len(self.dom0_cmds)):
+ if self.dom0_cmds[i].getAddCmd():
+ self.dom0_cmds[i].runAddCmd(runOnDom0=True)
+
+ if len(self.domU_cmds) > 0:
+ for i in range(0, len(self.domU_cmds)):
+ if self.domU_cmds[i].getAddCmd():
+ self.domU_cmds[i].runAddCmd()
+
+ def execRemoveCmds(self):
+ # Cmds for when a device is removed from the system
+ if len(self.dom0_cmds) > 0:
+ for i in range(0, len(self.dom0_cmds)):
+ if (self.dom0_cmds[i].getRemoveCmd()
+ and self.dom0_cmds[i].hasAddRun() == True):
+ self.dom0_cmds[i].runRemoveCmd(runOnDom0=True)
+
+ if len(self.domU_cmds) > 0:
+ for i in range(0, len(self.domU_cmds)):
+ if (self.domU_cmds[i].getRemoveCmd()
+ and self.domU_cmds[i].hasAddRun() == True):
+ self.domU_cmds[i].runRemoveCmd()
+
+ def removeDevice(self):
+ self.execRemoveCmds()
+
+ def getId(self):
+ return self.id
+
+ def getConfigOpt(self):
+ return self.configNode
+
+ def getDomain(self):
+ return self.domain
+
+class XenNetDevice(XenDevice):
+
+ def __init__(self, domain, id, devConfig=None):
+ """An object to represent Xen Network Device
+ @param domain: Domain the device is being added to
+ @param id: Network device identifier, interface name like eth0
+ @param devConfig: Initial dictionary configuration for XenNetDevice
+ """
+ if devConfig:
+ self.config = devConfig
+ else:
+ self.config = {}
+
+ self.id = id
+ self.domain = domain
+ self.configNode = "vif"
+ self.dom0_cmds = []
+ self.domU_cmds = []
+ self.network = None
+ self.netmask = None
+ self.ip = None
+ self.dom0_alias_ip = None
+
+ if domain.getDomainType() == "HVM":
+ self.config["type"] = "ioemu"
+ if not self.config.has_key('bridge'):
+ self.config["bridge"] = "xenbr0"
+
+ if self.config.has_key("ip"):
+ self.setNetDevIP(ip=self.config["ip"])
+ else:
+ if NETWORK_IP_RANGE != "dhcp":
+ self.setNetDevIP()
+
+ def __del__(self):
+ # Make sure we clean up NetConfig's list of ips, so the ip can be
+ # reused
+ self.releaseNetDevIP()
+
+ def addIfconfigCmd(self, domU=True):
+ # Method to add start and remove ifconfig functions
+ if domU == True:
+ locmd = XenNetDevCmd(self, addCmd="ifconfig lo 127.0.0.1", removeCmd=None)
+ ifcmd = []
+
+
+ # Start or Add cmd
+ acmd = 'ifconfig %s inet %s netmask %s up' % (self.id, self.ip, self.netmask)
+ rcmd = 'ifconfig %s down' % self.id
+ ifcmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
+
+ if domU == True:
+ self.domU_cmds.append(locmd)
+ self.domU_cmds.append(ifcmd)
+ else:
+ self.dom0_cmds.append(ifcmd)
+
+ def removeDevice(self):
+ self.releaseNetDevIP()
+
+ def addDom0AliasCmd(self, dev="vif0.0"):
+ # Method to add start and remove dom0 alias cmds
+ acmd = 'ip addr add %s dev %s' % (self.dom0_alias_ip, dev)
+ rcmd = 'ip addr del %s dev %s' % (self.dom0_alias_ip, dev)
+ aliascmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
+
+ self.dom0_cmds.append(aliascmd)
+
+ def releaseNetDevIP(self):
+ # Must remove start cmds for ip configuration and then release from
+ # NetConfig
+ self.execRemoveCmds()
+ self.dom0_cmds = []
+ self.domU_cmds = []
+ if self.config.has_key("ip"):
+ del self.config["ip"]
+
+ if self.dom0_alias_ip:
+ xmtest_netconf.releaseIP("domain0", self.domain.getName(), self.dom0_alias_ip)
+ xmtest_netconf.releaseIP(self.domain.getName(), self.id, self.ip)
+
+ def getNetDevIP(self):
+ return self.ip
+
+ def getDom0AliasIP(self):
+ return self.dom0_alias_ip
+
+ def getNetwork(self):
+ return self.network
+
+ def setNetDevIP(self, ip=None):
+ # Function to set a new IP for NetDevice.
+ if NETWORK_IP_RANGE == "dhcp":
+ raise NetworkError("System configured for dhcp, cannot set new ip.")
+
+ if (self.ip and not ip) or ((self.ip and ip) and (self.ip != ip)):
+ self.releaseNetDevIP()
+
+ if not self.netmask:
+ self.netmask = xmtest_netconf.getNetMask()
+
+ if not self.network:
+ self.network = xmtest_netconf.getNetwork()
+
+ if ip:
+ xmtest_netconf.setIP(self.domain.getName(), self.id, ip)
+ self.ip = ip
+ else:
+ self.ip = xmtest_netconf.getIP(self.domain.getName(), self.id)
+
+ self.addIfconfigCmd()
+
+ # Setup an alias for Dom0
+ self.dom0_alias_ip = xmtest_netconf.getIP("domain0", self.domain.getName())
+ self.addDom0AliasCmd()
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/block_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/block_utils.py Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+# Copyright (c) 2006 XenSource Inc.
+# Author: Ewan Mellor <ewan@xensource.com>
+
+import time
+
+from XmTestLib import *
+
+import xen.util.blkif
+
+
+__all__ = [ "block_attach", "block_detach" ]
+
+
+def get_state(domain, devname):
+ number = xen.util.blkif.blkdev_name_to_number(devname)
+ s, o = traceCommand("xm block-list %s | awk '/^%d/ {print $4}'" %
+ (domain.getName(), number))
+ if s != 0:
+ FAIL("block-list failed")
+ if o == "":
+ return 0
+ else:
+ return int(o)
+
+
+def block_attach(domain, phy, virt):
+ status, output = traceCommand("xm block-attach %s %s %s w" %
+ (domain.getName(), phy, virt))
+ if status != 0:
+ FAIL("xm block-attach returned invalid %i != 0" % status)
+
+ for i in range(10):
+ if get_state(domain, virt) == 4:
+ break
+ time.sleep(1)
+ else:
+ FAIL("block-attach failed: device did not switch to Connected state")
+
+
+def block_detach(domain, virt):
+ status, output = traceCommand("xm block-detach %s %s" %
+ (domain.getName(), virt))
+ if status != 0:
+ FAIL("xm block-detach returned invalid %i != 0" % status)
+
+ for i in range(10):
+ if get_state(domain, virt) == 0:
+ break
+ time.sleep(1)
+ else:
+ FAIL("block-detach failed: device did not disappear")
diff -r 707737b66f58 -r 5d9eb92e63e2 xen/arch/x86/compat.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/compat.c Mon May 08 14:46:11 2006 -0600
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * compat.c
+ *
+ * Implementations of legacy hypercalls. These call through to the new
+ * hypercall after doing necessary argument munging.
+ */
+
+#include <xen/config.h>
+#include <xen/guest_access.h>
+#include <xen/hypercall.h>
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
+{
+ struct physdev_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u });
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+ struct evtchn_op op;
+
+ if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+ return -EFAULT;
+
+ return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u });
+}
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_XEN_TPMDEV_FRONTEND) += tpmfront.o
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,767 +0,0 @@
-/*
- * Copyright (c) 2005, IBM Corporation
- *
- * Author: Stefan Berger, stefanb@us.ibm.com
- * Grant table support: Mahadevan Gomathisankaran
- *
- * This code has been derived from drivers/xen/netfront/netfront.c
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <xen/tpmfe.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <asm/io.h>
-#include <xen/evtchn.h>
-#include <xen/interface/grant_table.h>
-#include <xen/interface/io/tpmif.h>
-#include <asm/uaccess.h>
-#include <xen/xenbus.h>
-#include <xen/interface/grant_table.h>
-
-#include "tpmfront.h"
-
-#undef DEBUG
-
-/* locally visible variables */
-static grant_ref_t gref_head;
-static struct tpm_private *my_priv;
-
-/* local function prototypes */
-static irqreturn_t tpmif_int(int irq,
- void *tpm_priv,
- struct pt_regs *ptregs);
-static void tpmif_rx_action(unsigned long unused);
-static int tpmif_connect(struct xenbus_device *dev,
- struct tpm_private *tp,
- domid_t domid);
-static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
-static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
-static void tpmif_free_tx_buffers(struct tpm_private *tp);
-static void tpmif_set_connected_state(struct tpm_private *tp,
- u8 newstate);
-static int tpm_xmit(struct tpm_private *tp,
- const u8 * buf, size_t count, int userbuffer,
- void *remember);
-static void destroy_tpmring(struct tpm_private *tp);
-
-#define DPRINTK(fmt, args...) \
- pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
-#define IPRINTK(fmt, args...) \
- printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
-#define WPRINTK(fmt, args...) \
- printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
-
-#define GRANT_INVALID_REF 0
-
-
-static inline int
-tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
- int isuserbuffer)
-{
- int copied = len;
-
- if (len > txb->size) {
- copied = txb->size;
- }
- if (isuserbuffer) {
- if (copy_from_user(txb->data, src, copied))
- return -EFAULT;
- } else {
- memcpy(txb->data, src, copied);
- }
- txb->len = len;
- return copied;
-}
-
-static inline struct tx_buffer *tx_buffer_alloc(void)
-{
- struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
- GFP_KERNEL);
-
- if (txb) {
- txb->len = 0;
- txb->size = PAGE_SIZE;
- txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
- if (txb->data == NULL) {
- kfree(txb);
- txb = NULL;
- }
- }
- return txb;
-}
-
-
-static inline void tx_buffer_free(struct tx_buffer *txb)
-{
- if (txb) {
- free_page((long)txb->data);
- kfree(txb);
- }
-}
-
-/**************************************************************
- Utility function for the tpm_private structure
-**************************************************************/
-static inline void tpm_private_init(struct tpm_private *tp)
-{
- spin_lock_init(&tp->tx_lock);
- init_waitqueue_head(&tp->wait_q);
-}
-
-static inline void tpm_private_free(void)
-{
- tpmif_free_tx_buffers(my_priv);
- kfree(my_priv);
- my_priv = NULL;
-}
-
-static struct tpm_private *tpm_private_get(void)
-{
- int err;
- if (!my_priv) {
- my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
- if (my_priv) {
- tpm_private_init(my_priv);
- err = tpmif_allocate_tx_buffers(my_priv);
- if (err < 0) {
- tpm_private_free();
- }
- }
- }
- return my_priv;
-}
-
-/**************************************************************
-
- The interface to let the tpm plugin register its callback
- function and send data to another partition using this module
-
-**************************************************************/
-
-static DEFINE_MUTEX(upperlayer_lock);
-static DEFINE_MUTEX(suspend_lock);
-static struct tpmfe_device *upperlayer_tpmfe;
-
-/*
- * Send data via this module by calling this function
- */
-int tpm_fe_send(struct tpm_private *tp, const u8 * buf, size_t count, void *ptr)
-{
- int sent;
-
- mutex_lock(&suspend_lock);
- sent = tpm_xmit(tp, buf, count, 0, ptr);
- mutex_unlock(&suspend_lock);
-
- return sent;
-}
-EXPORT_SYMBOL(tpm_fe_send);
-
-/*
- * Register a callback for receiving data from this module
- */
-int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
-{
- int rc = 0;
-
- mutex_lock(&upperlayer_lock);
- if (NULL == upperlayer_tpmfe) {
- upperlayer_tpmfe = tpmfe_dev;
- tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
- tpmfe_dev->tpm_private = tpm_private_get();
- if (!tpmfe_dev->tpm_private) {
- rc = -ENOMEM;
- }
- } else {
- rc = -EBUSY;
- }
- mutex_unlock(&upperlayer_lock);
- return rc;
-}
-EXPORT_SYMBOL(tpm_fe_register_receiver);
-
-/*
- * Unregister the callback for receiving data from this module
- */
-void tpm_fe_unregister_receiver(void)
-{
- mutex_lock(&upperlayer_lock);
- upperlayer_tpmfe = NULL;
- mutex_unlock(&upperlayer_lock);
-}
-EXPORT_SYMBOL(tpm_fe_unregister_receiver);
-
-/*
- * Call this function to send data to the upper layer's
- * registered receiver function.
- */
-static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
- const void *ptr)
-{
- int rc = 0;
-
- mutex_lock(&upperlayer_lock);
-
- if (upperlayer_tpmfe && upperlayer_tpmfe->receive)
- rc = upperlayer_tpmfe->receive(buf, count, ptr);
-
- mutex_unlock(&upperlayer_lock);
- return rc;
-}
-
-/**************************************************************
- XENBUS support code
-**************************************************************/
-
-static int setup_tpmring(struct xenbus_device *dev,
- struct tpm_private *tp)
-{
- tpmif_tx_interface_t *sring;
- int err;
-
- tp->ring_ref = GRANT_INVALID_REF;
-
- sring = (void *)__get_free_page(GFP_KERNEL);
- if (!sring) {
- xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
- return -ENOMEM;
- }
- tp->tx = sring;
-
- err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
- if (err < 0) {
- free_page((unsigned long)sring);
- tp->tx = NULL;
- xenbus_dev_fatal(dev, err, "allocating grant reference");
- goto fail;
- }
- tp->ring_ref = err;
-
- err = tpmif_connect(dev, tp, dev->otherend_id);
- if (err)
- goto fail;
-
- return 0;
-fail:
- destroy_tpmring(tp);
- return err;
-}
-
-
-static void destroy_tpmring(struct tpm_private *tp)
-{
- tpmif_set_connected_state(tp, 0);
-
- if (tp->ring_ref != GRANT_INVALID_REF) {
- gnttab_end_foreign_access(tp->ring_ref, 0,
- (unsigned long)tp->tx);
- tp->ring_ref = GRANT_INVALID_REF;
- tp->tx = NULL;
- }
-
- if (tp->irq)
- unbind_from_irqhandler(tp->irq, tp);
-
- tp->evtchn = tp->irq = 0;
-}
-
-
-static int talk_to_backend(struct xenbus_device *dev,
- struct tpm_private *tp)
-{
- const char *message = NULL;
- int err;
- xenbus_transaction_t xbt;
-
- err = setup_tpmring(dev, tp);
- if (err) {
- xenbus_dev_fatal(dev, err, "setting up ring");
- goto out;
- }
-
-again:
- err = xenbus_transaction_start(&xbt);
- if (err) {
- xenbus_dev_fatal(dev, err, "starting transaction");
- goto destroy_tpmring;
- }
-
- err = xenbus_printf(xbt, dev->nodename,
- "ring-ref","%u", tp->ring_ref);
- if (err) {
- message = "writing ring-ref";
- goto abort_transaction;
- }
-
- err = xenbus_printf(xbt, dev->nodename,
- "event-channel", "%u", tp->evtchn);
- if (err) {
- message = "writing event-channel";
- goto abort_transaction;
- }
-
- err = xenbus_transaction_end(xbt, 0);
- if (err == -EAGAIN)
- goto again;
- if (err) {
- xenbus_dev_fatal(dev, err, "completing transaction");
- goto destroy_tpmring;
- }
-
- xenbus_switch_state(dev, XenbusStateConnected);
-
- return 0;
-
-abort_transaction:
- xenbus_transaction_end(xbt, 1);
- if (message)
- xenbus_dev_error(dev, err, "%s", message);
-destroy_tpmring:
- destroy_tpmring(tp);
-out:
- return err;
-}
-
-/**
- * Callback received when the backend's state changes.
- */
-static void backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
-{
- struct tpm_private *tp = dev->data;
- DPRINTK("\n");
-
- switch (backend_state) {
- case XenbusStateInitialising:
- case XenbusStateInitWait:
- case XenbusStateInitialised:
- case XenbusStateUnknown:
- break;
-
- case XenbusStateConnected:
- tpmif_set_connected_state(tp, 1);
- break;
-
- case XenbusStateClosing:
- tpmif_set_connected_state(tp, 0);
- break;
-
- case XenbusStateClosed:
- if (tp->is_suspended == 0) {
- device_unregister(&dev->dev);
- }
- xenbus_switch_state(dev, XenbusStateClosed);
- break;
- }
-}
-
-
-static int tpmfront_probe(struct xenbus_device *dev,
- const struct xenbus_device_id *id)
-{
- int err;
- int handle;
- struct tpm_private *tp = tpm_private_get();
-
- if (!tp)
- return -ENOMEM;
-
- err = xenbus_scanf(XBT_NULL, dev->nodename,
- "handle", "%i", &handle);
- if (XENBUS_EXIST_ERR(err))
- return err;
-
- if (err < 0) {
- xenbus_dev_fatal(dev,err,"reading virtual-device");
- return err;
- }
-
- tp->dev = dev;
- dev->data = tp;
-
- err = talk_to_backend(dev, tp);
- if (err) {
- tpm_private_free();
- dev->data = NULL;
- return err;
- }
- return 0;
-}
-
-
-static int tpmfront_remove(struct xenbus_device *dev)
-{
- struct tpm_private *tp = (struct tpm_private *)dev->data;
- destroy_tpmring(tp);
- return 0;
-}
-
-static int tpmfront_suspend(struct xenbus_device *dev)
-{
- struct tpm_private *tp = (struct tpm_private *)dev->data;
- u32 ctr;
-
- /* lock, so no app can send */
- mutex_lock(&suspend_lock);
- xenbus_switch_state(dev, XenbusStateClosed);
- tp->is_suspended = 1;
-
- for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
- if ((ctr % 10) == 0)
- printk("TPM-FE [INFO]: Waiting for outstanding request.\n");
- /*
- * Wait for a request to be responded to.
- */
- interruptible_sleep_on_timeout(&tp->wait_q, 100);
- }
-
- if (atomic_read(&tp->tx_busy)) {
- /*
- * A temporary work-around.
- */
- printk("TPM-FE [WARNING]: Resetting busy flag.");
- atomic_set(&tp->tx_busy, 0);
- }
-
- return 0;
-}
-
-static int tpmfront_resume(struct xenbus_device *dev)
-{
- struct tpm_private *tp = (struct tpm_private *)dev->data;
- destroy_tpmring(tp);
- return talk_to_backend(dev, tp);
-}
-
-static int tpmif_connect(struct xenbus_device *dev,
- struct tpm_private *tp,
- domid_t domid)
-{
- int err;
-
- tp->backend_id = domid;
-
- err = xenbus_alloc_evtchn(dev, &tp->evtchn);
- if (err)
- return err;
-
- err = bind_evtchn_to_irqhandler(tp->evtchn,
- tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
- tp);
- if (err <= 0) {
- WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
- return err;
- }
-
- tp->irq = err;
- return 0;
-}
-
-static struct xenbus_device_id tpmfront_ids[] = {
- { "vtpm" },
- { "" }
-};
-
-static struct xenbus_driver tpmfront = {
- .name = "vtpm",
- .owner = THIS_MODULE,
- .ids = tpmfront_ids,
- .probe = tpmfront_probe,
- .remove = tpmfront_remove,
- .resume = tpmfront_resume,
- .otherend_changed = backend_changed,
- .suspend = tpmfront_suspend,
-};
-
-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;
-
- for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
- tp->tx_buffers[i] = tx_buffer_alloc();
- if (!tp->tx_buffers[i]) {
- tpmif_free_tx_buffers(tp);
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static void tpmif_free_tx_buffers(struct tpm_private *tp)
-{
- unsigned int i;
-
- for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
- tx_buffer_free(tp->tx_buffers[i]);
- }
-}
-
-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;
-
- received = tx->size;
-
- buffer = kmalloc(received, GFP_KERNEL);
- if (NULL == buffer) {
- goto exit;
- }
-
- for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
- struct tx_buffer *txb = tp->tx_buffers[i];
- tpmif_tx_request_t *tx;
- unsigned int tocopy;
-
- tx = &tp->tx->ring[i].req;
- tocopy = tx->size;
- if (tocopy > PAGE_SIZE) {
- tocopy = PAGE_SIZE;
- }
-
- memcpy(&buffer[offset], txb->data, tocopy);
-
- gnttab_release_grant_reference(&gref_head, tx->ref);
-
- offset += tocopy;
- }
-
- tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
- kfree(buffer);
-
-exit:
- atomic_set(&tp->tx_busy, 0);
- wake_up_interruptible(&tp->wait_q);
-}
-
-
-static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
-{
- struct tpm_private *tp = tpm_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&tp->tx_lock, flags);
- tpmif_rx_tasklet.data = (unsigned long)tp;
- tasklet_schedule(&tpmif_rx_tasklet);
- spin_unlock_irqrestore(&tp->tx_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-
-static int tpm_xmit(struct tpm_private *tp,
- const u8 * buf, size_t count, int isuserbuffer,
- void *remember)
-{
- tpmif_tx_request_t *tx;
- TPMIF_RING_IDX i;
- unsigned int offset = 0;
-
- spin_lock_irq(&tp->tx_lock);
-
- if (unlikely(atomic_read(&tp->tx_busy))) {
- printk("tpm_xmit: There's an outstanding request/response "
- "on the way!\n");
- spin_unlock_irq(&tp->tx_lock);
- return -EBUSY;
- }
-
- if (tp->is_connected != 1) {
- spin_unlock_irq(&tp->tx_lock);
- return -EIO;
- }
-
- for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
- struct tx_buffer *txb = tp->tx_buffers[i];
- int copied;
-
- if (NULL == txb) {
- DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
- "Not transmitting anything!\n", i);
- spin_unlock_irq(&tp->tx_lock);
- return -EFAULT;
- }
- copied = tx_buffer_copy(txb, &buf[offset], count,
- isuserbuffer);
- if (copied < 0) {
- /* An error occurred */
- spin_unlock_irq(&tp->tx_lock);
- return copied;
- }
- count -= copied;
- offset += copied;
-
- tx = &tp->tx->ring[i].req;
-
- tx->addr = virt_to_machine(txb->data);
- tx->size = txb->len;
-
- DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
- txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
-
- /* get the granttable reference for this page */
- tx->ref = gnttab_claim_grant_reference(&gref_head);
-
- if (-ENOSPC == tx->ref) {
- spin_unlock_irq(&tp->tx_lock);
- DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
- return -ENOSPC;
- }
- gnttab_grant_foreign_access_ref( tx->ref,
- tp->backend_id,
- (tx->addr >> PAGE_SHIFT),
- 0 /*RW*/);
- wmb();
- }
-
- atomic_set(&tp->tx_busy, 1);
- tp->tx_remember = remember;
- mb();
-
- DPRINTK("Notifying backend via event channel %d\n",
- tp->evtchn);
-
- notify_remote_via_irq(tp->irq);
-
- spin_unlock_irq(&tp->tx_lock);
- return offset;
-}
-
-
-static void tpmif_notify_upperlayer(struct tpm_private *tp)
-{
- /*
- * Notify upper layer about the state of the connection
- * to the BE.
- */
- mutex_lock(&upperlayer_lock);
-
- if (upperlayer_tpmfe != NULL) {
- if (tp->is_connected) {
- upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
- } else {
- upperlayer_tpmfe->status(0);
- }
- }
- mutex_unlock(&upperlayer_lock);
-}
-
-
-static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
-{
- /*
- * Don't notify upper layer if we are in suspend mode and
- * should disconnect - assumption is that we will resume
- * The mutex keeps apps from sending.
- */
- if (is_connected == 0 && tp->is_suspended == 1) {
- return;
- }
-
- /*
- * Unlock the mutex if we are connected again
- * after being suspended - now resuming.
- * This also removes the suspend state.
- */
- if (is_connected == 1 && tp->is_suspended == 1) {
- tp->is_suspended = 0;
- /* unlock, so apps can resume sending */
- mutex_unlock(&suspend_lock);
- }
-
- if (is_connected != tp->is_connected) {
- tp->is_connected = is_connected;
- tpmif_notify_upperlayer(tp);
- }
-}
-
-
-/* =================================================================
- * Initialization function.
- * =================================================================
- */
-
-static int __init tpmif_init(void)
-{
- IPRINTK("Initialising the vTPM driver.\n");
- if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
- &gref_head ) < 0) {
- return -EFAULT;
- }
-
- init_tpm_xenbus();
-
- return 0;
-}
-
-module_init(tpmif_init);
-
-static void __exit tpmif_exit(void)
-{
- exit_tpm_xenbus();
- gnttab_free_grant_references(gref_head);
-}
-
-module_exit(tpmif_exit);
-
-MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#ifndef TPM_FRONT_H
-#define TPM_FRONT_H
-
-struct tpm_private {
- tpmif_tx_interface_t *tx;
- unsigned int evtchn;
- unsigned int irq;
- u8 is_connected;
- u8 is_suspended;
-
- spinlock_t tx_lock;
-
- struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
-
- atomic_t tx_busy;
- void *tx_remember;
- domid_t backend_id;
- wait_queue_head_t wait_q;
-
- struct xenbus_device *dev;
- int ring_ref;
-};
-
-struct tx_buffer {
- unsigned int size; // available space in data
- unsigned int len; // used space in data
- unsigned char *data; // pointer to a page
-};
-
-#endif
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r 707737b66f58 -r 5d9eb92e63e2 linux-2.6-xen-sparse/include/xen/tpmfe.h
--- a/linux-2.6-xen-sparse/include/xen/tpmfe.h Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#ifndef TPM_FE_H
-#define TPM_FE_H
-
-struct tpm_private;
-
-struct tpmfe_device {
- /*
- * Let upper layer receive data from front-end
- */
- int (*receive)(const u8 *buffer, size_t count, const void *ptr);
- /*
- * Indicate the status of the front-end to the upper
- * layer.
- */
- void (*status)(unsigned int flags);
-
- /*
- * This field indicates the maximum size the driver can
- * transfer in one chunk. It is filled out by the front-end
- * driver and should be propagated to the generic tpm driver
- * for allocation of buffers.
- */
- unsigned int max_tx_size;
- /*
- * The following is a private structure of the underlying
- * driver. It's expected as first parameter in the send function.
- */
- struct tpm_private *tpm_private;
-};
-
-enum {
- TPMFE_STATUS_DISCONNECTED = 0x0,
- TPMFE_STATUS_CONNECTED = 0x1
-};
-
-int tpm_fe_send(struct tpm_private * tp, const u8 * buf, size_t count, void *ptr);
-int tpm_fe_register_receiver(struct tpmfe_device *);
-void tpm_fe_unregister_receiver(void);
-
-#endif
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/device_bind.patch
--- a/patches/linux-2.6.16/device_bind.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
---- linux-2.6.16/drivers/base/bus.c 2006-03-16 10:50:20.000000000 -0500
-+++ linux-2.6.16/drivers/base/bus.c 2006-03-16 11:02:08.000000000 -0500
-@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
- up(&dev->sem);
- if (dev->parent)
- up(&dev->parent->sem);
-+
-+ if (err > 0) /* success */
-+ err = count;
-+ else if (err == 0) /* driver didn't accept device */
-+ err = -ENODEV;
- }
- put_device(dev);
- put_bus(bus);
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/i386-mach-io-check-nmi.patch
--- a/patches/linux-2.6.16/i386-mach-io-check-nmi.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
---- ../pristine-linux-2.6.16/arch/i386/kernel/traps.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/kernel/traps.c 2006-03-20 19:38:17.000000000 +0000
-@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
-
- static void io_check_error(unsigned char reason, struct pt_regs * regs)
- {
-- unsigned long i;
--
- printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
- show_registers(regs);
-
- /* Re-enable the IOCK line, wait for a few seconds */
-- reason = (reason & 0xf) | 8;
-- outb(reason, 0x61);
-- i = 2000;
-- while (--i) udelay(1000);
-- reason &= ~8;
-- outb(reason, 0x61);
-+ clear_io_check_error(reason);
- }
-
- static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
---- ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/mach-default/mach_traps.h 2006-03-20 19:38:17.000000000 +0000
-@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
- outb(reason, 0x61);
- }
-
-+static inline void clear_io_check_error(unsigned char reason)
-+{
-+ unsigned long i;
-+
-+ reason = (reason & 0xf) | 8;
-+ outb(reason, 0x61);
-+ i = 2000;
-+ while (--i) udelay(1000);
-+ reason &= ~8;
-+ outb(reason, 0x61);
-+}
-+
- static inline unsigned char get_nmi_reason(void)
- {
- return inb(0x61);
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/net-csum.patch
--- a/patches/linux-2.6.16/net-csum.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-03-20 19:38:19.000000000 +0000
-@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
- if (hdrsize < sizeof(*hdr))
- return 1;
-
-- hdr->check = ip_nat_cheat_check(~oldip, newip,
-+ if ((*pskb)->proto_csum_blank) {
-+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+ } else {
-+ hdr->check = ip_nat_cheat_check(~oldip, newip,
- ip_nat_cheat_check(oldport ^ 0xFFFF,
- newport,
- hdr->check));
-+ }
- return 1;
- }
-
-diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-03-20 19:38:19.000000000 +0000
-@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
- newport = tuple->dst.u.udp.port;
- portptr = &hdr->dest;
- }
-- if (hdr->check) /* 0 is a special case meaning no checksum */
-- hdr->check = ip_nat_cheat_check(~oldip, newip,
-+ if (hdr->check) { /* 0 is a special case meaning no checksum */
-+ if ((*pskb)->proto_csum_blank) {
-+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+ } else {
-+ hdr->check = ip_nat_cheat_check(~oldip, newip,
- ip_nat_cheat_check(*portptr ^ 0xFFFF,
- newport,
- hdr->check));
-+ }
-+ }
- *portptr = newport;
- return 1;
- }
-diff -r 601fa226a761 net/ipv4/xfrm4_output.c
---- a/net/ipv4/xfrm4_output.c Wed Apr 19 18:52:30 2006
-+++ b/net/ipv4/xfrm4_output.c Thu Apr 20 15:49:40 2006
-@@ -16,6 +16,8 @@
- #include <net/ip.h>
- #include <net/xfrm.h>
- #include <net/icmp.h>
-+
-+extern int skb_checksum_setup(struct sk_buff *skb);
-
- /* Add encapsulation header.
- *
-@@ -103,6 +105,10 @@
- struct xfrm_state *x = dst->xfrm;
- int err;
-
-+ err = skb_checksum_setup(skb);
-+ if (err)
-+ goto error_nolock;
-+
- if (skb->ip_summed == CHECKSUM_HW) {
- err = skb_checksum_help(skb, 0);
- if (err)
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/pmd-shared.patch
--- a/patches/linux-2.6.16/pmd-shared.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
---- ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/mm/pageattr.c 2006-03-20 19:38:23.000000000 +0000
-@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
- unsigned long flags;
-
- set_pte_atomic(kpte, pte); /* change init_mm */
-- if (PTRS_PER_PMD > 1)
-+ if (HAVE_SHARED_KERNEL_PMD)
- return;
-
- spin_lock_irqsave(&pgd_lock, flags);
-diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
---- ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/mm/pgtable.c 2006-03-20 19:38:23.000000000 +0000
-@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
- spin_lock_irqsave(&pgd_lock, flags);
- }
-
-- clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-- swapper_pg_dir + USER_PTRS_PER_PGD,
-- KERNEL_PGD_PTRS);
-+ if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
-+ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-+ swapper_pg_dir + USER_PTRS_PER_PGD,
-+ KERNEL_PGD_PTRS);
- if (PTRS_PER_PMD > 1)
- return;
-
-@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
- goto out_oom;
- set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
- }
-+
-+ if (!HAVE_SHARED_KERNEL_PMD) {
-+ unsigned long flags;
-+
-+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+ pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+ if (!pmd)
-+ goto out_oom;
-+ set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
-+ }
-+
-+ spin_lock_irqsave(&pgd_lock, flags);
-+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+ unsigned long v = (unsigned long)i << PGDIR_SHIFT;
-+ pgd_t *kpgd = pgd_offset_k(v);
-+ pud_t *kpud = pud_offset(kpgd, v);
-+ pmd_t *kpmd = pmd_offset(kpud, v);
-+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+ memcpy(pmd, kpmd, PAGE_SIZE);
-+ }
-+ pgd_list_add(pgd);
-+ spin_unlock_irqrestore(&pgd_lock, flags);
-+ }
-+
- return pgd;
-
- out_oom:
-@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
- int i;
-
- /* in the PAE case user pgd entries are overwritten before usage */
-- if (PTRS_PER_PMD > 1)
-- for (i = 0; i < USER_PTRS_PER_PGD; ++i)
-- kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
-+ if (PTRS_PER_PMD > 1) {
-+ for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+ kmem_cache_free(pmd_cache, pmd);
-+ }
-+ if (!HAVE_SHARED_KERNEL_PMD) {
-+ unsigned long flags;
-+ spin_lock_irqsave(&pgd_lock, flags);
-+ pgd_list_del(pgd);
-+ spin_unlock_irqrestore(&pgd_lock, flags);
-+ for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+ pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+ memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
-+ kmem_cache_free(pmd_cache, pmd);
-+ }
-+ }
-+ }
- /* in the non-PAE case, free_pgtables() clears user pgd entries */
- kmem_cache_free(pgd_cache, pgd);
- }
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/pgtable-2level-defs.h 2006-03-20 19:38:23.000000000 +0000
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
- #define _I386_PGTABLE_2LEVEL_DEFS_H
-
-+#define HAVE_SHARED_KERNEL_PMD 0
-+
- /*
- * traditional i386 two-level paging structure:
- */
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/pgtable-3level-defs.h 2006-03-20 19:38:23.000000000 +0000
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
- #define _I386_PGTABLE_3LEVEL_DEFS_H
-
-+#define HAVE_SHARED_KERNEL_PMD 1
-+
- /*
- * PGDIR_SHIFT determines what a top-level page table entry can map
- */
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
--- a/patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-Index: sysenter/linux-2.6-xen-sparse/arch/i386/kernel/entry.S
-===================================================================
---- linux-2.6.16.orig/arch/i386/kernel/entry.S 2006-04-05 11:12:51.000000000 +0100
-+++ linux-2.6.16/arch/i386/kernel/entry.S 2006-04-05 11:12:52.000000000 +0100
-@@ -177,7 +177,7 @@
-
- # sysenter call handler stub
- ENTRY(sysenter_entry)
-- movl TSS_sysenter_esp0(%esp),%esp
-+ movl SYSENTER_stack_esp0(%esp),%esp
- sysenter_past_esp:
- sti
- pushl $(__USER_DS)
-@@ -492,7 +492,7 @@
- * that sets up the real kernel stack. Check here, since we can't
- * allow the wrong stack to be used.
- *
-- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
-+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
- * already pushed 3 words if it hits on the sysenter instruction:
- * eflags, cs and eip.
- *
-@@ -504,7 +504,7 @@
- cmpw $__KERNEL_CS,4(%esp); \
- jne ok; \
- label: \
-- movl TSS_sysenter_esp0+offset(%esp),%esp; \
-+ movl SYSENTER_stack_esp0+offset(%esp),%esp; \
- pushfl; \
- pushl $__KERNEL_CS; \
- pushl $sysenter_past_esp
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/smp-alts.patch
--- a/patches/linux-2.6.16/smp-alts.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,591 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16/arch/i386/Kconfig ./arch/i386/Kconfig
---- ../pristine-linux-2.6.16/arch/i386/Kconfig 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/Kconfig 2006-03-20 19:38:27.000000000 +0000
-@@ -202,6 +202,19 @@ config SMP
-
- If you don't know what to do here, say N.
-
-+config SMP_ALTERNATIVES
-+ bool "SMP alternatives support (EXPERIMENTAL)"
-+ depends on SMP && EXPERIMENTAL
-+ help
-+ Try to reduce the overhead of running an SMP kernel on a uniprocessor
-+ host slightly by replacing certain key instruction sequences
-+ according to whether we currently have more than one CPU available.
-+ This should provide a noticeable boost to performance when
-+ running SMP kernels on UP machines, and have negligible impact
-+ when running on an true SMP host.
-+
-+ If unsure, say N.
-+
- config NR_CPUS
- int "Maximum number of CPUs (2-255)"
- range 2 255
-diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
---- ../pristine-linux-2.6.16/arch/i386/kernel/Makefile 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/kernel/Makefile 2006-03-20 19:38:27.000000000 +0000
-@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o
- obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
- obj-$(CONFIG_VM86) += vm86.o
- obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-+obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o
-
- EXTRA_AFLAGS := -traditional
-
-diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
---- ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c 1970-01-01 01:00:00.000000000 +0100
-+++ ./arch/i386/kernel/smpalts.c 2006-03-20 19:38:27.000000000 +0000
-@@ -0,0 +1,85 @@
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+#include <asm/smp_alt.h>
-+#include <asm/processor.h>
-+#include <asm/string.h>
-+
-+struct smp_replacement_record {
-+ unsigned char targ_size;
-+ unsigned char smp1_size;
-+ unsigned char smp2_size;
-+ unsigned char up_size;
-+ unsigned char feature;
-+ unsigned char data[0];
-+};
-+
-+struct smp_alternative_record {
-+ void *targ_start;
-+ struct smp_replacement_record *repl;
-+};
-+
-+extern struct smp_alternative_record __start_smp_alternatives_table,
-+ __stop_smp_alternatives_table;
-+extern unsigned long __init_begin, __init_end;
-+
-+void prepare_for_smp(void)
-+{
-+ struct smp_alternative_record *r;
-+ printk(KERN_INFO "Enabling SMP...\n");
-+ for (r = &__start_smp_alternatives_table;
-+ r != &__stop_smp_alternatives_table;
-+ r++) {
-+ BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+ BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+ BUG_ON(r->repl->targ_size < r->repl->up_size);
-+ if (system_state == SYSTEM_RUNNING &&
-+ r->targ_start >= (void *)&__init_begin &&
-+ r->targ_start < (void *)&__init_end)
-+ continue;
-+ if (r->repl->feature != (unsigned char)-1 &&
-+ boot_cpu_has(r->repl->feature)) {
-+ memcpy(r->targ_start,
-+ r->repl->data + r->repl->smp1_size,
-+ r->repl->smp2_size);
-+ memset(r->targ_start + r->repl->smp2_size,
-+ 0x90,
-+ r->repl->targ_size - r->repl->smp2_size);
-+ } else {
-+ memcpy(r->targ_start,
-+ r->repl->data,
-+ r->repl->smp1_size);
-+ memset(r->targ_start + r->repl->smp1_size,
-+ 0x90,
-+ r->repl->targ_size - r->repl->smp1_size);
-+ }
-+ }
-+ /* Paranoia */
-+ asm volatile ("jmp 1f\n1:");
-+ mb();
-+}
-+
-+void unprepare_for_smp(void)
-+{
-+ struct smp_alternative_record *r;
-+ printk(KERN_INFO "Disabling SMP...\n");
-+ for (r = &__start_smp_alternatives_table;
-+ r != &__stop_smp_alternatives_table;
-+ r++) {
-+ BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+ BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+ BUG_ON(r->repl->targ_size < r->repl->up_size);
-+ if (system_state == SYSTEM_RUNNING &&
-+ r->targ_start >= (void *)&__init_begin &&
-+ r->targ_start < (void *)&__init_end)
-+ continue;
-+ memcpy(r->targ_start,
-+ r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
-+ r->repl->up_size);
-+ memset(r->targ_start + r->repl->up_size,
-+ 0x90,
-+ r->repl->targ_size - r->repl->up_size);
-+ }
-+ /* Paranoia */
-+ asm volatile ("jmp 1f\n1:");
-+ mb();
-+}
-diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
---- ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/kernel/smpboot.c 2006-03-20 19:38:27.000000000 +0000
-@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
- if (max_cpus <= cpucount+1)
- continue;
-
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+ if (kicked == 1)
-+ prepare_for_smp();
-+#endif
-+
- if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
- printk("CPU #%d not responding - cannot use it.\n",
- apicid);
-@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
- return -EIO;
- }
-
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+ if (num_online_cpus() == 1)
-+ prepare_for_smp();
-+#endif
-+
- local_irq_enable();
- per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
- /* Unleash the CPU! */
-diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
---- ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S 2006-03-20 05:53:29.000000000 +0000
-+++ ./arch/i386/kernel/vmlinux.lds.S 2006-03-20 19:38:27.000000000 +0000
-@@ -34,6 +34,13 @@ SECTIONS
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
- __stop___ex_table = .;
-
-+ . = ALIGN(16);
-+ __start_smp_alternatives_table = .;
-+ __smp_alternatives : { *(__smp_alternatives) }
-+ __stop_smp_alternatives_table = .;
-+
-+ __smp_replacements : { *(__smp_replacements) }
-+
- RODATA
-
- /* writeable */
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
---- ../pristine-linux-2.6.16/include/asm-i386/atomic.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/atomic.h 2006-03-20 19:38:27.000000000 +0000
-@@ -4,18 +4,13 @@
- #include <linux/config.h>
- #include <linux/compiler.h>
- #include <asm/processor.h>
-+#include <asm/smp_alt.h>
-
- /*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- */
-
--#ifdef CONFIG_SMP
--#define LOCK "lock ; "
--#else
--#define LOCK ""
--#endif
--
- /*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
---- ../pristine-linux-2.6.16/include/asm-i386/bitops.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/bitops.h 2006-03-20 19:38:27.000000000 +0000
-@@ -7,6 +7,7 @@
-
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
-
- /*
- * These have to be done with inline assembly: that way the bit-setting
-@@ -16,12 +17,6 @@
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-
--#ifdef CONFIG_SMP
--#define LOCK_PREFIX "lock ; "
--#else
--#define LOCK_PREFIX ""
--#endif
--
- #define ADDR (*(volatile long *) addr)
-
- /**
-@@ -41,7 +36,7 @@
- */
- static inline void set_bit(int nr, volatile unsigned long * addr)
- {
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btsl %1,%0"
- :"+m" (ADDR)
- :"Ir" (nr));
-@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
- */
- static inline void clear_bit(int nr, volatile unsigned long * addr)
- {
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btrl %1,%0"
- :"+m" (ADDR)
- :"Ir" (nr));
-@@ -121,7 +116,7 @@ static inline void __change_bit(int nr,
- */
- static inline void change_bit(int nr, volatile unsigned long * addr)
- {
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btcl %1,%0"
- :"+m" (ADDR)
- :"Ir" (nr));
-@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
- {
- int oldbit;
-
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
- :"Ir" (nr) : "memory");
-@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
- {
- int oldbit;
-
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
- :"Ir" (nr) : "memory");
-@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
- {
- int oldbit;
-
-- __asm__ __volatile__( LOCK_PREFIX
-+ __asm__ __volatile__( LOCK
- "btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
- :"Ir" (nr) : "memory");
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/futex.h ./include/asm-i386/futex.h
---- ../pristine-linux-2.6.16/include/asm-i386/futex.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/futex.h 2006-03-20 19:38:27.000000000 +0000
-@@ -28,7 +28,7 @@
- "1: movl %2, %0\n\
- movl %0, %3\n" \
- insn "\n" \
--"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2: " LOCK "cmpxchgl %3, %2\n\
- jnz 1b\n\
- 3: .section .fixup,\"ax\"\n\
- 4: mov %5, %1\n\
-@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op,
- #endif
- switch (op) {
- case FUTEX_OP_ADD:
-- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
-+ __futex_atomic_op1(LOCK "xaddl %0, %2", ret,
- oldval, uaddr, oparg);
- break;
- case FUTEX_OP_OR:
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
---- ../pristine-linux-2.6.16/include/asm-i386/rwsem.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/rwsem.h 2006-03-20 19:38:27.000000000 +0000
-@@ -40,6 +40,7 @@
-
- #include <linux/list.h>
- #include <linux/spinlock.h>
-+#include <asm/smp_alt.h>
-
- struct rwsem_waiter;
-
-@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
- {
- __asm__ __volatile__(
- "# beginning down_read\n\t"
--LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */
-+LOCK " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */
- " js 2f\n\t" /* jump if we weren't granted the lock */
- "1:\n\t"
- LOCK_SECTION_START("")
-@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
- " movl %1,%2\n\t"
- " addl %3,%2\n\t"
- " jle 2f\n\t"
--LOCK_PREFIX " cmpxchgl %2,%0\n\t"
-+LOCK " cmpxchgl %2,%0\n\t"
- " jnz 1b\n\t"
- "2:\n\t"
- "# ending __down_read_trylock\n\t"
-@@ -150,7 +151,7 @@ static inline void __down_write(struct r
- tmp = RWSEM_ACTIVE_WRITE_BIAS;
- __asm__ __volatile__(
- "# beginning down_write\n\t"
--LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
-+LOCK " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
- " testl %%edx,%%edx\n\t" /* was the count 0 before? */
- " jnz 2f\n\t" /* jump if we weren't granted the lock */
- "1:\n\t"
-@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
- __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
- __asm__ __volatile__(
- "# beginning __up_read\n\t"
--LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
-+LOCK " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
- " js 2f\n\t" /* jump if the lock is being waited upon */
- "1:\n\t"
- LOCK_SECTION_START("")
-@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
- __asm__ __volatile__(
- "# beginning __up_write\n\t"
- " movl %2,%%edx\n\t"
--LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
-+LOCK " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
- " jnz 2f\n\t" /* jump if the lock is being waited upon */
- "1:\n\t"
- LOCK_SECTION_START("")
-@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
- {
- __asm__ __volatile__(
- "# beginning __downgrade_write\n\t"
--LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
-+LOCK " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
- " js 2f\n\t" /* jump if the lock is being waited upon */
- "1:\n\t"
- LOCK_SECTION_START("")
-@@ -263,7 +264,7 @@ LOCK_PREFIX " addl %2,(%%eax)\n\t"
- static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
- {
- __asm__ __volatile__(
--LOCK_PREFIX "addl %1,%0"
-+LOCK "addl %1,%0"
- : "=m"(sem->count)
- : "ir"(delta), "m"(sem->count));
- }
-@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
- int tmp = delta;
-
- __asm__ __volatile__(
--LOCK_PREFIX "xadd %0,(%2)"
-+LOCK "xadd %0,(%2)"
- : "+r"(tmp), "=m"(sem->count)
- : "r"(sem), "m"(sem->count)
- : "memory");
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
---- ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h 1970-01-01 01:00:00.000000000 +0100
-+++ ./include/asm-i386/smp_alt.h 2006-03-20 19:38:27.000000000 +0000
-@@ -0,0 +1,32 @@
-+#ifndef __ASM_SMP_ALT_H__
-+#define __ASM_SMP_ALT_H__
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define LOCK \
-+ "6677: nop\n" \
-+ ".section __smp_alternatives,\"a\"\n" \
-+ ".long 6677b\n" \
-+ ".long 6678f\n" \
-+ ".previous\n" \
-+ ".section __smp_replacements,\"a\"\n" \
-+ "6678: .byte 1\n" \
-+ ".byte 1\n" \
-+ ".byte 0\n" \
-+ ".byte 1\n" \
-+ ".byte -1\n" \
-+ "lock\n" \
-+ "nop\n" \
-+ ".previous\n"
-+void prepare_for_smp(void);
-+void unprepare_for_smp(void);
-+#else
-+#define LOCK "lock ; "
-+#endif
-+#else
-+#define LOCK ""
-+#endif
-+
-+#endif /* __ASM_SMP_ALT_H__ */
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
---- ../pristine-linux-2.6.16/include/asm-i386/spinlock.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/spinlock.h 2006-03-20 19:38:27.000000000 +0000
-@@ -6,6 +6,7 @@
- #include <asm/page.h>
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
-
- /*
- * Your basic SMP spinlocks, allowing only a single CPU anywhere
-@@ -23,7 +24,8 @@
-
- #define __raw_spin_lock_string \
- "\n1:\t" \
-- "lock ; decb %0\n\t" \
-+ LOCK \
-+ "decb %0\n\t" \
- "jns 3f\n" \
- "2:\t" \
- "rep;nop\n\t" \
-@@ -34,7 +36,8 @@
-
- #define __raw_spin_lock_string_flags \
- "\n1:\t" \
-- "lock ; decb %0\n\t" \
-+ LOCK \
-+ "decb %0\n\t" \
- "jns 4f\n\t" \
- "2:\t" \
- "testl $0x200, %1\n\t" \
-@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
- static inline int __raw_spin_trylock(raw_spinlock_t *lock)
- {
- char oldval;
-+#ifdef CONFIG_SMP_ALTERNATIVES
- __asm__ __volatile__(
-- "xchgb %b0,%1"
-+ "1:movb %1,%b0\n"
-+ "movb $0,%1\n"
-+ "2:"
-+ ".section __smp_alternatives,\"a\"\n"
-+ ".long 1b\n"
-+ ".long 3f\n"
-+ ".previous\n"
-+ ".section __smp_replacements,\"a\"\n"
-+ "3: .byte 2b - 1b\n"
-+ ".byte 5f-4f\n"
-+ ".byte 0\n"
-+ ".byte 6f-5f\n"
-+ ".byte -1\n"
-+ "4: xchgb %b0,%1\n"
-+ "5: movb %1,%b0\n"
-+ "movb $0,%1\n"
-+ "6:\n"
-+ ".previous\n"
- :"=q" (oldval), "=m" (lock->slock)
- :"0" (0) : "memory");
-+#else
-+ __asm__ __volatile__(
-+ "xchgb %b0,%1\n"
-+ :"=q" (oldval), "=m" (lock->slock)
-+ :"0" (0) : "memory");
-+#endif
- return oldval > 0;
- }
-
-@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
-
- static inline void __raw_read_unlock(raw_rwlock_t *rw)
- {
-- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
-+ asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
- }
-
- static inline void __raw_write_unlock(raw_rwlock_t *rw)
- {
-- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
-+ asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
- : "=m" (rw->lock) : : "memory");
- }
-
-diff -pruN ../pristine-linux-2.6.16/include/asm-i386/system.h ./include/asm-i386/system.h
---- ../pristine-linux-2.6.16/include/asm-i386/system.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/asm-i386/system.h 2006-03-20 19:38:27.000000000 +0000
-@@ -5,7 +5,7 @@
- #include <linux/kernel.h>
- #include <asm/segment.h>
- #include <asm/cpufeature.h>
--#include <linux/bitops.h> /* for LOCK_PREFIX */
-+#include <asm/smp_alt.h>
-
- #ifdef __KERNEL__
-
-@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
- unsigned long prev;
- switch (size) {
- case 1:
-- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
-+ __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
-- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
-+ __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
-- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
-+ __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
-@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
- unsigned long long new)
- {
- unsigned long long prev;
-- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
-+ __asm__ __volatile__(LOCK "cmpxchg8b %3"
- : "=A"(prev)
- : "b"((unsigned long)new),
- "c"((unsigned long)(new >> 32)),
-@@ -503,11 +503,55 @@ struct alt_instr {
- #endif
-
- #ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define smp_alt_mb(instr) \
-+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
-+ ".section __smp_alternatives,\"a\"\n" \
-+ ".long 6667b\n" \
-+ ".long 6673f\n" \
-+ ".previous\n" \
-+ ".section __smp_replacements,\"a\"\n" \
-+ "6673:.byte 6668b-6667b\n" \
-+ ".byte 6670f-6669f\n" \
-+ ".byte 6671f-6670f\n" \
-+ ".byte 0\n" \
-+ ".byte %c0\n" \
-+ "6669:lock;addl $0,0(%%esp)\n" \
-+ "6670:" instr "\n" \
-+ "6671:\n" \
-+ ".previous\n" \
-+ : \
-+ : "i" (X86_FEATURE_XMM2) \
-+ : "memory")
-+#define smp_rmb() smp_alt_mb("lfence")
-+#define smp_mb() smp_alt_mb("mfence")
-+#define set_mb(var, value) do { \
-+unsigned long __set_mb_temp; \
-+__asm__ __volatile__("6667:movl %1, %0\n6668:\n" \
-+ ".section __smp_alternatives,\"a\"\n" \
-+ ".long 6667b\n" \
-+ ".long 6673f\n" \
-+ ".previous\n" \
-+ ".section __smp_replacements,\"a\"\n" \
-+ "6673: .byte 6668b-6667b\n" \
-+ ".byte 6670f-6669f\n" \
-+ ".byte 0\n" \
-+ ".byte 6671f-6670f\n" \
-+ ".byte -1\n" \
-+ "6669: xchg %1, %0\n" \
-+ "6670:movl %1, %0\n" \
-+ "6671:\n" \
-+ ".previous\n" \
-+ : "=m" (var), "=r" (__set_mb_temp) \
-+ : "1" (value) \
-+ : "memory"); } while (0)
-+#else
- #define smp_mb() mb()
- #define smp_rmb() rmb()
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#endif
- #define smp_wmb() wmb()
- #define smp_read_barrier_depends() read_barrier_depends()
--#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
- #else
- #define smp_mb() barrier()
- #define smp_rmb() barrier()
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch
--- a/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-Subject: Increase x86 interrupt vector range
-
-Remove the limit of 256 interrupt vectors by changing the value
-stored in orig_{e,r}ax to be the negated interrupt vector.
-The orig_{e,r}ax needs to be < 0 to allow the signal code to
-distinguish between return from interrupt and return from syscall.
-With this change applied, NR_IRQS can be > 256.
-
-Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
----
- arch/i386/kernel/entry.S | 4 ++--
- arch/i386/kernel/irq.c | 4 ++--
- arch/x86_64/kernel/entry.S | 2 +-
- arch/x86_64/kernel/irq.c | 4 ++--
- arch/x86_64/kernel/smp.c | 4 ++--
- include/asm-x86_64/hw_irq.h | 2 +-
- 6 files changed, 10 insertions(+), 10 deletions(-)
-
-diff -r 7d239c83edea arch/i386/kernel/entry.S
---- a/arch/i386/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
-+++ b/arch/i386/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
-@@ -406,7 +406,7 @@ ENTRY(irq_entries_start)
- ENTRY(irq_entries_start)
- .rept NR_IRQS
- ALIGN
--1: pushl $vector-256
-+1: pushl $~(vector)
- jmp common_interrupt
- .data
- .long 1b
-@@ -423,7 +423,7 @@ common_interrupt:
-
- #define BUILD_INTERRUPT(name, nr) \
- ENTRY(name) \
-- pushl $nr-256; \
-+ pushl $~(nr); \
- SAVE_ALL \
- movl %esp,%eax; \
- call smp_/**/name; \
-diff -r 7d239c83edea arch/i386/kernel/irq.c
---- a/arch/i386/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
-+++ b/arch/i386/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
-@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[.NR_CPU
- */
- fastcall unsigned int do_IRQ(struct pt_regs *regs)
- {
-- /* high bits used in ret_from_ code */
-- int irq = regs->orig_eax & 0xff;
-+ /* high bit used in ret_from_ code */
-+ int irq = ~regs->orig_eax;
- #ifdef CONFIG_4KSTACKS
- union irq_ctx *curctx, *irqctx;
- u32 *isp;
-diff -r 7d239c83edea arch/x86_64/kernel/entry.S
---- a/arch/x86_64/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
-+++ b/arch/x86_64/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
-@@ -609,7 +609,7 @@ retint_kernel:
- */
- .macro apicinterrupt num,func
- INTR_FRAME
-- pushq $\num-256
-+ pushq $~(\num)
- CFI_ADJUST_CFA_OFFSET 8
- interrupt \func
- jmp ret_from_intr
-diff -r 7d239c83edea arch/x86_64/kernel/irq.c
---- a/arch/x86_64/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
-+++ b/arch/x86_64/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
-@@ -96,8 +96,8 @@ skip:
- */
- asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
- {
-- /* high bits used in ret_from_ code */
-- unsigned irq = regs->orig_rax & 0xff;
-+ /* high bit used in ret_from_ code */
-+ unsigned irq = ~regs->orig_rax;
-
- exit_idle();
- irq_enter();
-diff -r 7d239c83edea arch/x86_64/kernel/smp.c
---- a/arch/x86_64/kernel/smp.c Mon Mar 20 06:00:20 2006 +0000
-+++ b/arch/x86_64/kernel/smp.c Fri Mar 31 17:01:35 2006 +0100
-@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
-
- cpu = smp_processor_id();
- /*
-- * orig_rax contains the interrupt vector - 256.
-+ * orig_rax contains the negated interrupt vector.
- * Use that to determine where the sender put the data.
- */
-- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
-+ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
- f = &per_cpu(flush_state, sender);
-
- if (!cpu_isset(cpu, f->flush_cpumask))
-diff -r 7d239c83edea include/asm-x86_64/hw_irq.h
---- a/include/asm-x86_64/hw_irq.h Mon Mar 20 06:00:20 2006 +0000
-+++ b/include/asm-x86_64/hw_irq.h Fri Mar 31 17:01:35 2006 +0100
-@@ -127,7 +127,7 @@ __asm__( \
- __asm__( \
- "\n.p2align\n" \
- "IRQ" #nr "_interrupt:\n\t" \
-- "push $" #nr "-256 ; " \
-+ "push $~(" #nr ") ; " \
- "jmp common_interrupt");
-
- #if defined(CONFIG_X86_IO_APIC)
diff -r 707737b66f58 -r 5d9eb92e63e2 patches/linux-2.6.16/xenoprof-generic.patch
--- a/patches/linux-2.6.16/xenoprof-generic.patch Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
---- ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/buffer_sync.c 2006-04-03 15:53:05.000000000 +0100
-@@ -6,6 +6,10 @@
- *
- * @author John Levon <levon@movementarian.org>
- *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
- * This is the core of the buffer management. Each
- * CPU buffer is processed and entered into the
- * global event buffer. Such processing is necessary
-@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
- last_cookie = INVALID_COOKIE;
- }
-
--static void add_kernel_ctx_switch(unsigned int in_kernel)
-+static void add_cpu_mode_switch(unsigned int cpu_mode)
- {
- add_event_entry(ESCAPE_CODE);
-- if (in_kernel)
-- add_event_entry(KERNEL_ENTER_SWITCH_CODE);
-- else
-- add_event_entry(KERNEL_EXIT_SWITCH_CODE);
-+ switch (cpu_mode) {
-+ case CPU_MODE_USER:
-+ add_event_entry(USER_ENTER_SWITCH_CODE);
-+ break;
-+ case CPU_MODE_KERNEL:
-+ add_event_entry(KERNEL_ENTER_SWITCH_CODE);
-+ break;
-+ case CPU_MODE_XEN:
-+ add_event_entry(XEN_ENTER_SWITCH_CODE);
-+ break;
-+ default:
-+ break;
-+ }
- }
--
-+
- static void
- add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
- {
-@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
- * for later lookup from userspace.
- */
- static int
--add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
-+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
- {
-- if (in_kernel) {
-+ if (cpu_mode >= CPU_MODE_KERNEL) {
- add_sample_entry(s->eip, s->event);
- return 1;
- } else if (mm) {
-@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
- struct mm_struct *mm = NULL;
- struct task_struct * new;
- unsigned long cookie = 0;
-- int in_kernel = 1;
-+ int cpu_mode = 1;
- unsigned int i;
- sync_buffer_state state = sb_buffer_start;
- unsigned long available;
-@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
- struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
-
- if (is_code(s->eip)) {
-- if (s->event <= CPU_IS_KERNEL) {
-+ if (s->event <= CPU_MODE_XEN) {
- /* kernel/userspace switch */
-- in_kernel = s->event;
-+ cpu_mode = s->event;
- if (state == sb_buffer_start)
- state = sb_sample_start;
-- add_kernel_ctx_switch(s->event);
-+ add_cpu_mode_switch(s->event);
- } else if (s->event == CPU_TRACE_BEGIN) {
- state = sb_bt_start;
- add_trace_begin();
-@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
- }
- } else {
- if (state >= sb_bt_start &&
-- !add_sample(mm, s, in_kernel)) {
-+ !add_sample(mm, s, cpu_mode)) {
- if (state == sb_bt_start) {
- state = sb_bt_ignore;
- atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/cpu_buffer.c 2006-04-03 15:53:05.000000000 +0100
-@@ -6,6 +6,10 @@
- *
- * @author John Levon <levon@movementarian.org>
- *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
- * Each CPU has a local buffer that stores PC value/event
- * pairs. We also log context switches when we notice them.
- * Eventually each CPU's buffer is processed into the global
-@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
- goto fail;
-
- b->last_task = NULL;
-- b->last_is_kernel = -1;
-+ b->last_cpu_mode = -1;
- b->tracing = 0;
- b->buffer_size = buffer_size;
- b->tail_pos = 0;
-@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
- * collected will populate the buffer with proper
- * values to initialize the buffer
- */
-- cpu_buf->last_is_kernel = -1;
-+ cpu_buf->last_cpu_mode = -1;
- cpu_buf->last_task = NULL;
- }
-
-@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
- * because of the head/tail separation of the writer and reader
- * of the CPU buffer.
- *
-- * is_kernel is needed because on some architectures you cannot
-+ * cpu_mode is needed because on some architectures you cannot
- * tell if you are in kernel or user space simply by looking at
-- * pc. We tag this in the buffer by generating kernel enter/exit
-- * events whenever is_kernel changes
-+ * pc. We tag this in the buffer by generating kernel/user (and xen)
-+ * enter events whenever cpu_mode changes
- */
- static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
-- int is_kernel, unsigned long event)
-+ int cpu_mode, unsigned long event)
- {
- struct task_struct * task;
-
-@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
- return 0;
- }
-
-- is_kernel = !!is_kernel;
-+ WARN_ON(cpu_mode > CPU_MODE_XEN);
-
- task = current;
-
- /* notice a switch from user->kernel or vice versa */
-- if (cpu_buf->last_is_kernel != is_kernel) {
-- cpu_buf->last_is_kernel = is_kernel;
-- add_code(cpu_buf, is_kernel);
-+ if (cpu_buf->last_cpu_mode != cpu_mode) {
-+ cpu_buf->last_cpu_mode = cpu_mode;
-+ add_code(cpu_buf, cpu_mode);
- }
--
-+
- /* notice a task switch */
- if (cpu_buf->last_task != task) {
- cpu_buf->last_task = task;
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/cpu_buffer.h 2006-04-03 15:53:05.000000000 +0100
-@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
- volatile unsigned long tail_pos;
- unsigned long buffer_size;
- struct task_struct * last_task;
-- int last_is_kernel;
-+ int last_cpu_mode;
- int tracing;
- struct op_sample * buffer;
- unsigned long sample_received;
-@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
- void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
-
- /* transient events for the CPU buffer -> event buffer */
--#define CPU_IS_KERNEL 1
--#define CPU_TRACE_BEGIN 2
-+#define CPU_MODE_USER 0
-+#define CPU_MODE_KERNEL 1
-+#define CPU_MODE_XEN 2
-+#define CPU_TRACE_BEGIN 3
-
- #endif /* OPROFILE_CPU_BUFFER_H */
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
---- ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/event_buffer.h 2006-04-03 15:53:05.000000000 +0100
-@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
- #define CPU_SWITCH_CODE 2
- #define COOKIE_SWITCH_CODE 3
- #define KERNEL_ENTER_SWITCH_CODE 4
--#define KERNEL_EXIT_SWITCH_CODE 5
-+#define USER_ENTER_SWITCH_CODE 5
- #define MODULE_LOADED_CODE 6
- #define CTX_TGID_CODE 7
- #define TRACE_BEGIN_CODE 8
- #define TRACE_END_CODE 9
-+#define XEN_ENTER_SWITCH_CODE 10
-
- #define INVALID_COOKIE ~0UL
- #define NO_COOKIE 0UL
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/oprof.c 2006-04-03 15:53:05.000000000 +0100
-@@ -5,6 +5,10 @@
- * @remark Read the file COPYING
- *
- * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
- */
-
- #include <linux/kernel.h>
-@@ -19,7 +23,7 @@
- #include "cpu_buffer.h"
- #include "buffer_sync.h"
- #include "oprofile_stats.h"
--
-+
- struct oprofile_operations oprofile_ops;
-
- unsigned long oprofile_started;
-@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
- */
- static int timer = 0;
-
-+extern unsigned int adomains;
-+extern int active_domains[MAX_OPROF_DOMAINS];
-+
-+int oprofile_set_active(void)
-+{
-+ if (oprofile_ops.set_active)
-+ return oprofile_ops.set_active(active_domains, adomains);
-+
-+ return -EINVAL;
-+}
-+
- int oprofile_setup(void)
- {
- int err;
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/oprof.h 2006-04-03 15:53:05.000000000 +0100
-@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
- void oprofile_timer_init(struct oprofile_operations * ops);
-
- int oprofile_set_backtrace(unsigned long depth);
-+
-+int oprofile_set_active(void);
-
- #endif /* OPROF_H */
-diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
---- ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c 2006-03-20 05:53:29.000000000 +0000
-+++ ./drivers/oprofile/oprofile_files.c 2006-04-03 15:53:05.000000000 +0100
-@@ -5,15 +5,21 @@
- * @remark Read the file COPYING
- *
- * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
- */
-
- #include <linux/fs.h>
- #include <linux/oprofile.h>
-+#include <asm/uaccess.h>
-+#include <linux/ctype.h>
-
- #include "event_buffer.h"
- #include "oprofile_stats.h"
- #include "oprof.h"
--
-+
- unsigned long fs_buffer_size = 131072;
- unsigned long fs_cpu_buffer_size = 8192;
- unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file *
- static struct file_operations dump_fops = {
- .write = dump_write,
- };
--
-+
-+#define TMPBUFSIZE 512
-+
-+unsigned int adomains = 0;
-+long active_domains[MAX_OPROF_DOMAINS];
-+
-+static ssize_t adomain_write(struct file * file, char const __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ char tmpbuf[TMPBUFSIZE];
-+ char * startp = tmpbuf;
-+ char * endp = tmpbuf;
-+ int i;
-+ unsigned long val;
-+
-+ if (*offset)
-+ return -EINVAL;
-+ if (!count)
-+ return 0;
-+ if (count > TMPBUFSIZE - 1)
-+ return -EINVAL;
-+
-+ memset(tmpbuf, 0x0, TMPBUFSIZE);
-+
-+ if (copy_from_user(tmpbuf, buf, count))
-+ return -EFAULT;
-+
-+ for (i = 0; i < MAX_OPROF_DOMAINS; i++)
-+ active_domains[i] = -1;
-+ adomains = 0;
-+
-+ while (1) {
-+ val = simple_strtol(startp, &endp, 0);
-+ if (endp == startp)
-+ break;
-+ while (ispunct(*endp))
-+ endp++;
-+ active_domains[adomains++] = val;
-+ if (adomains >= MAX_OPROF_DOMAINS)
-+ break;
-+ startp = endp;
-+ }
-+ if (oprofile_set_active())
-+ return -EINVAL;
-+ return count;
-+}
-+
-+static ssize_t adomain_read(struct file * file, char __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ char tmpbuf[TMPBUFSIZE];
-+ size_t len = 0;
-+ int i;
-+ /* This is all screwed up if we run out of space */
-+ for (i = 0; i < adomains; i++)
-+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len,
-+ "%u ", (unsigned int)active_domains[i]);
-+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
-+ return simple_read_from_buffer((void __user *)buf, count,
-+ offset, tmpbuf, len);
-+}
-+
-+
-+static struct file_operations active_domain_ops = {
-+ .read = adomain_read,
-+ .write = adomain_write,
-+};
-+
- void oprofile_create_files(struct super_block * sb, struct dentry * root)
- {
- oprofilefs_create_file(sb, root, "enable", &enable_fops);
- oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
-+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
- oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
- oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
- oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
-diff -pruN ../pristine-linux-2.6.16/include/linux/oprofile.h ./include/linux/oprofile.h
---- ../pristine-linux-2.6.16/include/linux/oprofile.h 2006-03-20 05:53:29.000000000 +0000
-+++ ./include/linux/oprofile.h 2006-04-03 15:53:05.000000000 +0100
-@@ -16,6 +16,8 @@
- #include <linux/types.h>
- #include <linux/spinlock.h>
- #include <asm/atomic.h>
-+
-+#include <xen/interface/xenoprof.h>
-
- struct super_block;
- struct dentry;
-@@ -27,6 +29,8 @@ struct oprofile_operations {
- /* create any necessary configuration files in the oprofile fs.
- * Optional. */
- int (*create_files)(struct super_block * sb, struct dentry * root);
-+ /* setup active domains with Xen */
-+ int (*set_active)(int *active_domains, unsigned int adomains);
- /* Do any necessary interrupt setup. Optional. */
- int (*setup)(void);
- /* Do any necessary interrupt shutdown. Optional. */
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenstat/libxenstat/src/xen-interface.c
--- a/tools/xenstat/libxenstat/src/xen-interface.c Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/* xen-interface.c
- *
- * Copyright (C) International Business Machines Corp., 2005
- * Authors: Josh Triplett <josht@us.ibm.com>
- * Judy Fischbach <jfisch@us.ibm.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-#include "xen-interface.h"
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <xen/linux/privcmd.h>
-
-struct xi_handle {
- int fd;
-};
-
-/* Initialize for xen-interface. Returns a handle to be used with subsequent
- * calls to the xen-interface functions or NULL if an error occurs. */
-xi_handle *xi_init(void)
-{
- xi_handle *handle;
-
- handle = (xi_handle *)calloc(1, sizeof(xi_handle));
- if (handle == NULL)
- return NULL;
-
- handle->fd = open("/proc/xen/privcmd", O_RDWR);
- if (handle->fd < 0) {
- perror("Couldn't open /proc/xen/privcmd");
- free(handle);
- return NULL;
- }
-
- return handle;
-}
-
-/* Release the handle to libxc, free resources, etc. */
-void xi_uninit(xi_handle *handle)
-{
- close (handle->fd);
- free (handle);
-}
-
-/* Make simple xen version hypervisor calls */
-static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum,
- xen_extraversion_t *ver)
-{
- privcmd_hypercall_t privcmd;
- int ret = 0;
-
- if (mlock(&privcmd, sizeof(privcmd)) < 0) {
- perror("Failed to mlock privcmd structure");
- return -1;
- }
-
- if (mlock(ver, sizeof(*ver)) < 0) {
- perror("Failed to mlock extraversion structure");
- munlock(&privcmd, sizeof(privcmd));
- return -1;
- }
-
- privcmd.op = __HYPERVISOR_xen_version;
- privcmd.arg[0] = (unsigned long)XENVER_version;
- privcmd.arg[1] = 0;
-
- *vnum = ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd);
- if (*vnum < 0) {
- perror("Hypercall failed");
- ret = -1;
- }
-
- privcmd.op = __HYPERVISOR_xen_version;
- privcmd.arg[0] = (unsigned long)XENVER_extraversion;
- privcmd.arg[1] = (unsigned long)ver;
-
- if (ioctl(handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
- perror("Hypercall failed");
- ret = -1;
- }
-
- munlock(&privcmd, sizeof(privcmd));
- munlock(ver, sizeof(*ver));
-
- return ret;
-}
-
-/* Make Xen Dom0 op hypervisor call */
-static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op,
- int dom_opcode)
-{
- privcmd_hypercall_t privcmd;
- int ret = 0;
-
- /* set up for doing hypercall */
- privcmd.op = __HYPERVISOR_dom0_op;
- privcmd.arg[0] = (unsigned long)dom_op;
- dom_op->cmd = dom_opcode;
- dom_op->interface_version = DOM0_INTERFACE_VERSION;
-
- if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
- perror("Failed to mlock privcmd structure");
- return -1;
- }
-
- if (mlock( dom_op, sizeof(dom0_op_t)) < 0) {
- perror("Failed to mlock dom0_op structure");
- munlock( &privcmd, sizeof(privcmd_hypercall_t));
- return -1;
- }
-
- if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
- perror("Hypercall failed");
- ret = -1;
- }
-
- munlock( &privcmd, sizeof(privcmd_hypercall_t));
- munlock( dom_op, sizeof(dom0_op_t));
-
- return ret;
-}
-
-/* Obtain domain data from dom0 */
-int xi_get_physinfo(xi_handle *handle, dom0_physinfo_t *physinfo)
-{
- dom0_op_t op;
-
- if (xi_make_dom0_op(handle, &op, DOM0_PHYSINFO) < 0) {
- perror("DOM0_PHYSINFO Hypercall failed");
- return -1;
- }
-
- *physinfo = op.u.physinfo;
- return 0;
-}
-
-/* Obtain domain data from dom0 */
-int xi_get_domaininfolist(xi_handle *handle, dom0_getdomaininfo_t *info,
- unsigned int first_domain, unsigned int max_domains)
-{
- dom0_op_t op;
- op.u.getdomaininfolist.first_domain = first_domain;
- op.u.getdomaininfolist.max_domains = max_domains;
- op.u.getdomaininfolist.buffer = info;
-
- if (mlock( info, max_domains * sizeof(dom0_getdomaininfo_t)) < 0) {
- perror("Failed to mlock domaininfo array");
- return -1;
- }
-
- if (xi_make_dom0_op(handle, &op, DOM0_GETDOMAININFOLIST) < 0) {
- perror("DOM0_GETDOMAININFOLIST Hypercall failed");
- return -1;
- }
-
- return op.u.getdomaininfolist.num_domains;
-}
-
-/* Get vcpu info from a domain */
-int xi_get_domain_vcpu_info(xi_handle *handle, unsigned int domain,
- unsigned int vcpu, dom0_getvcpuinfo_t *info)
-{
- dom0_op_t op;
- op.u.getvcpuinfo.domain = domain;
- op.u.getvcpuinfo.vcpu = vcpu;
-
- if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUINFO) < 0) {
- perror("DOM0_GETVCPUINFO Hypercall failed");
- return -1;
- }
-
- memcpy(info, &op.u.getvcpuinfo, sizeof(dom0_getvcpuinfo_t));
-
- return 0;
-}
-
-/* gets xen version information from hypervisor */
-int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
-{
- /* gets the XENVER_version and XENVER_extraversion */
- if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {
- perror("XEN VERSION Hypercall failed");
- return -1;
- }
-
- return 0;
-}
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xenstat/libxenstat/src/xen-interface.h
--- a/tools/xenstat/libxenstat/src/xen-interface.h Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/* xen-interface.h
- *
- * Copyright (C) International Business Machines Corp., 2005
- * Authors: Josh Triplett <josht@us.ibm.com>
- * Judy Fischbach <jfisch@us.ibm.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-#include <stdint.h>
-#include <xen/xen.h>
-#include <xen/dom0_ops.h>
-#include <xen/sched.h>
-#include <xen/version.h>
-
-/* Opaque handles */
-typedef struct xi_handle xi_handle;
-
-/* Initialize for xen-interface. Returns a handle to be used with subsequent
- * calls to the xen-interface functions or NULL if an error occurs. */
-xi_handle *xi_init(void);
-
-/* Release the handle to libxc, free resources, etc. */
-void xi_uninit(xi_handle *handle);
-
-/* Obtain xen version information from hypervisor */
-int xi_get_xen_version(xi_handle *, long *vnum, xen_extraversion_t *ver);
-
-/* Obtain physinfo data from dom0 */
-int xi_get_physinfo(xi_handle *, dom0_physinfo_t *);
-
-/* Obtain domain data from dom0 */
-int xi_get_domaininfolist(xi_handle *, dom0_getdomaininfo_t *, unsigned int,
- unsigned int);
-
-/* Get vcpu info from a domain */
-int xi_get_domain_vcpu_info(xi_handle *, unsigned int, unsigned int,
- dom0_getvcpuinfo_t *);
diff -r 707737b66f58 -r 5d9eb92e63e2 tools/xm-test/lib/XmTestLib/Network.py
--- a/tools/xm-test/lib/XmTestLib/Network.py Mon May 08 13:41:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#!/usr/bin/python
-"""
- Network.py - Common utilities for network tests
-
- Copyright (C) International Business Machines Corp., 2005
- Author: Jim Dykman <dykman@us.ibm.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; under version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""
-import sys;
-import os;
-import atexit;
-import random;
-
-from Test import *
-from Xm import *
-from config import *
-
-class NetworkError(Exception):
- def __init__(self, msg):
- self.errMsg = msg
-
- def __str__(self):
- return str(self.errMsg)
-
-def undo_dom0_alias(eth, ip):
- traceCommand("ip addr del " + ip + " dev " + eth)
-
-def net_from_ip(ip):
- return ip[:ip.rfind(".")] + ".0/24"
-
-class XmNetwork:
-
- def __init__(self):
- # Check for existing zeroconf address. We are using the zeroconf
- # address range as static IP addresses.... if someone is using
- # real zeroconf addresses, then we're going to skip tests to
- # avoid interfering with them.
- rc, out = traceCommand(
- "ip addr show |grep \"inet 169.254\" | grep -v vif")
-
- if rc == 0:
- SKIP("Zeroconf address found: " + out)
-
- # Randomize one octet of the IP addresses we choose, so that
- # multiple machines running network tests don't interfere
- # with each other.
- self.subnet = random.randint(1,254)
-
- def calc_ip_address(self, dom, interface):
- # Generate an IP address from the dom# and eth#:
- # 169.254.(self.subnet).(eth#)*16 + (dom# + 1)
- ethnum = int(interface[len("eth"):])
- if (ethnum > 15):
- raise NetworkError("ethnum > 15 : " + interface)
- domnum = int(dom[len("dom"):])
- if (domnum > 14):
- raise NetworkError("domnum > 14 : " + dom)
-
- return "169.254."+ str(self.subnet) + "." + str(ethnum*16+domnum+1)
-
- def ip(self, dom, interface, todomname=None, toeth=None, bridge=None):
- newip = self.calc_ip_address(dom, interface)
-
- # If the testcase is going to talk to dom0, we need to add an
- # IP address in the proper subnet
- if dom == "dom0":
- if ENABLE_HVM_SUPPORT:
- # HVM uses ioemu which uses a bridge
- if not bridge:
- SKIP("no bridge supplied")
- else:
- vifname = bridge
- else:
- # The domain's vif is a convenient place to add to
- vifname = "vif" + str(domid(todomname)) + "." + toeth[3:]
-
- # register the exit handler FIRST, just in case
- atexit.register(undo_dom0_alias, vifname, newip)
-
- # add the alias
- status, output = traceCommand("ip addr add " + newip +
- " dev " + vifname)
- if status:
- SKIP("\"ip addr add\" failed")
-
- if ENABLE_HVM_SUPPORT:
- # We need to add a route to the bridge device
- network = net_from_ip(newip)
- status, output = traceCommand("ip route add " + network + " dev " + vifname + " scope link")
-
- if status:
- SKIP("\"ip route add\" failed")
-
- return newip
-
- def mask(self, dom, interface):
- return "255.255.255.240"

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog
merge with xen-unstable.hg [ In reply to ]
# HG changeset patch
# User awilliam@xenbuild.aw
# Node ID 72c5d8206d4882172d9ad1b0c6ad819130e3309f
# Parent fbf676a36ee44558d54db9ebb43a5fe7971d669d
# Parent 13d6d993d79724d86a0c9ac556a7f884baed98ae
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/arch/ia64/xen/xen_ksyms.c | 12
tools/xentrace/tbctl.c | 26
README | 40
buildconfigs/linux-defconfig_xen0_x86_32 | 10
buildconfigs/linux-defconfig_xen0_x86_64 | 10
buildconfigs/linux-defconfig_xenU_x86_32 | 19
buildconfigs/linux-defconfig_xenU_x86_64 | 10
buildconfigs/linux-defconfig_xen_x86_32 | 12
buildconfigs/linux-defconfig_xen_x86_64 | 12
docs/man/xend-config.sxp.pod.5 | 2
docs/man/xm.pod.1 | 18
docs/man/xmdomain.cfg.pod.5 | 4
extras/mini-os/Makefile | 35
extras/mini-os/console/console.c | 10
extras/mini-os/include/mm.h | 90 +
extras/mini-os/include/types.h | 7
extras/mini-os/kernel.c | 22
extras/mini-os/mm.c | 72 -
extras/mini-os/traps.c | 36
extras/mini-os/x86_32.S | 8
extras/mini-os/x86_64.S | 3
linux-2.6-xen-sparse/arch/i386/kernel/fixup.c | 10
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S | 10
linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c | 10
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 266 ++--
linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c | 11
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 10
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c | 10
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c | 13
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c | 10
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c | 10
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 81 -
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 3
linux-2.6-xen-sparse/arch/ia64/xen/Makefile | 4
linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c | 7
linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S | 12
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c | 257 +---
linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S | 16
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 73 -
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 36
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig | 9
linux-2.6-xen-sparse/drivers/char/tpm/Makefile | 3
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 15
linux-2.6-xen-sparse/drivers/xen/Kconfig | 16
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 14
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 21
linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 19
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 29
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c | 23
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 15
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c | 12
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h | 10
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c | 10
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 10
linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 10
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 10
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 10
linux-2.6-xen-sparse/drivers/xen/char/mem.c | 10
linux-2.6-xen-sparse/drivers/xen/console/console.c | 14
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c | 10
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 22
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 12
linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c | 3
linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 10
linux-2.6-xen-sparse/drivers/xen/core/skbuff.c | 10
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 52
linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c | 10
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c | 7
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 13
linux-2.6-xen-sparse/drivers/xen/net_driver_util.c | 10
linux-2.6-xen-sparse/drivers/xen/netback/common.h | 18
linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 33
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 10
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 23
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 13
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 521 +++-----
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 13
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 12
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 22
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 14
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c | 12
linux-2.6-xen-sparse/drivers/xen/util.c | 10
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c | 10
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 11
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c | 10
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h | 10
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c | 10
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 19
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 10
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/page.h | 3
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h | 28
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 6
linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h | 5
linux-2.6-xen-sparse/include/asm-x86_64/e820.h | 63 +
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h | 16
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h | 2
linux-2.6-xen-sparse/include/xen/balloon.h | 10
linux-2.6-xen-sparse/include/xen/driver_util.h | 10
linux-2.6-xen-sparse/include/xen/evtchn.h | 10
linux-2.6-xen-sparse/include/xen/foreign_page.h | 10
linux-2.6-xen-sparse/include/xen/gnttab.h | 10
linux-2.6-xen-sparse/include/xen/net_driver_util.h | 10
linux-2.6-xen-sparse/include/xen/public/evtchn.h | 10
linux-2.6-xen-sparse/include/xen/public/privcmd.h | 10
linux-2.6-xen-sparse/include/xen/xen_proc.h | 10
linux-2.6-xen-sparse/include/xen/xenbus.h | 10
patches/linux-2.6.16.13/xen-hotplug.patch | 9
patches/linux-2.6.16.13/xenoprof-generic.patch | 46
tools/examples/README | 13
tools/examples/external-device-migrate | 124 +-
tools/examples/network-bridge | 2
tools/examples/vtpm | 3
tools/examples/vtpm-common.sh | 120 +
tools/examples/xmexample.hvm | 4
tools/examples/xmexample1 | 4
tools/examples/xmexample2 | 4
tools/examples/xmexample3 | 4
tools/firmware/acpi/acpi_dsdt.asl | 10
tools/firmware/acpi/acpi_dsdt.c | 289 ++--
tools/firmware/acpi/acpi_fadt.h | 4
tools/ioemu/hw/acpi.c | 178 ++
tools/ioemu/hw/cirrus_vga.c | 151 ++
tools/ioemu/hw/mc146818rtc.c | 25
tools/ioemu/hw/pc.c | 24
tools/ioemu/hw/pckbd.c | 153 +-
tools/ioemu/hw/serial.c | 1
tools/ioemu/hw/vga.c | 19
tools/ioemu/hw/vga_int.h | 2
tools/ioemu/target-i386-dm/Makefile | 2
tools/ioemu/vl.c | 208 ---
tools/ioemu/vl.h | 30
tools/libxc/xc_acm.c | 33
tools/libxc/xc_linux_build.c | 46
tools/libxc/xc_load_elf.c | 69 -
tools/libxc/xc_ptrace.c | 211 +--
tools/libxc/xc_tbuf.c | 31
tools/libxc/xenctrl.h | 42
tools/libxc/xg_private.h | 5
tools/python/xen/lowlevel/acm/acm.c | 54
tools/python/xen/lowlevel/xc/xc.c | 7
tools/python/xen/xend/XendCheckpoint.py | 8
tools/python/xen/xend/XendDomain.py | 6
tools/python/xen/xend/XendDomainInfo.py | 34
tools/python/xen/xend/image.py | 27
tools/python/xen/xend/server/DevController.py | 8
tools/python/xen/xend/server/pciif.py | 25
tools/python/xen/xend/server/tpmif.py | 12
tools/security/Makefile | 4
tools/security/secpol_tool.c | 32
tools/tests/Makefile | 2
tools/vtpm/Makefile | 21
tools/vtpm/tpm_emulator.patch | 1
tools/vtpm/vtpm.patch | 163 --
tools/vtpm_manager/Rules.mk | 8
tools/vtpm_manager/manager/dmictl.c | 142 --
tools/vtpm_manager/manager/securestorage.c | 29
tools/vtpm_manager/manager/vtpm_ipc.c | 141 ++
tools/vtpm_manager/manager/vtpm_ipc.h | 71 +
tools/vtpm_manager/manager/vtpm_lock.c | 63 +
tools/vtpm_manager/manager/vtpm_lock.h | 48
tools/vtpm_manager/manager/vtpm_manager.c | 602 ----------
tools/vtpm_manager/manager/vtpm_manager.h | 36
tools/vtpm_manager/manager/vtpm_manager_handler.c | 455 +++++++
tools/vtpm_manager/manager/vtpmd.c | 309 ++++-
tools/vtpm_manager/manager/vtpmpriv.h | 73 -
tools/xenmon/xenbaked.c | 99 -
tools/xenstore/xenstored_core.c | 17
tools/xenstore/xenstored_domain.c | 9
tools/xenstore/xenstored_domain.h | 2
tools/xenstore/xs_lib.c | 4
tools/xenstore/xs_lib.h | 2
tools/xentrace/Makefile | 2
tools/xentrace/setsize.c | 56
tools/xentrace/xentrace.8 | 75 +
tools/xentrace/xentrace.c | 43
tools/xentrace/xentrace_format | 6
tools/xm-test/configure.ac | 1
tools/xm-test/ramdisk/bin/create_disk_image | 7
tools/xm-test/tests/Makefile.am | 7
tools/xm-test/tests/block-integrity/01_block_device_read_verify.py | 62 +
tools/xm-test/tests/block-integrity/Makefile.am | 21
tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py | 87 +
tools/xm-test/tests/network/03_network_local_tcp_pos.py | 4
tools/xm-test/tests/network/04_network_local_udp_pos.py | 4
tools/xm-test/tests/network/06_network_dom0_tcp_pos.py | 2
tools/xm-test/tests/network/07_network_dom0_udp_pos.py | 2
tools/xm-test/tests/network/12_network_domU_tcp_pos.py | 2
tools/xm-test/tests/network/13_network_domU_udp_pos.py | 2
tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py | 61 -
tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py | 100 +
tools/xm-test/tests/vtpm/Makefile.am | 3
xen/arch/x86/dom0_ops.c | 21
xen/arch/x86/domain.c | 5
xen/arch/x86/hvm/hvm.c | 11
xen/arch/x86/hvm/i8259.c | 88 +
xen/arch/x86/hvm/platform.c | 4
xen/arch/x86/hvm/svm/intr.c | 17
xen/arch/x86/hvm/svm/svm.c | 342 +++--
xen/arch/x86/hvm/svm/vmcb.c | 42
xen/arch/x86/hvm/vmx/vmcs.c | 96 +
xen/arch/x86/hvm/vmx/vmx.c | 5
xen/arch/x86/mm.c | 35
xen/arch/x86/shadow.c | 24
xen/arch/x86/shadow32.c | 8
xen/arch/x86/shadow_public.c | 5
xen/arch/x86/x86_emulate.c | 4
xen/common/acm_ops.c | 282 ++--
xen/common/elf.c | 83 -
xen/common/event_channel.c | 3
xen/include/asm-ia64/event.h | 17
xen/include/asm-x86/event.h | 6
xen/include/asm-x86/hvm/svm/svm.h | 8
xen/include/asm-x86/hvm/svm/vmcb.h | 1
xen/include/asm-x86/hvm/vmx/vmcs.h | 2
xen/include/asm-x86/hvm/vpic.h | 3
xen/include/public/acm_ops.h | 54
xen/include/public/arch-ia64.h | 79 -
xen/include/public/arch-x86_32.h | 36
xen/include/public/arch-x86_64.h | 29
xen/include/public/callback.h | 10
xen/include/public/dom0_ops.h | 205 ++-
xen/include/public/event_channel.h | 99 -
xen/include/public/grant_table.h | 30
xen/include/public/hvm/ioreq.h | 26
xen/include/public/hvm/vmx_assist.h | 5
xen/include/public/io/blkif.h | 12
xen/include/public/io/netif.h | 32
xen/include/public/io/tpmif.h | 19
xen/include/public/memory.h | 48
xen/include/public/nmi.h | 5
xen/include/public/physdev.h | 45
xen/include/public/sched.h | 15
xen/include/public/vcpu.h | 10
xen/include/public/version.h | 15
xen/include/public/xen.h | 47
xen/include/public/xenoprof.h | 15
xen/include/xen/hypercall.h | 2
xen/include/xen/sched.h | 1
240 files changed, 5232 insertions(+), 4388 deletions(-)

diff -r fbf676a36ee4 -r 72c5d8206d48 README
--- a/README Mon May 22 08:53:26 2006 -0600
+++ b/README Mon May 22 14:13:38 2006 -0600
@@ -1,9 +1,9 @@
################################
- __ __ _____ ___
- \ \/ /___ _ __ |___ / / _ \
+ __ __ _____ ___
+ \ \/ /___ _ __ |___ / / _ \
\ // _ \ '_ \ |_ \| | | |
/ \ __/ | | | ___) | |_| |
- /_/\_\___|_| |_| |____(_)___/
+ /_/\_\___|_| |_| |____(_)___/

################################

@@ -66,14 +66,14 @@ 2. Configure your bootloader to boot Xen

The linux command line takes all the usual options, such as
root=<root-dev> to specify your usual root partition (e.g.,
- /dev/hda1).
+ /dev/hda1).

The Xen command line takes a number of optional arguments described
in the manual. The most common is 'dom0_mem=xxxM' which sets the
amount of memory to allocate for use by your initial virtual
machine (known as domain 0). Note that Xen itself reserves about
32MB memory for internal use, which is not available for allocation
- to virtual machines.
+ to virtual machines.

3. Reboot your system and select the "Xen 3.0 / XenLinux 2.6" menu
option. After booting Xen, Linux will start and your initialisation
@@ -86,7 +86,7 @@ release. Make sure you have all the foll
release. Make sure you have all the following installed, either by
visiting the project webpage or installing a pre-built package
provided by your Linux distributor:
- * GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
+ * GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib-dev)
@@ -122,19 +122,19 @@ 3. For the very first build, or if you w
# make world
# make install

- This will create and install onto the local machine. It will build
+ This will create and install onto the local machine. It will build
the xen binary (xen.gz), and a linux kernel and modules that can be
used in both dom0 and an unprivileged guest kernel (vmlinuz-2.6.x-xen),
the tools and the documentation.

- You can override the destination for make install by setting DESTDIR
+ You can override the destination for make install by setting DESTDIR
to some value.

- The make command line defaults to building the kernel vmlinuz-2.6.x-xen.
- You can override this default by specifying KERNELS=kernelname. For
- example, you can make two kernels - linux-2.6-xen0
- and linux-2.6-xenU - which are smaller builds containing only selected
- modules, intended primarily for developers that don't like to wait
+ The make command line defaults to building the kernel vmlinuz-2.6.x-xen.
+ You can override this default by specifying KERNELS=kernelname. For
+ example, you can make two kernels - linux-2.6-xen0
+ and linux-2.6-xenU - which are smaller builds containing only selected
+ modules, intended primarily for developers that don't like to wait
for a full -xen kernel to build. The -xenU kernel is particularly small,
as it does not contain any physical device drivers, and hence is
only useful for guest domains.
@@ -153,15 +153,15 @@ 4. To rebuild an existing tree without m
# make dist

This will build and install xen, kernels, tools, and
- docs into the local dist/ directory.
+ docs into the local dist/ directory.

- You can override the destination for make install by setting DISTDIR
+ You can override the destination for make install by setting DISTDIR
to some value.

- make install and make dist differ in that make install does the
- right things for your local machine (installing the appropriate
- version of hotplug or udev scripts, for example), but make dist
- includes all versions of those scripts, so that you can copy the dist
+ make install and make dist differ in that make install does the
+ right things for your local machine (installing the appropriate
+ version of hotplug or udev scripts, for example), but make dist
+ includes all versions of those scripts, so that you can copy the dist
directory to another machine and install from that distribution.

5. To rebuild a kernel with a modified config:
@@ -171,6 +171,6 @@ 5. To rebuild a kernel with a modified c
# make linux-2.6-xen-install

Depending on your config, you may need to use 'mkinitrd' to create
- an initial ram disk, just like a native system e.g.
+ an initial ram disk, just like a native system e.g.
# depmod 2.6.16-xen
# mkinitrd -v -f --with=aacraid --with=sd_mod --with=scsi_mod initrd-2.6.16-xen.img 2.6.16-xen
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_32 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-xen0
-# Sat Apr 8 11:34:07 2006
+# Linux kernel version: 2.6.16.13-xen0
+# Thu May 11 17:06:31 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -1309,7 +1309,7 @@ CONFIG_CRYPTO_CRC32C=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030101
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -1330,10 +1330,12 @@ CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
-# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_64 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-xen0
-# Thu Apr 13 14:58:29 2006
+# Linux kernel version: 2.6.16.13-xen0
+# Thu May 11 17:17:19 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@@ -1250,7 +1250,7 @@ CONFIG_CRYPTO_CRC32C=m
# Hardware crypto devices
#
CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030101
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -1271,10 +1271,12 @@ CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
-# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xenU_x86_32
--- a/buildconfigs/linux-defconfig_xenU_x86_32 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xenU_x86_32 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen0
-# Thu Feb 16 22:53:43 2006
+# Linux kernel version: 2.6.16.13-xenU
+# Thu May 11 17:08:12 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -617,11 +617,7 @@ CONFIG_DUMMY_CONSOLE=y
#

#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set

@@ -852,7 +848,7 @@ CONFIG_CRYPTO_CRC32C=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
-CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -862,12 +858,15 @@ CONFIG_XEN_UNPRIVILEGED_GUEST=y
# CONFIG_XEN_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_NO_IDLE_HZ=y

#
# Library routines
@@ -883,4 +882,6 @@ CONFIG_X86_SMP=y
CONFIG_X86_SMP=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
CONFIG_KTIME_SCALAR=y
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xenU_x86_64
--- a/buildconfigs/linux-defconfig_xenU_x86_64 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xenU_x86_64 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-xenU
-# Thu Apr 13 14:59:16 2006
+# Linux kernel version: 2.6.16.13-xenU
+# Thu May 11 17:17:57 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@@ -1135,7 +1135,7 @@ CONFIG_CRYPTO_CRC32C=m
# Hardware crypto devices
#
CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030101
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -1145,10 +1145,12 @@ CONFIG_XEN_UNPRIVILEGED_GUEST=y
# CONFIG_XEN_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-xen
-# Thu Apr 20 17:07:18 2006
+# Linux kernel version: 2.6.16.13-xen
+# Thu May 11 17:11:00 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -888,7 +888,7 @@ CONFIG_MTD_NAND_DISKONCHIP=m
# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
-CONFIG_MTD_NAND_NANDSIM=y
+CONFIG_MTD_NAND_NANDSIM=m

#
# OneNAND Flash Device Drivers
@@ -3009,7 +3009,7 @@ CONFIG_CRYPTO_TEST=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030101
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -3030,10 +3030,12 @@ CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
-CONFIG_XEN_TPMDEV_FRONTEND=m
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
diff -r fbf676a36ee4 -r 72c5d8206d48 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64 Mon May 22 08:53:26 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64 Mon May 22 14:13:38 2006 -0600
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-xen
-# Thu Apr 20 17:05:48 2006
+# Linux kernel version: 2.6.16.13-xen
+# Thu May 11 17:18:58 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@@ -840,7 +840,7 @@ CONFIG_MTD_NAND_DISKONCHIP=m
# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
-CONFIG_MTD_NAND_NANDSIM=y
+CONFIG_MTD_NAND_NANDSIM=m

#
# OneNAND Flash Device Drivers
@@ -2841,7 +2841,7 @@ CONFIG_CRYPTO_TEST=m
# Hardware crypto devices
#
CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030101
+CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
@@ -2863,10 +2863,12 @@ CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
-CONFIG_XEN_TPMDEV_FRONTEND=m
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
diff -r fbf676a36ee4 -r 72c5d8206d48 docs/man/xend-config.sxp.pod.5
--- a/docs/man/xend-config.sxp.pod.5 Mon May 22 08:53:26 2006 -0600
+++ b/docs/man/xend-config.sxp.pod.5 Mon May 22 14:13:38 2006 -0600
@@ -107,7 +107,7 @@ If the value is 0, all available CPUs wi
=item I<enable-dump>

A boolean value that tells xend whether or not core dumps of guest
-domains should be saved when a crash occurrs. Defaults to I<no>.
+domains should be saved when a crash occurs. Defaults to I<no>.

=item I<external-migration-tool>

diff -r fbf676a36ee4 -r 72c5d8206d48 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Mon May 22 08:53:26 2006 -0600
+++ b/docs/man/xm.pod.1 Mon May 22 14:13:38 2006 -0600
@@ -27,12 +27,12 @@ each of those sub commands.

=head1 NOTES

-All B<xm> opperations rely upon the Xen control daemon, aka B<xend>.
+All B<xm> operations rely upon the Xen control daemon, aka B<xend>.
For any xm commands to run xend must also be running. For this reason
you should start xend as a service when your system first boots using
xen.

-Most B<xm> commands require root privledges to run due to the
+Most B<xm> commands require root privileges to run due to the
communications channels used to talk to the hypervisor. Running as
non root will return an error.

@@ -169,7 +169,7 @@ The domain is currently running on a CPU

=item B<b - blocked>

-The domain is blocked, and not running or runable. This can be caused
+The domain is blocked, and not running or runnable. This can be caused
because the domain is waiting on IO (a traditional wait state) or has
gone to sleep because there was nothing else for it to do.

@@ -260,7 +260,7 @@ careful when using this command on runni

Migrate a domain to another Host machine. B<Xend> must be running on
other host machine, it must be running the same version of xen, it
-must have the migration tcp port open and accepting connections from
+must have the migration TCP port open and accepting connections from
the source host, and there must be sufficient resources for the domain
to run (memory, disk, etc).

@@ -337,7 +337,7 @@ severed upon restore, as TCP timeouts ma
=item B<shutdown> I<[options]> I<domain-id>

Gracefully shuts down a domain. This coordinates with the domain OS
-to perform graceful shutdown, so there is no guaruntee that it will
+to perform graceful shutdown, so there is no guarantee that it will
succeed, and may take a variable length of time depending on what
services must be shutdown in the domain. The command returns
immediately after signally the domain unless that I<-w> flag is used.
@@ -573,11 +573,11 @@ B<PARAMETERS>

=item I<period>

-The normal EDF scheduling usage in nanosecs
+The normal EDF scheduling usage in nanoseconds

=item I<slice>

-The normal EDF scheduling usage in nanosecs
+The normal EDF scheduling usage in nanoseconds

FIXME: these are lame, should explain more.

@@ -726,7 +726,7 @@ circumstances this should actually work.

=item I<mac=macaddr>

-The MAC address that the domain will see on its ethernet device. If
+The MAC address that the domain will see on its Ethernet device. If
the device is not specified it will be randomly generated with the
00:16:3e vendor id prefix.

@@ -768,7 +768,7 @@ formatted as a list or as an S-Expressio

The Virtual Network interfaces for Xen.

-FIXME: This needs a lot more explaination, or it needs to be ripped
+FIXME: This needs a lot more explanation, or it needs to be ripped
out entirely.

=over 4
diff -r fbf676a36ee4 -r 72c5d8206d48 docs/man/xmdomain.cfg.pod.5
--- a/docs/man/xmdomain.cfg.pod.5 Mon May 22 08:53:26 2006 -0600
+++ b/docs/man/xmdomain.cfg.pod.5 Mon May 22 14:13:38 2006 -0600
@@ -80,7 +80,7 @@ An array of block device stanzas, in the

disk = [ "stanza1", "stanza2", ... ]

-Each stanza has 3 terms, seperated by commas,
+Each stanza has 3 terms, separated by commas,
"backend-dev,frontend-dev,mode".

=over 4
@@ -112,7 +112,7 @@ I<r> (read-only), I<w> (read/write).

=item B<vif>

-An arrray of virtual interface stanzas in the form:
+An array of virtual interface stanzas in the form:

vif = [ "stanza1", "stanza2", ... ]

diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/Makefile Mon May 22 14:13:38 2006 -0600
@@ -1,4 +1,5 @@ debug ?= y
debug ?= y
+pae ?= n

include $(CURDIR)/../../Config.mk

@@ -6,18 +7,28 @@ override TARGET_ARCH := $(XEN_TARGET
override TARGET_ARCH := $(XEN_TARGET_ARCH)

# NB. '-Wcast-qual' is nasty, so I omitted it.
-CFLAGS := -fno-builtin -Wall -Werror -Iinclude/ -Wredundant-decls -Wno-format
+CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
+
+override CPPFLAGS := -Iinclude $(CPPFLAGS)
+ASFLAGS = -D__ASSEMBLY__
+
+LDFLAGS := -N -T minios-$(TARGET_ARCH).lds

ifeq ($(TARGET_ARCH),x86_32)
CFLAGS += -m32 -march=i686
-LDFLAGS := -m elf_i386
+LDFLAGS += -m elf_i386
+endif
+
+ifeq ($(TARGET_ARCH)$(pae),x86_32y)
+CFLAGS += -DCONFIG_X86_PAE=1
+ASFLAGS += -DCONFIG_X86_PAE=1
endif

ifeq ($(TARGET_ARCH),x86_64)
CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks
CFLAGS += -fno-asynchronous-unwind-tables
-LDFLAGS := -m elf_x86_64
+LDFLAGS += -m elf_x86_64
endif

ifeq ($(debug),y)
@@ -28,12 +39,12 @@ endif

TARGET := mini-os

-OBJS := $(TARGET_ARCH).o
-OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
+HEAD := $(TARGET_ARCH).o
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
-
+
HDRS := $(wildcard include/*.h)
HDRS += $(wildcard include/xen/*.h)

@@ -44,21 +55,25 @@ links:
links:
[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen

-$(TARGET): links $(OBJS)
- $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
+libminios.a: $(OBJS) $(HEAD)
+ ar r libminios.a $(HEAD) $(OBJS)
+
+$(TARGET): links libminios.a $(HEAD)
+ $(LD) $(LDFLAGS) $(HEAD) -L. -lminios -o $@.elf
gzip -f -9 -c $@.elf >$@.gz

.PHONY: clean
clean:
find . -type f -name '*.o' | xargs rm -f
rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
+ rm -f libminios.a
find . -type l | xargs rm -f

%.o: %.c $(HDRS) Makefile
- $(CC) $(CFLAGS) -c $< -o $@
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

%.o: %.S $(HDRS) Makefile
- $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
+ $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@

define all_sources
( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/console/console.c Mon May 22 14:13:38 2006 -0600
@@ -45,6 +45,10 @@
#include <xen/io/console.h>


+/* Copies all print output to the Xen emergency console apart
+ of standard dom0 handled console */
+#define USE_XEN_CONSOLE
+
/* Low level functions defined in xencons_ring.c */
extern int xencons_ring_init(void);
extern int xencons_ring_send(const char *data, unsigned len);
@@ -117,7 +121,9 @@ void print(int direct, const char *fmt,
(void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
return;
} else {
- if(!console_initialised)
+#ifndef USE_XEN_CONSOLE
+ if(!console_initialised)
+#endif
(void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);

console_print(buf, strlen(buf));
@@ -128,7 +134,7 @@ void printk(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- print(1, fmt, args);
+ print(0, fmt, args);
va_end(args);
}

diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/include/mm.h Mon May 22 14:13:38 2006 -0600
@@ -43,6 +43,8 @@

#if defined(__i386__)

+#if !defined(CONFIG_X86_PAE)
+
#define L2_PAGETABLE_SHIFT 22

#define L1_PAGETABLE_ENTRIES 1024
@@ -50,6 +52,30 @@

#define PADDR_BITS 32
#define PADDR_MASK (~0UL)
+
+#define UNMAPPED_PT_FRAMES 1
+#define PRIpte "08lx"
+typedef unsigned long pgentry_t;
+
+#else /* defined(CONFIG_X86_PAE) */
+
+#define L2_PAGETABLE_SHIFT 21
+#define L3_PAGETABLE_SHIFT 30
+
+#define L1_PAGETABLE_ENTRIES 512
+#define L2_PAGETABLE_ENTRIES 512
+#define L3_PAGETABLE_ENTRIES 4
+
+#define PADDR_BITS 44
+#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
+
+#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
+
+#define UNMAPPED_PT_FRAMES 2
+#define PRIpte "016llx"
+typedef uint64_t pgentry_t;
+
+#endif /* !defined(CONFIG_X86_PAE) */

#elif defined(__x86_64__)

@@ -81,6 +107,10 @@
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)

+#define UNMAPPED_PT_FRAMES 3
+#define PRIpte "016lx"
+typedef unsigned long pgentry_t;
+
#endif

#define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1)
@@ -90,9 +120,11 @@
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
#define l2_table_offset(_a) \
(((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
#define l3_table_offset(_a) \
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
+#endif
+#if defined(__x86_64__)
#define l4_table_offset(_a) \
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
#endif
@@ -111,14 +143,21 @@
#if defined(__i386__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
+#if defined(CONFIG_X86_PAE)
+#define L3_PROT (_PAGE_PRESENT)
+#endif /* CONFIG_X86_PAE */
#elif defined(__x86_64__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#endif
-
+#endif /* __i386__ || __x86_64__ */
+
+#ifndef CONFIG_X86_PAE
#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT)
+#else
+#define PAGE_SIZE (1ULL << L1_PAGETABLE_SHIFT)
+#endif
#define PAGE_SHIFT L1_PAGETABLE_SHIFT
#define PAGE_MASK (~(PAGE_SIZE-1))

@@ -129,36 +168,41 @@
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)

+/* Definitions for machine and pseudophysical addresses. */
+#ifdef CONFIG_X86_PAE
+typedef unsigned long long paddr_t;
+typedef unsigned long long maddr_t;
+#else
+typedef unsigned long paddr_t;
+typedef unsigned long maddr_t;
+#endif
+
extern unsigned long *phys_to_machine_mapping;
+extern char _text, _etext, _edata, _end;
#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
-static __inline__ unsigned long phys_to_machine(unsigned long phys)
-{
- unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT);
- machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
- return machine;
-}
-
+static __inline__ maddr_t phys_to_machine(paddr_t phys)
+{
+ maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+ machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+ return machine;
+}

#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
-static __inline__ unsigned long machine_to_phys(unsigned long machine)
-{
- unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
- phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK);
- return phys;
-}
-
-#if defined(__x86_64__)
-#define VIRT_START 0xFFFFFFFF80000000UL
-#elif defined(__i386__)
-#define VIRT_START 0xC0000000UL
-#endif
+static __inline__ paddr_t machine_to_phys(maddr_t machine)
+{
+ paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+ phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+ return phys;
+}
+
+#define VIRT_START ((unsigned long)&_text)

#define to_phys(x) ((unsigned long)(x)-VIRT_START)
#define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START))

#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
#define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach)))
-#define mfn_to_virt(_mfn) (mach_to_virt(_mfn << PAGE_SHIFT))
+#define mfn_to_virt(_mfn) (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
#define pfn_to_virt(_pfn) (to_virt(_pfn << PAGE_SHIFT))

/* Pagetable walking. */
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/include/types.h
--- a/extras/mini-os/include/types.h Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/include/types.h Mon May 22 14:13:38 2006 -0600
@@ -43,14 +43,19 @@ typedef unsigned long long u_quad_t;
typedef unsigned long long u_quad_t;
typedef unsigned int uintptr_t;

+#if !defined(CONFIG_X86_PAE)
typedef struct { unsigned long pte_low; } pte_t;
+#else
+typedef struct { unsigned long pte_low, pte_high; } pte_t;
+#endif /* CONFIG_X86_PAE */
+
#elif defined(__x86_64__)
typedef long quad_t;
typedef unsigned long u_quad_t;
typedef unsigned long uintptr_t;

typedef struct { unsigned long pte; } pte_t;
-#endif
+#endif /* __i386__ || __x86_64__ */

typedef u8 uint8_t;
typedef s8 int8_t;
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/kernel.c Mon May 22 14:13:38 2006 -0600
@@ -63,7 +63,12 @@ void failsafe_callback(void);

extern char shared_info[PAGE_SIZE];

+#if !defined(CONFIG_X86_PAE)
#define __pte(x) ((pte_t) { (x) } )
+#else
+#define __pte(x) ({ unsigned long long _x = (x); \
+ ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
+#endif

static shared_info_t *map_shared_info(unsigned long pa)
{
@@ -71,7 +76,7 @@ static shared_info_t *map_shared_info(un
(unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) )
{
printk("Failed to map shared_info!!\n");
- *(int*)0=0;
+ do_exit();
}
return (shared_info_t *)shared_info;
}
@@ -106,6 +111,12 @@ void setup_xen_features(void)
}
}

+/* This should be overridden by the application we are linked against. */
+__attribute__((weak)) int app_main(start_info_t *si)
+{
+ printk("Dummy main: start_info=%p\n", si);
+ return 0;
+}

/*
* INITIAL C ENTRY POINT.
@@ -120,6 +131,10 @@ void start_kernel(start_info_t *si)
/* WARN: don't do printk before here, it uses information from
shared_info. Use xprintk instead. */
memcpy(&start_info, si, sizeof(*si));
+
+ /* set up minimal memory infos */
+ phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
+
/* Grab the shared_info pointer and put it in a safe place. */
HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);

@@ -165,12 +180,15 @@ void start_kernel(start_info_t *si)
/* Init the console driver. */
init_console();

- /* Init scheduler. */
+ /* Init scheduler. */
init_sched();

/* Init XenBus from a separate thread */
create_thread("init_xs", init_xs, NULL);

+ /* Call (possibly overridden) app_main() */
+ app_main(&start_info);
+
/* Everything initialised, start idle thread */
run_idle_thread();
}
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/mm.c Mon May 22 14:13:38 2006 -0600
@@ -50,7 +50,6 @@

unsigned long *phys_to_machine_mapping;
extern char *stack;
-extern char _text, _etext, _edata, _end;
extern void page_walk(unsigned long virt_addr);

/*********************
@@ -369,7 +368,7 @@ void new_pt_frame(unsigned long *pt_pfn,
void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
unsigned long offset, unsigned long level)
{
- unsigned long *tab = (unsigned long *)start_info.pt_base;
+ pgentry_t *tab = (pgentry_t *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
unsigned long prot_e, prot_t, pincmd;
mmu_update_t mmu_updates[1];
@@ -383,40 +382,45 @@ void new_pt_frame(unsigned long *pt_pfn,
as a page table page */
memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);

- if (level == L1_FRAME)
- {
+ switch ( level )
+ {
+ case L1_FRAME:
prot_e = L1_PROT;
prot_t = L2_PROT;
pincmd = MMUEXT_PIN_L1_TABLE;
- }
-#if (defined __x86_64__)
- else if (level == L2_FRAME)
- {
+ break;
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
+ case L2_FRAME:
prot_e = L2_PROT;
prot_t = L3_PROT;
pincmd = MMUEXT_PIN_L2_TABLE;
- }
- else if (level == L3_FRAME)
- {
+ break;
+#endif
+#if defined(__x86_64__)
+ case L3_FRAME:
prot_e = L3_PROT;
prot_t = L4_PROT;
pincmd = MMUEXT_PIN_L3_TABLE;
- }
-#endif
- else
- {
+ break;
+#endif
+ default:
printk("new_pt_frame() called with invalid level number %d\n", level);
do_exit();
- }
+ break;
+ }

/* Update the entry */
-#if (defined __x86_64__)
+#if defined(__x86_64__)
tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
#endif
- mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) +
- sizeof(void *)* l1_table_offset(pt_page);
- mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
+#if defined(CONFIG_X86_PAE)
+ tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
+#endif
+
+ mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) +
+ sizeof(pgentry_t) * l1_table_offset(pt_page);
+ mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
(prot_e & ~_PAGE_RW);
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
@@ -435,8 +439,8 @@ void new_pt_frame(unsigned long *pt_pfn,

/* Now fill the new page table page with entries.
Update the page directory as well. */
- mmu_updates[0].ptr = (prev_l_mfn << PAGE_SHIFT) + sizeof(void *) * offset;
- mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
+ mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
+ mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
{
printk("ERROR: mmu_update failed\n");
@@ -451,16 +455,13 @@ void build_pagetable(unsigned long *star
unsigned long start_address, end_address;
unsigned long pfn_to_map, pt_pfn = *start_pfn;
static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
- unsigned long *tab = (unsigned long *)start_info.pt_base;
+ pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
- unsigned long page, offset;
+ unsigned long offset;
int count = 0;

-#if defined(__x86_64__)
- pfn_to_map = (start_info.nr_pt_frames - 3) * L1_PAGETABLE_ENTRIES;
-#else
- pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES;
-#endif
+ pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * L1_PAGETABLE_ENTRIES;
+
start_address = (unsigned long)pfn_to_virt(pfn_to_map);
end_address = (unsigned long)pfn_to_virt(*max_pfn);

@@ -469,7 +470,7 @@ void build_pagetable(unsigned long *star

while(start_address < end_address)
{
- tab = (unsigned long *)start_info.pt_base;
+ tab = (pgentry_t *)start_info.pt_base;
mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));

#if defined(__x86_64__)
@@ -481,6 +482,8 @@ void build_pagetable(unsigned long *star
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
+#endif
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_address);
/* Need new L2 pt frame */
if(!(start_address & L2_MASK))
@@ -499,9 +502,9 @@ void build_pagetable(unsigned long *star
mfn = pte_to_mfn(page);
offset = l1_table_offset(start_address);

- mmu_updates[count].ptr = (mfn << PAGE_SHIFT) + sizeof(void *) * offset;
+ mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[count].val =
- pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
+ (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
count++;
if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
{
@@ -558,9 +561,6 @@ void init_mm(void)
printk(" stack start: %p\n", &stack);
printk(" _end: %p\n", &_end);

- /* set up minimal memory infos */
- phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
-
/* First page follows page table pages and 3 more pages (store page etc) */
start_pfn = PFN_UP(to_phys(start_info.pt_base)) +
start_info.nr_pt_frames + 3;
@@ -570,7 +570,7 @@ void init_mm(void)
printk(" max_pfn: %lx\n", max_pfn);

build_pagetable(&start_pfn, &max_pfn);
-
+
/*
* now we can initialise the page allocator
*/
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/traps.c
--- a/extras/mini-os/traps.c Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/traps.c Mon May 22 14:13:38 2006 -0600
@@ -95,34 +95,47 @@ DO_ERROR(18, "machine check", machine_ch

void page_walk(unsigned long virt_address)
{
- unsigned long *tab = (unsigned long *)start_info.pt_base;
- unsigned long addr = virt_address, page;
+ pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
+ unsigned long addr = virt_address;
printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base);

#if defined(__x86_64__)
page = tab[l4_table_offset(addr)];
- tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
- printk(" L4 = %p (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr));
-
+ tab = pte_to_virt(page);
+ printk(" L4 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr));
+#endif
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
page = tab[l3_table_offset(addr)];
- tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
- printk(" L3 = %p (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr));
+ tab = pte_to_virt(page);
+ printk(" L3 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr));
#endif
page = tab[l2_table_offset(addr)];
- tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
- printk(" L2 = %p (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr));
+ tab = pte_to_virt(page);
+ printk(" L2 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr));

page = tab[l1_table_offset(addr)];
- printk(" L1 = %p (%p) [offset = %lx]\n", page, tab, l1_table_offset(addr));
+ printk(" L1 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l1_table_offset(addr));

}

#define read_cr2() \
(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)

+static int handling_pg_fault = 0;
+
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
unsigned long addr = read_cr2();
+ /* If we are already handling a page fault, and got another one
+ that means we faulted in pagetable walk. Continuing here would cause
+ a recursive fault */
+ if(handling_pg_fault)
+ {
+ printk("Page fault in pagetable walk (access to invalid memory?).\n");
+ do_exit();
+ }
+ handling_pg_fault = 1;
+
#if defined(__x86_64__)
printk("Page fault at linear address %p, rip %p, code %lx\n",
addr, regs->rip, error_code);
@@ -130,9 +143,12 @@ void do_page_fault(struct pt_regs *regs,
printk("Page fault at linear address %p, eip %p, code %lx\n",
addr, regs->eip, error_code);
#endif
+
dump_regs(regs);
page_walk(addr);
do_exit();
+ /* We should never get here ... but still */
+ handling_pg_fault = 0;
}

void do_general_protection(struct pt_regs *regs, long error_code)
diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/x86_32.S Mon May 22 14:13:38 2006 -0600
@@ -4,9 +4,15 @@
.section __xen_guest
.ascii "GUEST_OS=Mini-OS"
.ascii ",XEN_VER=xen-3.0"
+ .ascii ",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */
+ .ascii ",ELF_PADDR_OFFSET=0xc0000000"
.ascii ",HYPERCALL_PAGE=0x2"
+#ifdef CONFIG_X86_PAE
+ .ascii ",PAE=yes"
+#else
+ .ascii ",PAE=no"
+#endif
.ascii ",LOADER=generic"
- .ascii ",PT_MODE_WRITABLE"
.byte 0
.text

diff -r fbf676a36ee4 -r 72c5d8206d48 extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S Mon May 22 08:53:26 2006 -0600
+++ b/extras/mini-os/x86_64.S Mon May 22 14:13:38 2006 -0600
@@ -4,9 +4,10 @@
.section __xen_guest
.ascii "GUEST_OS=Mini-OS"
.ascii ",XEN_VER=xen-3.0"
+ .ascii ",VIRT_BASE=0xffffffff80000000" /* &_text from minios_x86_64.lds */
+ .ascii ",ELF_PADDR_OFFSET=0xffffffff80000000"
.ascii ",HYPERCALL_PAGE=0x2"
.ascii ",LOADER=generic"
- .ascii ",PT_MODE_WRITABLE"
.byte 0
.text

diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Mon May 22 14:13:38 2006 -0600
@@ -84,13 +84,3 @@ static int __init fixup_init(void)
return 0;
}
__initcall(fixup_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon May 22 14:13:38 2006 -0600
@@ -23,6 +23,8 @@
#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id

+#define VIRT_ENTRY_OFFSET 0x0
+.org VIRT_ENTRY_OFFSET
ENTRY(startup_32)
movl %esi,xen_start_info
cld
@@ -155,6 +157,14 @@ ENTRY(cpu_gdt_table)
.ascii ",XEN_VER=xen-3.0"
.ascii ",VIRT_BASE=0x"
utoa __PAGE_OFFSET
+#ifdef CONFIG_XEN_COMPAT_030002
+ .ascii ",ELF_PADDR_OFFSET=0x"
+ utoa __PAGE_OFFSET
+#else
+ .ascii ",ELF_PADDR_OFFSET=0x0"
+#endif /* !CONFIG_XEN_COMPAT_030002 */
+ .ascii ",VIRT_ENTRY=0x"
+ utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
.ascii ",HYPERCALL_PAGE=0x"
utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
.ascii ",FEATURES=writable_page_tables"
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c Mon May 22 14:13:38 2006 -0600
@@ -342,13 +342,3 @@ dma_sync_single_for_device(struct device
swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
}
EXPORT_SYMBOL(dma_sync_single_for_device);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 22 14:13:38 2006 -0600
@@ -70,9 +70,6 @@

/* Forward Declaration. */
void __init find_max_pfn(void);
-
-/* Allows setting of maximum possible memory size */
-static unsigned long xen_override_max_pfn;

static int xen_panic_event(struct notifier_block *, unsigned long, void *);
static struct notifier_block xen_panic_block = {
@@ -399,6 +396,26 @@ start_info_t *xen_start_info;
start_info_t *xen_start_info;
EXPORT_SYMBOL(xen_start_info);

+static void __init add_memory_region(unsigned long long start,
+ unsigned long long size, int type)
+{
+ int x;
+
+ if (!efi_enabled) {
+ x = e820.nr_map;
+
+ if (x == E820MAX) {
+ printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+ return;
+ }
+
+ e820.map[x].addr = start;
+ e820.map[x].size = size;
+ e820.map[x].type = type;
+ e820.nr_map++;
+ }
+} /* add_memory_region */
+
static void __init limit_regions(unsigned long long size)
{
unsigned long long current_addr = 0;
@@ -442,27 +459,20 @@ static void __init limit_regions(unsigne
}
return;
}
-}
-
-static void __init add_memory_region(unsigned long long start,
- unsigned long long size, int type)
-{
- int x;
-
- if (!efi_enabled) {
- x = e820.nr_map;
-
- if (x == E820MAX) {
- printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
- return;
- }
-
- e820.map[x].addr = start;
- e820.map[x].size = size;
- e820.map[x].type = type;
- e820.nr_map++;
- }
-} /* add_memory_region */
+#ifdef CONFIG_XEN
+ if (i==e820.nr_map && current_addr < size) {
+ /*
+ * The e820 map finished before our requested size so
+ * extend the final entry to the requested address.
+ */
+ --i;
+ if (e820.map[i].type == E820_RAM)
+ e820.map[i].size -= current_addr - size;
+ else
+ add_memory_region(current_addr, size - current_addr, E820_RAM);
+ }
+#endif
+}

#define E820_DEBUG 1

@@ -492,7 +502,6 @@ static void __init print_memory_map(char
}
}

-#if 0
/*
* Sanitize the BIOS e820 map.
*
@@ -680,9 +689,13 @@ static int __init sanitize_e820_map(stru
*/
static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
{
+#ifndef CONFIG_XEN
/* Only one memory region (or negative)? Ignore it */
if (nr_map < 2)
return -1;
+#else
+ BUG_ON(nr_map < 1);
+#endif

do {
unsigned long long start = biosmap->addr;
@@ -694,6 +707,7 @@ static int __init copy_e820_map(struct e
if (start > end)
return -1;

+#ifndef CONFIG_XEN
/*
* Some BIOSes claim RAM in the 640k - 1M region.
* Not right. Fix it up.
@@ -708,11 +722,11 @@ static int __init copy_e820_map(struct e
size = end - start;
}
}
+#endif
add_memory_region(start, size, type);
} while (biosmap++,--nr_map);
return 0;
}
-#endif

#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
struct edd edd;
@@ -785,13 +799,8 @@ static void __init parse_cmdline_early (
unsigned long long mem_size;

mem_size = memparse(from+4, &from);
-#if 0
limit_regions(mem_size);
userdef=1;
-#else
- xen_override_max_pfn =
- (unsigned long)(mem_size>>PAGE_SHIFT);
-#endif
}
}

@@ -984,7 +993,6 @@ static void __init parse_cmdline_early (
}
}

-#if 0 /* !XEN */
/*
* Callback for efi_memory_walk.
*/
@@ -1036,21 +1044,6 @@ void __init find_max_pfn(void)
memory_present(0, start, end);
}
}
-#else
-/* We don't use the fake e820 because we need to respond to user override. */
-void __init find_max_pfn(void)
-{
- if (xen_override_max_pfn == 0) {
- max_pfn = xen_start_info->nr_pages;
- /* Default 8MB slack (to balance backend allocations). */
- max_pfn += 8 << (20 - PAGE_SHIFT);
- } else if (xen_override_max_pfn > xen_start_info->nr_pages) {
- max_pfn = xen_override_max_pfn;
- } else {
- max_pfn = xen_start_info->nr_pages;
- }
-}
-#endif /* XEN */

/*
* Determine low and high memory ranges:
@@ -1158,6 +1151,15 @@ static void __init register_bootmem_low_
*/
last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);

+#ifdef CONFIG_XEN
+ /*
+ * Truncate to the number of actual pages currently
+ * present.
+ */
+ if (last_pfn > xen_start_info->nr_pages)
+ last_pfn = xen_start_info->nr_pages;
+#endif
+
if (last_pfn > max_low_pfn)
last_pfn = max_low_pfn;

@@ -1351,83 +1353,33 @@ void __init remapped_pgdat_init(void)
* and also for regions reported as reserved by the e820.
*/
static void __init
-legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+legacy_init_iomem_resources(struct e820entry *e820, int nr_map,
+ struct resource *code_resource,
+ struct resource *data_resource)
{
int i;
-#ifdef CONFIG_XEN
- dom0_op_t op;
- struct dom0_memory_map_entry *map;
- unsigned long gapstart, gapsize;
- unsigned long long last;
-#endif
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+
+#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
probe_roms();
#endif

-#ifdef CONFIG_XEN
- map = alloc_bootmem_low_pages(PAGE_SIZE);
- op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
- set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
- op.u.physical_memory_map.max_map_entries =
- PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
- BUG_ON(HYPERVISOR_dom0_op(&op));
-
- last = 0x100000000ULL;
- gapstart = 0x10000000;
- gapsize = 0x400000;
-
- for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
+ for (i = 0; i < nr_map; i++) {
struct resource *res;
-
- if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
- gapsize = last - map[i].end;
- gapstart = map[i].end;
- }
- if (map[i].start < last)
- last = map[i].start;
-
- if (map[i].end > 0x100000000ULL)
+ if (e820[i].addr + e820[i].size > 0x100000000ULL)
continue;
res = alloc_bootmem_low(sizeof(struct resource));
- res->name = map[i].is_ram ? "System RAM" : "reserved";
- res->start = map[i].start;
- res->end = map[i].end - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- request_resource(&iomem_resource, res);
- }
-
- free_bootmem(__pa(map), PAGE_SIZE);
-
- /*
- * Start allocating dynamic PCI memory a bit into the gap,
- * aligned up to the nearest megabyte.
- *
- * Question: should we try to pad it up a bit (do something
- * like " + (gapsize >> 3)" in there too?). We now have the
- * technology.
- */
- pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
-
- printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
- pci_mem_start, gapstart, gapsize);
-#else
- for (i = 0; i < e820.nr_map; i++) {
- struct resource *res;
- if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
- continue;
- res = alloc_bootmem_low(sizeof(struct resource));
- switch (e820.map[i].type) {
+ switch (e820[i].type) {
case E820_RAM: res->name = "System RAM"; break;
case E820_ACPI: res->name = "ACPI Tables"; break;
case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
default: res->name = "reserved";
}
- res->start = e820.map[i].addr;
- res->end = res->start + e820.map[i].size - 1;
+ res->start = e820[i].addr;
+ res->end = res->start + e820[i].size - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
- if (e820.map[i].type == E820_RAM) {
+#ifndef CONFIG_XEN
+ if (e820[i].type == E820_RAM) {
/*
* We don't know which RAM region contains kernel data,
* so we try it repeatedly and let the resource manager
@@ -1439,38 +1391,21 @@ legacy_init_iomem_resources(struct resou
request_resource(res, &crashk_res);
#endif
}
- }
-#endif
-}
-
-/*
- * Request address space for all standard resources
- */
-static void __init register_memory(void)
-{
-#ifndef CONFIG_XEN
+#endif
+ }
+}
+
+/*
+ * Locate a unused range of the physical address space below 4G which
+ * can be used for PCI mappings.
+ */
+static void __init
+e820_setup_gap(struct e820entry *e820, int nr_map)
+{
unsigned long gapstart, gapsize, round;
unsigned long long last;
-#endif
- int i;
-
- /* Nothing to do if not running in dom0. */
- if (!(xen_start_info->flags & SIF_INITDOMAIN))
- return;
-
- if (efi_enabled)
- efi_initialize_iomem_resources(&code_resource, &data_resource);
- else
- legacy_init_iomem_resources(&code_resource, &data_resource);
-
- /* EFI systems may still have VGA */
- request_resource(&iomem_resource, &video_ram_resource);
-
- /* request I/O space for devices used on all i[345]86 PCs */
- for (i = 0; i < STANDARD_IO_RESOURCES; i++)
- request_resource(&ioport_resource, &standard_io_resources[i]);
-
-#ifndef CONFIG_XEN
+ int i;
+
/*
* Search for the bigest gap in the low 32 bits of the e820
* memory space.
@@ -1478,10 +1413,10 @@ static void __init register_memory(void)
last = 0x100000000ull;
gapstart = 0x10000000;
gapsize = 0x400000;
- i = e820.nr_map;
+ i = nr_map;
while (--i >= 0) {
- unsigned long long start = e820.map[i].addr;
- unsigned long long end = start + e820.map[i].size;
+ unsigned long long start = e820[i].addr;
+ unsigned long long end = start + e820[i].size;

/*
* Since "last" is at most 4GB, we know we'll
@@ -1511,6 +1446,53 @@ static void __init register_memory(void)

printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
pci_mem_start, gapstart, gapsize);
+}
+
+/*
+ * Request address space for all standard resources
+ */
+static void __init register_memory(void)
+{
+#ifdef CONFIG_XEN
+ struct e820entry *machine_e820;
+ struct xen_memory_map memmap;
+#endif
+ int i;
+
+ /* Nothing to do if not running in dom0. */
+ if (!(xen_start_info->flags & SIF_INITDOMAIN))
+ return;
+
+#ifdef CONFIG_XEN
+ machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
+
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, machine_e820);
+
+ BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
+
+ legacy_init_iomem_resources(machine_e820, memmap.nr_entries,
+ &code_resource, &data_resource);
+#else
+ if (efi_enabled)
+ efi_initialize_iomem_resources(&code_resource, &data_resource);
+ else
+ legacy_init_iomem_resources(e820.map, e820.nr_map,
+ &code_resource, &data_resource);
+#endif
+
+ /* EFI systems may still have VGA */
+ request_resource(&iomem_resource, &video_ram_resource);
+
+ /* request I/O space for devices used on all i[345]86 PCs */
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, &standard_io_resources[i]);
+
+#ifdef CONFIG_XEN
+ e820_setup_gap(machine_e820, memmap.nr_entries);
+ free_bootmem(__pa(machine_e820), PAGE_SIZE);
+#else
+ e820_setup_gap(e820.map, e820.nr_map);
#endif
}

diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c Mon May 22 14:13:38 2006 -0600
@@ -191,6 +191,7 @@ swiotlb_init(void)
if (swiotlb_force == 1) {
swiotlb = 1;
} else if ((swiotlb_force != -1) &&
+ is_running_on_xen() &&
(xen_start_info->flags & SIF_INITDOMAIN)) {
/* Domain 0 always has a swiotlb. */
ram_end = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
@@ -662,13 +663,3 @@ EXPORT_SYMBOL(swiotlb_unmap_page);
EXPORT_SYMBOL(swiotlb_unmap_page);
EXPORT_SYMBOL(swiotlb_dma_mapping_error);
EXPORT_SYMBOL(swiotlb_dma_supported);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Mon May 22 14:13:38 2006 -0600
@@ -1085,13 +1085,3 @@ static int __init xen_sysctl_init(void)
return 0;
}
__initcall(xen_sysctl_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon May 22 14:13:38 2006 -0600
@@ -412,13 +412,3 @@ int write_ldt_entry(void *ldt, int entry
mach_lp, (u64)entry_a | ((u64)entry_b<<32));
}
#endif
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Mon May 22 14:13:38 2006 -0600
@@ -228,6 +228,12 @@ static inline int page_kills_ppro(unsign
return 0;
}

+#else
+
+#define page_kills_ppro(p) 0
+
+#endif
+
extern int is_available_memory(efi_memory_desc_t *);

int page_is_ram(unsigned long pagenr)
@@ -268,13 +274,6 @@ int page_is_ram(unsigned long pagenr)
}
return 0;
}
-
-#else /* CONFIG_XEN */
-
-#define page_kills_ppro(p) 0
-#define page_is_ram(p) 1
-
-#endif

#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Mon May 22 14:13:38 2006 -0600
@@ -478,13 +478,3 @@ void __init bt_iounmap(void *addr, unsig
}

#endif /* __i386__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon May 22 14:13:38 2006 -0600
@@ -640,13 +640,3 @@ void _arch_exit_mmap(struct mm_struct *m
(atomic_read(&mm->mm_count) == 1))
mm_unpin(mm);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Mon May 22 14:13:38 2006 -0600
@@ -141,56 +141,40 @@ xenoprof_ovf_interrupt(int irq, void * d
}


-static void unbind_virq_cpu(void * info)
-{
- int cpu = smp_processor_id();
- if (ovf_irq[cpu] >= 0) {
- unbind_from_irqhandler(ovf_irq[cpu], NULL);
- ovf_irq[cpu] = -1;
- }
-}
-
-
static void unbind_virq(void)
{
- on_each_cpu(unbind_virq_cpu, NULL, 0, 1);
-}
-
-
-int bind_virq_error;
-
-static void bind_virq_cpu(void * info)
-{
- int result;
- int cpu = smp_processor_id();
-
- result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
- cpu,
- xenoprof_ovf_interrupt,
- SA_INTERRUPT,
- "xenoprof",
- NULL);
-
- if (result<0) {
- bind_virq_error = result;
- printk("xenoprof.c: binding VIRQ_XENOPROF to IRQ failed on CPU "
- "%d\n", cpu);
- } else {
- ovf_irq[cpu] = result;
+ int i;
+
+ for_each_cpu(i) {
+ if (ovf_irq[i] >= 0) {
+ unbind_from_irqhandler(ovf_irq[i], NULL);
+ ovf_irq[i] = -1;
+ }
}
}


static int bind_virq(void)
{
- bind_virq_error = 0;
- on_each_cpu(bind_virq_cpu, NULL, 0, 1);
- if (bind_virq_error) {
- unbind_virq();
- return bind_virq_error;
- } else {
- return 0;
- }
+ int i, result;
+
+ for_each_cpu(i) {
+ result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
+ i,
+ xenoprof_ovf_interrupt,
+ SA_INTERRUPT,
+ "xenoprof",
+ NULL);
+
+ if (result < 0) {
+ unbind_virq();
+ return result;
+ }
+
+ ovf_irq[i] = result;
+ }
+
+ return 0;
}


@@ -305,9 +289,13 @@ static int xenoprof_set_active(int * act

for (i=0; i<adomains; i++) {
domid = active_domains[i];
+ if (domid != active_domains[i]) {
+ ret = -EINVAL;
+ goto out;
+ }
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
- return (ret);
+ goto out;
if (active_domains[i] == 0)
set_dom0 = 1;
}
@@ -316,8 +304,11 @@ static int xenoprof_set_active(int * act
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
}
-
- active_defined = 1;
+
+out:
+ if (ret)
+ HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
+ active_defined = !ret;
return ret;
}

diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon May 22 14:13:38 2006 -0600
@@ -514,6 +514,9 @@ setup_arch (char **cmdline_p)
#ifdef CONFIG_XEN
if (running_on_xen) {
extern shared_info_t *HYPERVISOR_shared_info;
+ extern int xen_init (void);
+
+ xen_init ();

/* xen_start_info isn't setup yet, get the flags manually */
if (HYPERVISOR_shared_info->arch.flags & SIF_INITDOMAIN) {
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/ia64/xen/Makefile
--- a/linux-2.6-xen-sparse/arch/ia64/xen/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile Mon May 22 14:13:38 2006 -0600
@@ -2,7 +2,7 @@
# Makefile for Xen components
#

-obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o xenconsole.o xen_ksyms.o
+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o xenconsole.o

obj-$(CONFIG_XEN_IA64_DOM0_VP) += hypervisor.o pci-dma-xen.o util.o
-pci-dma-xen-$(CONFIG_XEN_IA64_DOM0_VP) := ../../i386/kernel/pci-dma-xen.o
\ No newline at end of file
+pci-dma-xen-$(CONFIG_XEN_IA64_DOM0_VP) := ../../i386/kernel/pci-dma-xen.o
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Mon May 22 14:13:38 2006 -0600
@@ -11,17 +11,20 @@ shared_info_t *HYPERVISOR_shared_info =
shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)XSI_BASE;
EXPORT_SYMBOL(HYPERVISOR_shared_info);

-static int initialized;
start_info_t *xen_start_info;
+
+int running_on_xen;
+EXPORT_SYMBOL(running_on_xen);

int xen_init(void)
{
+ static int initialized;
shared_info_t *s = HYPERVISOR_shared_info;

if (initialized)
return running_on_xen ? 0 : -1;

- if (!running_on_xen)
+ if (!is_running_on_xen())
return -1;

xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S Mon May 22 14:13:38 2006 -0600
@@ -7,12 +7,6 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/asmmacro.h>
-
- .data
- .align 8
- .globl running_on_xen
-running_on_xen:
- data4 0

#define isBP p3 // are we the Bootstrap Processor?

@@ -28,9 +22,3 @@ GLOBAL_ENTRY(early_xen_setup)
(p7) mov cr.iva=r10
br.ret.sptk.many rp;;
END(early_xen_setup)
-
-GLOBAL_ENTRY(is_running_on_xen)
- movl r9=running_on_xen;;
- ld4 r8=[r9]
- br.ret.sptk.many rp;;
-END(is_running_on_xen)
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon May 22 14:13:38 2006 -0600
@@ -26,53 +26,34 @@
#include <asm/sections.h>
#include <xen/interface/memory.h>

-unsigned long pci_mem_start = 0xaeedbabe;
-
/*
* PFN of last memory page.
*/
unsigned long end_pfn;
EXPORT_SYMBOL(end_pfn);
-unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;
-unsigned long end_pfn_map;
-
-/*
- * Add a memory region to the kernel e820 map.
- */
-void __init add_memory_region(unsigned long start, unsigned long size, int type)
-{
- int x = e820.nr_map;
-
- if (x == E820MAX) {
- printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
- return;
- }
-
- e820.map[x].addr = start;
- e820.map[x].size = size;
- e820.map[x].type = type;
- e820.nr_map++;
-}
-
-#ifndef CONFIG_XEN

/*
* end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
* The direct mapping extends to end_pfn_map, so that we can directly access
* apertures, ACPI and other tables without having to play with fixmaps.
*/
+unsigned long end_pfn_map;

/*
* Last pfn which the user wants to use.
*/
-
+unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;
+
+#ifndef CONFIG_XEN
extern struct resource code_resource, data_resource;
+#endif

/* Check for some hardcoded bad areas that early boot is not allowed to touch */
static inline int bad_addr(unsigned long *addrp, unsigned long size)
{
unsigned long addr = *addrp, last = addr + size;

+#ifndef CONFIG_XEN
/* various gunk below that needed for SMP startup */
if (addr < 0x8000) {
*addrp = 0x8000;
@@ -100,9 +81,16 @@ static inline int bad_addr(unsigned long
return 1;
}
/* XXX ramdisk image here? */
+#else
+ if (last < (table_end<<PAGE_SHIFT)) {
+ *addrp = table_end << PAGE_SHIFT;
+ return 1;
+ }
+#endif
return 0;
}

+#ifndef CONFIG_XEN
int __init e820_mapped(unsigned long start, unsigned long end, unsigned type)
{
int i;
@@ -116,6 +104,7 @@ int __init e820_mapped(unsigned long sta
}
return 0;
}
+#endif

/*
* Find a free area in a specific range.
@@ -246,22 +235,23 @@ e820_hole_size(unsigned long start_pfn,
/*
* Mark e820 reserved areas as busy for the resource manager.
*/
-void __init e820_reserve_resources(void)
-{
- int i;
- for (i = 0; i < e820.nr_map; i++) {
+void __init e820_reserve_resources(struct e820entry *e820, int nr_map)
+{
+ int i;
+ for (i = 0; i < nr_map; i++) {
struct resource *res;
res = alloc_bootmem_low(sizeof(struct resource));
- switch (e820.map[i].type) {
+ switch (e820[i].type) {
case E820_RAM: res->name = "System RAM"; break;
case E820_ACPI: res->name = "ACPI Tables"; break;
case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
default: res->name = "reserved";
}
- res->start = e820.map[i].addr;
- res->end = res->start + e820.map[i].size - 1;
+ res->start = e820[i].addr;
+ res->end = res->start + e820[i].size - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
+#ifndef CONFIG_XEN
if (e820.map[i].type == E820_RAM) {
/*
* We don't know which RAM region contains kernel data,
@@ -274,9 +264,27 @@ void __init e820_reserve_resources(void)
request_resource(res, &crashk_res);
#endif
}
- }
-}
-#endif /* CONFIG_XEN */
+#endif
+ }
+}
+
+/*
+ * Add a memory region to the kernel e820 map.
+ */
+void __init add_memory_region(unsigned long start, unsigned long size, int type)
+{
+ int x = e820.nr_map;
+
+ if (x == E820MAX) {
+ printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+ return;
+ }
+
+ e820.map[x].addr = start;
+ e820.map[x].size = size;
+ e820.map[x].type = type;
+ e820.nr_map++;
+}

void __init e820_print_map(char *who)
{
@@ -304,7 +312,6 @@ void __init e820_print_map(char *who)
}
}

-#ifndef CONFIG_XEN
/*
* Sanitize the BIOS e820 map.
*
@@ -491,9 +498,13 @@ static int __init sanitize_e820_map(stru
*/
static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
{
+#ifndef CONFIG_XEN
/* Only one memory region (or negative)? Ignore it */
if (nr_map < 2)
return -1;
+#else
+ BUG_ON(nr_map < 1);
+#endif

do {
unsigned long start = biosmap->addr;
@@ -505,6 +516,7 @@ static int __init copy_e820_map(struct e
if (start > end)
return -1;

+#ifndef CONFIG_XEN
/*
* Some BIOSes claim RAM in the 640k - 1M region.
* Not right. Fix it up.
@@ -523,12 +535,14 @@ static int __init copy_e820_map(struct e
size = end - start;
}
}
+#endif

add_memory_region(start, size, type);
} while (biosmap++,--nr_map);
return 0;
}

+#ifndef CONFIG_XEN
void __init setup_memory_region(void)
{
char *who = "BIOS-e820";
@@ -562,104 +576,63 @@ void __init setup_memory_region(void)

#else /* CONFIG_XEN */

-extern unsigned long xen_override_max_pfn;
-extern union xen_start_info_union xen_start_info_union;
-
-unsigned long __init e820_end_of_ram(void)
-{
- unsigned long max_end_pfn;
-
- if (xen_override_max_pfn == 0) {
- max_end_pfn = xen_start_info->nr_pages;
- /* Default 8MB slack (to balance backend allocations). */
- max_end_pfn += 8 << (20 - PAGE_SHIFT);
- } else if (xen_override_max_pfn > xen_start_info->nr_pages) {
- max_end_pfn = xen_override_max_pfn;
- } else {
- max_end_pfn = xen_start_info->nr_pages;
- }
-
- return max_end_pfn;
-}
-
-unsigned long __init
-e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
-{
- return 0;
-}
-
-void __init e820_reserve_resources(void)
-{
- dom0_op_t op;
- struct dom0_memory_map_entry *map;
- unsigned long gapstart, gapsize, round, last;
- int i, found = 0;
-
- if (!(xen_start_info->flags & SIF_INITDOMAIN))
- return;
-
- map = alloc_bootmem_low_pages(PAGE_SIZE);
- op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
- set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
- op.u.physical_memory_map.max_map_entries =
- PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
- BUG_ON(HYPERVISOR_dom0_op(&op));
-
- last = 0x100000000ULL;
- gapstart = 0x10000000;
- gapsize = 0x400000;
-
- for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
- struct resource *res;
-
- if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
- gapsize = last - map[i].end;
- gapstart = map[i].end;
- found = 1;
- }
- if (map[i].start < last)
- last = map[i].start;
-
- if (map[i].end > 0x100000000ULL)
- continue;
- res = alloc_bootmem_low(sizeof(struct resource));
- res->name = map[i].is_ram ? "System RAM" : "reserved";
- res->start = map[i].start;
- res->end = map[i].end - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- request_resource(&iomem_resource, res);
- }
-
- free_bootmem(__pa(map), PAGE_SIZE);
-
- if (!found) {
- gapstart = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
- gapstart = (gapstart << PAGE_SHIFT) + 1024*1024;
- printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
- KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
- }
-
+void __init setup_memory_region(void)
+{
+ int rc;
+ struct xen_memory_map memmap;
/*
- * See how much we want to round up: start off with
- * rounding to the next 1MB area.
+ * This is rather large for a stack variable but this early in
+ * the boot process we know we have plenty slack space.
*/
- round = 0x100000;
- while ((gapsize >> 4) > round)
- round += round;
- /* Fun with two's complement */
- pci_mem_start = (gapstart + round) & -round;
-
- printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
- pci_mem_start, gapstart, gapsize);
-}
-
+ struct e820entry map[E820MAX];
+
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, map);
+
+ rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+ if ( rc == -ENOSYS ) {
+ memmap.nr_entries = 1;
+ map[0].addr = 0ULL;
+ map[0].size = xen_start_info->nr_pages << PAGE_SHIFT;
+ /* 8MB slack (to balance backend allocations). */
+ map[0].size += 8 << 20;
+ map[0].type = E820_RAM;
+ rc = 0;
+ }
+ BUG_ON(rc);
+
+ sanitize_e820_map(map, (char *)&memmap.nr_entries);
+
+ BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);
+
+ printk(KERN_INFO "BIOS-provided physical RAM map:\n");
+ e820_print_map("Xen");
+}
#endif

void __init parse_memopt(char *p, char **from)
{
+ int i;
+ unsigned long current_end;
+ unsigned long end;
+
end_user_pfn = memparse(p, from);
end_user_pfn >>= PAGE_SHIFT;
- xen_override_max_pfn = (unsigned long) end_user_pfn;
+
+ end = end_user_pfn<<PAGE_SHIFT;
+ i = e820.nr_map-1;
+ current_end = e820.map[i].addr + e820.map[i].size;
+
+ if (current_end < end) {
+ /*
+ * The e820 map ends before our requested size so
+ * extend the final entry to the requested address.
+ */
+ if (e820.map[i].type == E820_RAM)
+ e820.map[i].size = end - e820.map[i].addr;
+ else
+ add_memory_region(current_end, end - current_end, E820_RAM);
+ }
}

void __init parse_memmapopt(char *p, char **from)
@@ -683,16 +656,17 @@ void __init parse_memmapopt(char *p, cha
p = *from;
}

+unsigned long pci_mem_start = 0xaeedbabe;
+
/*
* Search for the biggest gap in the low 32 bits of the e820
* memory space. We pass this space to PCI to assign MMIO resources
* for hotplug or unconfigured devices in.
* Hopefully the BIOS let enough space left.
*/
-__init void e820_setup_gap(void)
-{
-#ifndef CONFIG_XEN
- unsigned long gapstart, gapsize;
+__init void e820_setup_gap(struct e820entry *e820, int nr_map)
+{
+ unsigned long gapstart, gapsize, round;
unsigned long last;
int i;
int found = 0;
@@ -700,10 +674,10 @@ __init void e820_setup_gap(void)
last = 0x100000000ull;
gapstart = 0x10000000;
gapsize = 0x400000;
- i = e820.nr_map;
+ i = nr_map;
while (--i >= 0) {
- unsigned long long start = e820.map[i].addr;
- unsigned long long end = start + e820.map[i].size;
+ unsigned long long start = e820[i].addr;
+ unsigned long long end = start + e820[i].size;

/*
* Since "last" is at most 4GB, we know we'll
@@ -729,16 +703,15 @@ __init void e820_setup_gap(void)
}

/*
- * Start allocating dynamic PCI memory a bit into the gap,
- * aligned up to the nearest megabyte.
- *
- * Question: should we try to pad it up a bit (do something
- * like " + (gapsize >> 3)" in there too?). We now have the
- * technology.
+ * See how much we want to round up: start off with
+ * rounding to the next 1MB area.
*/
- pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+ round = 0x100000;
+ while ((gapsize >> 4) > round)
+ round += round;
+ /* Fun with two's complement */
+ pci_mem_start = (gapstart + round) & -round;

printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
-#endif
-}
+}
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Mon May 22 14:13:38 2006 -0600
@@ -24,6 +24,8 @@

.text
.code64
+#define VIRT_ENTRY_OFFSET 0x0
+.org VIRT_ENTRY_OFFSET
.globl startup_64
startup_64:
ENTRY(_start)
@@ -146,8 +148,18 @@ gdt_end:
.section __xen_guest
.ascii "GUEST_OS=linux,GUEST_VER=2.6"
.ascii ",XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0x"; utoh __START_KERNEL_map
- .ascii ",HYPERCALL_PAGE=0x"; utoh (phys_hypercall_page >> PAGE_SHIFT)
+ .ascii ",VIRT_BASE=0x"
+ utoh __START_KERNEL_map
+#ifdef CONFIG_XEN_COMPAT_030002
+ .ascii ",ELF_PADDR_OFFSET=0x"
+ utoh __START_KERNEL_map
+#else
+ .ascii ",ELF_PADDR_OFFSET=0x0"
+#endif /* !CONFIG_XEN_COMPAT_030002 */
+ .ascii ",VIRT_ENTRY=0x"
+ utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
+ .ascii ",HYPERCALL_PAGE=0x"
+ utoh (phys_hypercall_page >> PAGE_SHIFT)
.ascii ",FEATURES=writable_page_tables"
.ascii "|writable_descriptor_tables"
.ascii "|auto_translated_physmap"
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon May 22 14:13:38 2006 -0600
@@ -76,8 +76,8 @@
#include <xen/features.h>
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
-#define end_pfn_map end_pfn
#include <asm/mach-xen/setup_arch_post.h>
+#include <xen/interface/memory.h>

extern unsigned long start_pfn;
extern struct edid_info edid_info;
@@ -490,19 +490,6 @@ static __init void parse_cmdline_early (
}

#ifndef CONFIG_NUMA
-#ifdef CONFIG_XEN
-static void __init
-contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
-{
- unsigned long bootmap_size;
-
- bootmap_size = init_bootmem(start_pfn, end_pfn);
- free_bootmem(0, xen_start_info->nr_pages << PAGE_SHIFT);
- reserve_bootmem(HIGH_MEMORY,
- (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1)
- - HIGH_MEMORY);
-}
-#else
static void __init
contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
{
@@ -513,10 +500,13 @@ contig_initmem_init(unsigned long start_
if (bootmap == -1L)
panic("Cannot find bootmem map of size %ld\n",bootmap_size);
bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+#ifdef CONFIG_XEN
+ e820_bootmem_free(NODE_DATA(0), 0, xen_start_info->nr_pages<<PAGE_SHIFT);
+#else
e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
+#endif
reserve_bootmem(bootmap, bootmap_size);
}
-#endif /* !CONFIG_XEN */
#endif

/* Use inline assembly to define this because the nops are defined
@@ -636,6 +626,11 @@ void __init setup_arch(char **cmdline_p)
{
unsigned long kernel_end;

+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
+ struct e820entry *machine_e820;
+ struct xen_memory_map memmap;
+#endif
+
#ifdef CONFIG_XEN
/* Register a call for panic conditions. */
notifier_chain_register(&panic_notifier_list, &xen_panic_block);
@@ -693,20 +688,18 @@ void __init setup_arch(char **cmdline_p)
rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif
+#endif /* !CONFIG_XEN */
setup_memory_region();
copy_edd();
-#endif /* !CONFIG_XEN */

if (!MOUNT_ROOT_RDONLY)
root_mountflags &= ~MS_RDONLY;
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
-#ifdef CONFIG_XEN
- init_mm.brk = start_pfn << PAGE_SHIFT;
-#else
- init_mm.brk = (unsigned long) &_end;
-
+ init_mm.brk = (unsigned long) &_end;
+
+#ifndef CONFIG_XEN
code_resource.start = virt_to_phys(&_text);
code_resource.end = virt_to_phys(&_etext)-1;
data_resource.start = virt_to_phys(&_etext);
@@ -735,12 +728,11 @@ void __init setup_arch(char **cmdline_p)
#endif

#ifdef CONFIG_NUMA
- numa_initmem_init(start_pfn, end_pfn);
+ numa_initmem_init(0, end_pfn);
#else
- contig_initmem_init(start_pfn, end_pfn);
-#endif
-
-#ifndef CONFIG_XEN
+ contig_initmem_init(0, end_pfn);
+#endif
+
/* Reserve direct mapping */
reserve_bootmem_generic(table_start << PAGE_SHIFT,
(table_end - table_start) << PAGE_SHIFT);
@@ -749,6 +741,10 @@ void __init setup_arch(char **cmdline_p)
kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE);
reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);

+#ifdef CONFIG_XEN
+ /* reserve physmap, start info and initial page tables */
+ reserve_bootmem(kernel_end, (table_start<<PAGE_SHIFT)-kernel_end);
+#else
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
@@ -933,13 +929,25 @@ void __init setup_arch(char **cmdline_p)
prefill_possible_map();
#endif

-#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
/*
* Request address space for all standard RAM and ROM resources
* and also for regions reported as reserved by the e820.
*/
+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
probe_roms();
- e820_reserve_resources();
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
+
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, machine_e820);
+
+ BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
+
+ e820_reserve_resources(machine_e820, memmap.nr_entries);
+ }
+#elif !defined(CONFIG_XEN)
+ probe_roms();
+ e820_reserve_resources(e820.map, e820.nr_map);
#endif

request_resource(&iomem_resource, &video_ram_resource);
@@ -951,7 +959,14 @@ void __init setup_arch(char **cmdline_p)
request_resource(&ioport_resource, &standard_io_resources[i]);
}

- e820_setup_gap();
+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ e820_setup_gap(machine_e820, memmap.nr_entries);
+ free_bootmem(__pa(machine_e820), PAGE_SIZE);
+ }
+#elif !defined(CONFIG_XEN)
+ e820_setup_gap(e820.map, e820.nr_map);
+#endif

#ifdef CONFIG_GART_IOMMU
iommu_hole_init();
diff -r fbf676a36ee4 -r 72c5d8206d48 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 Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Mon May 22 14:13:38 2006 -0600
@@ -370,7 +370,7 @@ void __set_fixmap_user (enum fixed_addre
set_pte_phys(address, phys, prot, SET_FIXMAP_USER);
}

-unsigned long __initdata table_start, tables_space;
+unsigned long __initdata table_start, table_end;

unsigned long get_machine_pfn(unsigned long addr)
{
@@ -409,11 +409,17 @@ static inline int make_readonly(unsigned
{
int readonly = 0;

- /* Make old and new page tables read-only. */
+ /* Make new page tables read-only. */
+ if (!xen_feature(XENFEAT_writable_page_tables)
+ && (paddr >= (table_start << PAGE_SHIFT))
+ && (paddr < (table_end << PAGE_SHIFT)))
+ readonly = 1;
+ /* Make old page tables read-only. */
if (!xen_feature(XENFEAT_writable_page_tables)
&& (paddr >= (xen_start_info->pt_base - __START_KERNEL_map))
- && (paddr < ((table_start << PAGE_SHIFT) + tables_space)))
+ && (paddr < (start_pfn << PAGE_SHIFT)))
readonly = 1;
+
/*
* No need for writable mapping of kernel image. This also ensures that
* page and descriptor tables embedded inside don't have writable
@@ -544,7 +550,7 @@ void __init xen_init_pt(void)
mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
}

-void __init extend_init_mapping(void)
+void __init extend_init_mapping(unsigned long tables_space)
{
unsigned long va = __START_KERNEL_map;
unsigned long phys, addr, *pte_page;
@@ -599,23 +605,23 @@ void __init extend_init_mapping(void)

static void __init find_early_table_space(unsigned long end)
{
- unsigned long puds, pmds, ptes;
+ unsigned long puds, pmds, ptes, tables;

puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT;

- tables_space =
- round_up(puds * 8, PAGE_SIZE) +
+ tables = round_up(puds * 8, PAGE_SIZE) +
round_up(pmds * 8, PAGE_SIZE) +
round_up(ptes * 8, PAGE_SIZE);

- extend_init_mapping();
+ extend_init_mapping(tables);

table_start = start_pfn;
+ table_end = table_start + (tables>>PAGE_SHIFT);

early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n",
- end, table_start << PAGE_SHIFT, start_pfn << PAGE_SHIFT);
+ end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
}

/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
@@ -660,7 +666,7 @@ void __meminit init_memory_mapping(unsig
set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
}

- BUG_ON(!after_bootmem && start_pfn != table_start + (tables_space >> PAGE_SHIFT));
+ BUG_ON(!after_bootmem && start_pfn != table_end);

__flush_tlb_all();
}
@@ -1089,13 +1095,3 @@ int in_gate_area_no_task(unsigned long a
{
return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Mon May 22 14:13:38 2006 -0600
@@ -53,10 +53,9 @@ config TCG_XEN
tristate "XEN TPM Interface"
depends on TCG_TPM && XEN
---help---
- If you want to make TPM support available to a Xen
- user domain, say Yes and it will
- be accessible from within Linux. To compile this driver
- as a module, choose M here; the module will be called
- tpm_xen.
+ If you want to make TPM support available to a Xen user domain,
+ say Yes and it will be accessible from within Linux.
+ To compile this driver as a module, choose M here; the module
+ will be called tpm_xenu.

endmenu
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile Mon May 22 14:13:38 2006 -0600
@@ -8,4 +8,5 @@ obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
-obj-$(CONFIG_TCG_XEN) += tpm_xen.o tpm_vtpm.o
+obj-$(CONFIG_TCG_XEN) += tpm_xenu.o
+tpm_xenu-y = tpm_xen.o tpm_vtpm.o
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Mon May 22 14:13:38 2006 -0600
@@ -416,7 +416,7 @@ static int tpmfront_suspend(struct xenbu
*/
interruptible_sleep_on_timeout(&tp->wait_q, 100);
}
- xenbus_switch_state(dev, XenbusStateClosed);
+ xenbus_switch_state(dev, XenbusStateClosing);

if (atomic_read(&tp->tx_busy)) {
/*
@@ -745,23 +745,12 @@ failexit:

static void __exit tpmif_exit(void)
{
+ exit_tpm_xenbus();
cleanup_vtpm();
tpm_private_put();
- exit_tpm_xenbus();
gnttab_free_grant_references(gref_head);
}

module_init(tpmif_init);
-module_exit(tpmif_exit);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon May 22 14:13:38 2006 -0600
@@ -198,6 +198,22 @@ config XEN_SYSFS
help
Xen hypervisor attributes will show up under /sys/hypervisor/.

+choice
+ prompt "Xen version compatibility"
+ default XEN_COMPAT_030002_AND_LATER
+
+ config XEN_COMPAT_030002_AND_LATER
+ bool "3.0.2 and later"
+
+ config XEN_COMPAT_LATEST_ONLY
+ bool "no compatibility code"
+
+endchoice
+
+config XEN_COMPAT_030002
+ bool
+ default XEN_COMPAT_030002_AND_LATER
+
endmenu

config HAVE_ARCH_ALLOC_SKB
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon May 22 14:13:38 2006 -0600
@@ -468,8 +468,8 @@ static int __init balloon_init(void)

IPRINTK("Initialising balloon driver.\n");

- if (xen_init() < 0)
- return -1;
+ if (!is_running_on_xen())
+ return -ENODEV;

current_pages = min(xen_start_info->nr_pages, max_pfn);
totalram_pages = current_pages;
@@ -603,13 +603,3 @@ EXPORT_SYMBOL_GPL(balloon_dealloc_empty_
EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon May 22 14:13:38 2006 -0600
@@ -526,7 +526,7 @@ static int __init blkif_init(void)
struct page *page;
int i;

- if (xen_init() < 0)
+ if (!is_running_on_xen())
return -ENODEV;

mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
@@ -571,27 +571,10 @@ static int __init blkif_init(void)
list_add_tail(&pending_reqs[i].free_list, &pending_free);

blkif_xenbus_init();
- __unsafe(THIS_MODULE);
+
return 0;
}

module_init(blkif_init);

-static void blkif_exit(void)
-{
- BUG();
-}
-
-module_exit(blkif_exit);
-
MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Mon May 22 14:13:38 2006 -0600
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/vmalloc.h>
+#include <linux/wait.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/pgalloc.h>
@@ -90,21 +91,21 @@ typedef struct blkif_st {
int st_wr_req;
int st_oo_req;

- struct work_struct free_work;
+ wait_queue_head_t waiting_to_free;

grant_handle_t shmem_handle;
grant_ref_t shmem_ref;
} blkif_t;

-blkif_t *alloc_blkif(domid_t domid);
-void free_blkif_callback(blkif_t *blkif);
+blkif_t *blkif_alloc(domid_t domid);
+void blkif_free(blkif_t *blkif);
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);

#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
#define blkif_put(_b) \
do { \
if (atomic_dec_and_test(&(_b)->refcnt)) \
- free_blkif_callback(_b); \
+ wake_up(&(_b)->waiting_to_free);\
} while (0)

/* Create a vbd. */
@@ -133,13 +134,3 @@ int blkif_schedule(void *arg);
int blkif_schedule(void *arg);

#endif /* __BLKIF__BACKEND__COMMON_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Mon May 22 14:13:38 2006 -0600
@@ -35,7 +35,7 @@

static kmem_cache_t *blkif_cachep;

-blkif_t *alloc_blkif(domid_t domid)
+blkif_t *blkif_alloc(domid_t domid)
{
blkif_t *blkif;

@@ -49,6 +49,7 @@ blkif_t *alloc_blkif(domid_t domid)
atomic_set(&blkif->refcnt, 1);
init_waitqueue_head(&blkif->wq);
blkif->st_print = jiffies;
+ init_waitqueue_head(&blkif->waiting_to_free);

return blkif;
}
@@ -138,31 +139,23 @@ int blkif_map(blkif_t *blkif, unsigned l
return 0;
}

-static void free_blkif(void *arg)
+void blkif_free(blkif_t *blkif)
{
- blkif_t *blkif = (blkif_t *)arg;
+ atomic_dec(&blkif->refcnt);
+ wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);

/* Already disconnected? */
- if (blkif->irq) {
+ if (blkif->irq)
unbind_from_irqhandler(blkif->irq, blkif);
- blkif->irq = 0;
- }

vbd_free(&blkif->vbd);

if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
- blkif->blk_ring.sring = NULL;
}

kmem_cache_free(blkif_cachep, blkif);
-}
-
-void free_blkif_callback(blkif_t *blkif)
-{
- INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
- schedule_work(&blkif->free_work);
}

void __init blkif_interface_init(void)
@@ -170,13 +163,3 @@ void __init blkif_interface_init(void)
blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t),
0, 0, NULL, NULL);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Mon May 22 14:13:38 2006 -0600
@@ -55,6 +55,7 @@ int vbd_create(blkif_t *blkif, blkif_vde
unsigned minor, int readonly)
{
struct vbd *vbd;
+ struct block_device *bdev;

vbd = &blkif->vbd;
vbd->handle = handle;
@@ -63,14 +64,16 @@ int vbd_create(blkif_t *blkif, blkif_vde

vbd->pdevice = MKDEV(major, minor);

- vbd->bdev = open_by_devnum(
- vbd->pdevice,
- vbd->readonly ? FMODE_READ : FMODE_WRITE);
- if (IS_ERR(vbd->bdev)) {
- DPRINTK("vbd_creat: device %08x doesn't exist.\n",
+ bdev = open_by_devnum(vbd->pdevice,
+ vbd->readonly ? FMODE_READ : FMODE_WRITE);
+
+ if (IS_ERR(bdev)) {
+ DPRINTK("vbd_creat: device %08x could not be opened.\n",
vbd->pdevice);
return -ENOENT;
}
+
+ vbd->bdev = bdev;

if (vbd->bdev->bd_disk == NULL) {
DPRINTK("vbd_creat: device %08x doesn't exist.\n",
@@ -114,13 +117,3 @@ int vbd_translate(struct phys_req *req,
out:
return rc;
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon May 22 14:13:38 2006 -0600
@@ -108,7 +108,7 @@ static int blkback_remove(struct xenbus_
if (be->blkif) {
if (be->blkif->xenblkd)
kthread_stop(be->blkif->xenblkd);
- blkif_put(be->blkif);
+ blkif_free(be->blkif);
be->blkif = NULL;
}

@@ -140,7 +140,7 @@ static int blkback_probe(struct xenbus_d
be->dev = dev;
dev->data = be;

- be->blkif = alloc_blkif(dev->otherend_id);
+ be->blkif = blkif_alloc(dev->otherend_id);
if (IS_ERR(be->blkif)) {
err = PTR_ERR(be->blkif);
be->blkif = NULL;
@@ -408,14 +408,3 @@ void blkif_xenbus_init(void)
{
xenbus_register_backend(&blkback);
}
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon May 22 14:13:38 2006 -0600
@@ -792,7 +792,7 @@ static struct xenbus_driver blkfront = {

static int __init xlblk_init(void)
{
- if (xen_init() < 0)
+ if (!is_running_on_xen())
return -ENODEV;

return xenbus_register_frontend(&blkfront);
@@ -807,13 +807,3 @@ module_exit(xlblk_exit);
module_exit(xlblk_exit);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Mon May 22 14:13:38 2006 -0600
@@ -153,13 +153,3 @@ void xlvbd_del(struct blkfront_info *inf
void xlvbd_del(struct blkfront_info *info);

#endif /* __XEN_DRIVERS_BLOCK_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Mon May 22 14:13:38 2006 -0600
@@ -315,13 +315,3 @@ xlvbd_del(struct blkfront_info *info)
blk_cleanup_queue(info->rq);
info->rq = NULL;
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon May 22 14:13:38 2006 -0600
@@ -898,13 +898,3 @@ static int __init blkif_init(void)
}

__initcall(blkif_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Mon May 22 14:13:38 2006 -0600
@@ -98,13 +98,3 @@ irqreturn_t blkif_be_int(int irq, void *
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);

#endif /* __BLKIF__BACKEND__COMMON_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Mon May 22 14:13:38 2006 -0600
@@ -132,13 +132,3 @@ void __init blkif_interface_init(void)
blkif_cachep = kmem_cache_create(
"blkif_cache", sizeof(blkif_t), 0, 0, NULL, NULL);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Mon May 22 14:13:38 2006 -0600
@@ -221,13 +221,3 @@ void blkif_xenbus_init(void)
{
xenbus_register_backend(&blkback);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Mon May 22 14:13:38 2006 -0600
@@ -180,13 +180,3 @@ struct file_operations mem_fops = {
.mmap = mmap_mem,
.open = open_mem,
};
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon May 22 14:13:38 2006 -0600
@@ -183,7 +183,7 @@ static struct console kcons_info = {
#define __RETCODE 0
static int __init xen_console_init(void)
{
- if (xen_init() < 0)
+ if (!is_running_on_xen())
return __RETCODE;

if (xen_start_info->flags & SIF_INITDOMAIN) {
@@ -566,7 +566,7 @@ static int __init xencons_init(void)
{
int rc;

- if (xen_init() < 0)
+ if (!is_running_on_xen())
return -ENODEV;

if (xc_mode == XC_OFF)
@@ -636,13 +636,3 @@ module_init(xencons_init);
module_init(xencons_init);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Mon May 22 14:13:38 2006 -0600
@@ -139,13 +139,3 @@ void xencons_resume(void)
{
(void)xencons_ring_init();
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Mon May 22 14:13:38 2006 -0600
@@ -41,10 +41,10 @@
#include <asm/system.h>
#include <asm/ptrace.h>
#include <asm/synch_bitops.h>
+#include <xen/evtchn.h>
#include <xen/interface/event_channel.h>
#include <xen/interface/physdev.h>
#include <asm/hypervisor.h>
-#include <xen/evtchn.h>
#include <linux/mc146818rtc.h> /* RTC_IRQ */

/*
@@ -163,6 +163,12 @@ static inline unsigned int cpu_from_evtc
/* Upcall to generic IRQ layer. */
#ifdef CONFIG_X86
extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
+void __init xen_init_IRQ(void);
+void __init init_IRQ(void)
+{
+ irq_ctx_init(0);
+ xen_init_IRQ();
+}
#if defined (__i386__)
static inline void exit_idle(void) {}
#define IRQ_REG orig_eax
@@ -804,12 +810,10 @@ void irq_resume(void)
}
}

-void __init init_IRQ(void)
+void __init xen_init_IRQ(void)
{
int i;
int cpu;
-
- irq_ctx_init(0);

spin_lock_init(&irq_mapping_update_lock);

@@ -860,13 +864,3 @@ void __init init_IRQ(void)
irq_desc[pirq_to_irq(i)].handler = &pirq_type;
}
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon May 22 14:13:38 2006 -0600
@@ -443,7 +443,7 @@ gnttab_init(void)
{
int i;

- if (xen_init() < 0)
+ if (!is_running_on_xen())
return -ENODEV;

if (gnttab_resume() < 0)
@@ -459,13 +459,3 @@ gnttab_init(void)
}

core_initcall(gnttab_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c Mon May 22 14:13:38 2006 -0600
@@ -49,6 +49,9 @@ static struct kobj_type hyp_sysfs_kobj_t

static int __init hypervisor_subsys_init(void)
{
+ if (!is_running_on_xen())
+ return -ENODEV;
+
hypervisor_subsys.kset.kobj.ktype = &hyp_sysfs_kobj_type;
return subsystem_register(&hypervisor_subsys);
}
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Mon May 22 14:13:38 2006 -0600
@@ -369,13 +369,3 @@ static int __init setup_shutdown_event(v
}

subsys_initcall(setup_shutdown_event);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/skbuff.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c Mon May 22 14:13:38 2006 -0600
@@ -132,13 +132,3 @@ core_initcall(skbuff_init);
core_initcall(skbuff_init);

EXPORT_SYMBOL(__dev_alloc_skb);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Mon May 22 14:13:38 2006 -0600
@@ -107,6 +107,18 @@ void __init smp_alloc_memory(void)
{
}

+static inline void
+set_cpu_sibling_map(int cpu)
+{
+ phys_proc_id[cpu] = cpu;
+ cpu_core_id[cpu] = 0;
+
+ cpu_sibling_map[cpu] = cpumask_of_cpu(cpu);
+ cpu_core_map[cpu] = cpumask_of_cpu(cpu);
+
+ cpu_data[cpu].booted_cores = 1;
+}
+
static void xen_smp_intr_init(unsigned int cpu)
{
sprintf(resched_name[cpu], "resched%d", cpu);
@@ -230,14 +242,20 @@ void __init smp_prepare_cpus(unsigned in
struct Xgt_desc_struct *gdt_descr;
#endif

+ boot_cpu_data.apicid = 0;
cpu_data[0] = boot_cpu_data;

cpu_2_logical_apicid[0] = 0;
x86_cpu_to_apicid[0] = 0;

current_thread_info()->cpu = 0;
- cpu_sibling_map[0] = cpumask_of_cpu(0);
- cpu_core_map[0] = cpumask_of_cpu(0);
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(cpu_core_map[cpu]);
+ }
+
+ set_cpu_sibling_map(0);

xen_smp_intr_init(0);

@@ -262,6 +280,8 @@ void __init smp_prepare_cpus(unsigned in
XENFEAT_writable_descriptor_tables);

cpu_data[cpu] = boot_cpu_data;
+ cpu_data[cpu].apicid = cpu;
+
cpu_2_logical_apicid[cpu] = cpu;
x86_cpu_to_apicid[cpu] = cpu;

@@ -470,6 +490,18 @@ void smp_resume(void)
vcpu_hotplug(i);
}

+static void
+remove_siblinginfo(int cpu)
+{
+ phys_proc_id[cpu] = BAD_APICID;
+ cpu_core_id[cpu] = BAD_APICID;
+
+ cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(cpu_core_map[cpu]);
+
+ cpu_data[cpu].booted_cores = 0;
+}
+
int __cpu_disable(void)
{
cpumask_t map = cpu_online_map;
@@ -477,6 +509,8 @@ int __cpu_disable(void)

if (cpu == 0)
return -EBUSY;
+
+ remove_siblinginfo(cpu);

cpu_clear(cpu, map);
fixup_irqs(map);
@@ -549,6 +583,10 @@ int __devinit __cpu_up(unsigned int cpu)
prepare_for_smp();
#endif

+ /* This must be done before setting cpu_online_map */
+ set_cpu_sibling_map(cpu);
+ wmb();
+
xen_smp_intr_init(cpu);
cpu_set(cpu, cpu_online_map);

@@ -569,13 +607,3 @@ int setup_profiling_timer(unsigned int m
return -EINVAL;
}
#endif
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Mon May 22 14:13:38 2006 -0600
@@ -17,13 +17,3 @@ void remove_xen_proc_entry(const char *n
{
remove_proc_entry(name, xen_base);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Mon May 22 14:13:38 2006 -0600
@@ -276,7 +276,12 @@ static void xen_properties_destroy(void)

static int __init hyper_sysfs_init(void)
{
- int ret = xen_sysfs_type_init();
+ int ret;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ ret = xen_sysfs_type_init();
if (ret)
goto out;
ret = xen_sysfs_version_init();
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Mon May 22 14:13:38 2006 -0600
@@ -429,6 +429,9 @@ static int __init evtchn_init(void)
{
int err;

+ if (!is_running_on_xen())
+ return -ENODEV;
+
spin_lock_init(&port_user_lock);
memset(port_user, 0, sizeof(port_user));

@@ -453,13 +456,3 @@ module_exit(evtchn_cleanup);
module_exit(evtchn_cleanup);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/net_driver_util.c
--- a/linux-2.6-xen-sparse/drivers/xen/net_driver_util.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/net_driver_util.c Mon May 22 14:13:38 2006 -0600
@@ -56,13 +56,3 @@ int xen_net_read_mac(struct xenbus_devic
return 0;
}
EXPORT_SYMBOL_GPL(xen_net_read_mac);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon May 22 14:13:38 2006 -0600
@@ -38,6 +38,7 @@
#include <linux/in.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/wait.h>
#include <xen/evtchn.h>
#include <xen/interface/io/netif.h>
#include <asm/io.h>
@@ -91,7 +92,7 @@ typedef struct netif_st {
struct net_device *dev;
struct net_device_stats stats;

- struct work_struct free_work;
+ wait_queue_head_t waiting_to_free;
} netif_t;

#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
@@ -99,8 +100,7 @@ typedef struct netif_st {

void netif_disconnect(netif_t *netif);

-netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
-void free_netif(netif_t *netif);
+netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
unsigned long rx_ring_ref, unsigned int evtchn);

@@ -108,7 +108,7 @@ int netif_map(netif_t *netif, unsigned l
#define netif_put(_b) \
do { \
if ( atomic_dec_and_test(&(_b)->refcnt) ) \
- free_netif(_b); \
+ wake_up(&(_b)->waiting_to_free); \
} while (0)

void netif_xenbus_init(void);
@@ -121,13 +121,3 @@ irqreturn_t netif_be_int(int irq, void *
irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);

#endif /* __NETIF__BACKEND__COMMON_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon May 22 14:13:38 2006 -0600
@@ -78,7 +78,7 @@ static struct ethtool_ops network_ethtoo
.set_tx_csum = ethtool_op_set_tx_csum,
};

-netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
{
int err = 0, i;
struct net_device *dev;
@@ -97,7 +97,8 @@ netif_t *alloc_netif(domid_t domid, unsi
netif->domid = domid;
netif->handle = handle;
netif->status = DISCONNECTED;
- atomic_set(&netif->refcnt, 0);
+ atomic_set(&netif->refcnt, 1);
+ init_waitqueue_head(&netif->waiting_to_free);
netif->dev = dev;

netif->credit_bytes = netif->remaining_credit = ~0UL;
@@ -273,9 +274,10 @@ err_rx:
return err;
}

-static void free_netif_callback(void *arg)
-{
- netif_t *netif = (netif_t *)arg;
+static void netif_free(netif_t *netif)
+{
+ atomic_dec(&netif->refcnt);
+ wait_event(netif->waiting_to_free, atomic_read(&netif->refcnt) == 0);

if (netif->irq)
unbind_from_irqhandler(netif->irq, netif);
@@ -289,12 +291,6 @@ static void free_netif_callback(void *ar
}

free_netdev(netif->dev);
-}
-
-void free_netif(netif_t *netif)
-{
- INIT_WORK(&netif->free_work, free_netif_callback, (void *)netif);
- schedule_work(&netif->free_work);
}

void netif_disconnect(netif_t *netif)
@@ -308,22 +304,11 @@ void netif_disconnect(netif_t *netif)
__netif_down(netif);
rtnl_unlock();
netif_put(netif);
- break;
+ /* fall through */
case DISCONNECTED:
- BUG_ON(atomic_read(&netif->refcnt) != 0);
- free_netif(netif);
+ netif_free(netif);
break;
default:
BUG();
}
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Mon May 22 14:13:38 2006 -0600
@@ -251,13 +251,3 @@ module_exit(loopback_exit);
module_exit(loopback_exit);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon May 22 14:13:38 2006 -0600
@@ -170,7 +170,9 @@ int netif_be_start_xmit(struct sk_buff *
ret = skb_copy_bits(skb, -hlen, nskb->data - hlen,
skb->len + hlen);
BUG_ON(ret);
+ /* Copy only the header fields we use in this driver. */
nskb->dev = skb->dev;
+ nskb->ip_summed = skb->ip_summed;
nskb->proto_data_valid = skb->proto_data_valid;
dev_kfree_skb(skb);
skb = nskb;
@@ -808,6 +810,9 @@ static int __init netback_init(void)
int i;
struct page *page;

+ if (!is_running_on_xen())
+ return -ENODEV;
+
/* We can increase reservation by this much in net_rx_action(). */
balloon_update_driver_allowance(NET_RX_RING_SIZE);

@@ -848,27 +853,9 @@ static int __init netback_init(void)
&netif_be_dbg);
#endif

- __unsafe(THIS_MODULE);
-
return 0;
}

-static void netback_cleanup(void)
-{
- BUG();
-}
-
module_init(netback_init);
-module_exit(netback_cleanup);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Mon May 22 14:13:38 2006 -0600
@@ -172,7 +172,7 @@ static void backend_changed(struct xenbu
if (be->netif == NULL) {
u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };

- be->netif = alloc_netif(dev->otherend_id, handle, be_mac);
+ be->netif = netif_alloc(dev->otherend_id, handle, be_mac);
if (IS_ERR(be->netif)) {
err = PTR_ERR(be->netif);
be->netif = NULL;
@@ -353,14 +353,3 @@ void netif_xenbus_init(void)
{
xenbus_register_backend(&netback);
}
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon May 22 14:13:38 2006 -0600
@@ -1,25 +1,25 @@
/******************************************************************************
* Virtual network driver for conversing with remote driver backends.
- *
+ *
* Copyright (c) 2002-2005, K A Fraser
* Copyright (c) 2005, XenSource Ltd
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation; or, when distributed
* separately from the Linux kernel or incorporated into other
* software packages, subject to the following license:
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this source file (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -43,7 +43,6 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/bitops.h>
-#include <linux/proc_fs.h>
#include <linux/ethtool.h>
#include <linux/in.h>
#include <net/sock.h>
@@ -65,8 +64,8 @@

#define GRANT_INVALID_REF 0

-#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
+#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)

static inline void init_skb_shinfo(struct sk_buff *skb)
{
@@ -75,16 +74,14 @@ static inline void init_skb_shinfo(struc
skb_shinfo(skb)->frag_list = NULL;
}

-struct netfront_info
-{
+struct netfront_info {
struct list_head list;
struct net_device *netdev;

struct net_device_stats stats;
- unsigned int tx_full;
-
- netif_tx_front_ring_t tx;
- netif_rx_front_ring_t rx;
+
+ struct netif_tx_front_ring tx;
+ struct netif_rx_front_ring rx;

spinlock_t tx_lock;
spinlock_t rx_lock;
@@ -98,16 +95,11 @@ struct netfront_info
#define BEST_CONNECTED 2
unsigned int backend_state;

- /* Is this interface open or closed (down or up)? */
-#define UST_CLOSED 0
-#define UST_OPEN 1
- unsigned int user_state;
-
/* Receive-ring batched refills. */
#define RX_MIN_TARGET 8
#define RX_DFL_MIN_TARGET 64
#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
- int rx_min_target, rx_max_target, rx_target;
+ unsigned rx_min_target, rx_max_target, rx_target;
struct sk_buff_head rx_batch;

struct timer_list rx_refill_timer;
@@ -131,8 +123,8 @@ struct netfront_info
u8 mac[ETH_ALEN];

unsigned long rx_pfn_array[NET_RX_RING_SIZE];
- multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
- mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+ struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
+ struct mmu_update rx_mmu[NET_RX_RING_SIZE];
};

/*
@@ -153,7 +145,7 @@ static inline unsigned short get_id_from
}

#ifdef DEBUG
-static char *be_state_name[] = {
+static const char *be_state_name[] = {
[BEST_CLOSED] = "closed",
[BEST_DISCONNECTED] = "disconnected",
[BEST_CONNECTED] = "connected",
@@ -170,7 +162,7 @@ static char *be_state_name[] = {

static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
static int setup_device(struct xenbus_device *, struct netfront_info *);
-static int create_netdev(int, struct xenbus_device *, struct net_device **);
+static struct net_device *create_netdev(int, struct xenbus_device *);

static void netfront_closing(struct xenbus_device *);

@@ -188,16 +180,13 @@ static int send_fake_arp(struct net_devi

static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs);

-#ifdef CONFIG_PROC_FS
-static int xennet_proc_init(void);
-static int xennet_proc_addif(struct net_device *dev);
-static void xennet_proc_delif(struct net_device *dev);
-#else
-#define xennet_proc_init() (0)
-#define xennet_proc_addif(d) (0)
-#define xennet_proc_delif(d) ((void)0)
+#ifdef CONFIG_SYSFS
+static int xennet_sysfs_addif(struct net_device *netdev);
+static void xennet_sysfs_delif(struct net_device *netdev);
+#else /* !CONFIG_SYSFS */
+#define xennet_sysfs_addif(dev) (0)
+#define xennet_sysfs_delif(dev) do { } while(0)
#endif
-

/**
* Entry point to this code when a new device is created. Allocate the basic
@@ -205,8 +194,8 @@ static void xennet_proc_delif(struct net
* inform the backend of the appropriate details for those. Switch to
* Connected state.
*/
-static int netfront_probe(struct xenbus_device *dev,
- const struct xenbus_device_id *id)
+static int __devinit netfront_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
{
int err;
struct net_device *netdev;
@@ -219,8 +208,9 @@ static int netfront_probe(struct xenbus_
return err;
}

- err = create_netdev(handle, dev, &netdev);
- if (err) {
+ netdev = create_netdev(handle, dev);
+ if (IS_ERR(netdev)) {
+ err = PTR_ERR(netdev);
xenbus_dev_fatal(dev, err, "creating netdev");
return err;
}
@@ -230,7 +220,9 @@ static int netfront_probe(struct xenbus_

err = talk_to_backend(dev, info);
if (err) {
- kfree(info);
+ xennet_sysfs_delif(info->netdev);
+ unregister_netdev(netdev);
+ free_netdev(netdev);
dev->data = NULL;
return err;
}
@@ -325,8 +317,8 @@ again:

static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
{
- netif_tx_sring_t *txs;
- netif_rx_sring_t *rxs;
+ struct netif_tx_sring *txs;
+ struct netif_rx_sring *rxs;
int err;
struct net_device *netdev = info->netdev;

@@ -336,13 +328,13 @@ static int setup_device(struct xenbus_de
info->tx.sring = NULL;
info->irq = 0;

- txs = (netif_tx_sring_t *)__get_free_page(GFP_KERNEL);
+ txs = (struct netif_tx_sring *)__get_free_page(GFP_KERNEL);
if (!txs) {
err = -ENOMEM;
xenbus_dev_fatal(dev, err, "allocating tx ring page");
goto fail;
}
- rxs = (netif_rx_sring_t *)__get_free_page(GFP_KERNEL);
+ rxs = (struct netif_rx_sring *)__get_free_page(GFP_KERNEL);
if (!rxs) {
err = -ENOMEM;
xenbus_dev_fatal(dev, err, "allocating rx ring page");
@@ -447,8 +439,6 @@ static int network_open(struct net_devic

memset(&np->stats, 0, sizeof(np->stats));

- np->user_state = UST_OPEN;
-
network_alloc_rx_buffers(dev);
np->rx.sring->rsp_event = np->rx.rsp_cons + 1;

@@ -457,9 +447,20 @@ static int network_open(struct net_devic
return 0;
}

+static inline void network_maybe_wake_tx(struct net_device *dev)
+{
+ struct netfront_info *np = netdev_priv(dev);
+
+ if (unlikely(netif_queue_stopped(dev)) &&
+ !RING_FULL(&np->tx) &&
+ !gnttab_empty_grant_references(&np->gref_tx_head) &&
+ likely(netif_running(dev)))
+ netif_wake_queue(dev);
+}
+
static void network_tx_buf_gc(struct net_device *dev)
{
- RING_IDX i, prod;
+ RING_IDX cons, prod;
unsigned short id;
struct netfront_info *np = netdev_priv(dev);
struct sk_buff *skb;
@@ -471,15 +472,15 @@ static void network_tx_buf_gc(struct net
prod = np->tx.sring->rsp_prod;
rmb(); /* Ensure we see responses up to 'rp'. */

- for (i = np->tx.rsp_cons; i != prod; i++) {
- id = RING_GET_RESPONSE(&np->tx, i)->id;
+ for (cons = np->tx.rsp_cons; cons != prod; cons++) {
+ id = RING_GET_RESPONSE(&np->tx, cons)->id;
skb = np->tx_skbs[id];
if (unlikely(gnttab_query_foreign_access(
np->grant_tx_ref[id]) != 0)) {
printk(KERN_ALERT "network_tx_buf_gc: warning "
"-- grant still in use by backend "
"domain.\n");
- goto out;
+ break; /* bail immediately */
}
gnttab_end_foreign_access_ref(
np->grant_tx_ref[id], GNTMAP_readonly);
@@ -503,16 +504,9 @@ static void network_tx_buf_gc(struct net
np->tx.sring->rsp_event =
prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
mb();
- } while (prod != np->tx.sring->rsp_prod);
-
- out:
- if ((np->tx_full) &&
- ((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE) &&
- !gnttab_empty_grant_references(&np->gref_tx_head)) {
- np->tx_full = 0;
- if (np->user_state == UST_OPEN)
- netif_wake_queue(dev);
- }
+ } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
+
+ network_maybe_wake_tx(dev);
}


@@ -644,18 +638,11 @@ static int network_start_xmit(struct sk_
{
unsigned short id;
struct netfront_info *np = netdev_priv(dev);
- netif_tx_request_t *tx;
+ struct netif_tx_request *tx;
RING_IDX i;
grant_ref_t ref;
unsigned long mfn;
int notify;
-
- if (unlikely(np->tx_full)) {
- printk(KERN_ALERT "%s: full queue wasn't stopped!\n",
- dev->name);
- netif_stop_queue(dev);
- goto drop;
- }

if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
PAGE_SIZE)) {
@@ -665,7 +652,10 @@ static int network_start_xmit(struct sk_
goto drop;
skb_put(nskb, skb->len);
memcpy(nskb->data, skb->data, skb->len);
+ /* Copy only the header fields we use in this driver. */
nskb->dev = skb->dev;
+ nskb->ip_summed = skb->ip_summed;
+ nskb->proto_data_valid = skb->proto_data_valid;
dev_kfree_skb(skb);
skb = nskb;
}
@@ -708,10 +698,8 @@ static int network_start_xmit(struct sk_
network_tx_buf_gc(dev);

if (RING_FULL(&np->tx) ||
- gnttab_empty_grant_references(&np->gref_tx_head)) {
- np->tx_full = 1;
+ gnttab_empty_grant_references(&np->gref_tx_head))
netif_stop_queue(dev);
- }

spin_unlock_irq(&np->tx_lock);

@@ -737,7 +725,7 @@ static irqreturn_t netif_int(int irq, vo
spin_unlock_irqrestore(&np->tx_lock, flags);

if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx) &&
- (np->user_state == UST_OPEN))
+ likely(netif_running(dev)))
netif_rx_schedule(dev);

return IRQ_HANDLED;
@@ -748,10 +736,10 @@ static int netif_poll(struct net_device
{
struct netfront_info *np = netdev_priv(dev);
struct sk_buff *skb, *nskb;
- netif_rx_response_t *rx;
+ struct netif_rx_response *rx;
RING_IDX i, rp;
- mmu_update_t *mmu = np->rx_mmu;
- multicall_entry_t *mcl = np->rx_mcl;
+ struct mmu_update *mmu = np->rx_mmu;
+ struct multicall_entry *mcl = np->rx_mcl;
int work_done, budget, more_to_do = 1;
struct sk_buff_head rxq;
unsigned long flags;
@@ -898,8 +886,11 @@ static int netif_poll(struct net_device
skb_reserve(nskb, 2);
skb_put(nskb, skb->len);
memcpy(nskb->data, skb->data, skb->len);
+ /* Copy any other fields we already set up. */
nskb->dev = skb->dev;
nskb->ip_summed = skb->ip_summed;
+ nskb->proto_data_valid = skb->proto_data_valid;
+ nskb->proto_csum_blank = skb->proto_csum_blank;
}

/* Reinitialise and then destroy the old skbuff. */
@@ -956,7 +947,6 @@ static int network_close(struct net_devi
static int network_close(struct net_device *dev)
{
struct netfront_info *np = netdev_priv(dev);
- np->user_state = UST_CLOSED;
netif_stop_queue(np->netdev);
return 0;
}
@@ -972,7 +962,7 @@ static void network_connect(struct net_d
{
struct netfront_info *np;
int i, requeue_idx;
- netif_tx_request_t *tx;
+ struct netif_tx_request *tx;
struct sk_buff *skb;

np = netdev_priv(dev);
@@ -981,11 +971,8 @@ static void network_connect(struct net_d

/* Recovery procedure: */

- /* Step 1: Reinitialise variables. */
- np->tx_full = 0;
-
/*
- * Step 2: Rebuild the RX and TX ring contents.
+ * Step 1: Rebuild the RX and TX ring contents.
* NB. We could just free the queued TX packets now but we hope
* that sending them out might do some good. We have to rebuild
* the RX ring because some of our pages are currently flipped out
@@ -1049,7 +1036,7 @@ static void network_connect(struct net_d
RING_PUSH_REQUESTS(&np->rx);

/*
- * Step 3: All public and private state should now be sane. Get
+ * Step 2: All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
* packets.
@@ -1058,9 +1045,6 @@ static void network_connect(struct net_d
notify_remote_via_irq(np->irq);
network_tx_buf_gc(dev);

- if (np->user_state == UST_OPEN)
- netif_start_queue(dev);
-
spin_unlock(&np->rx_lock);
spin_unlock_irq(&np->tx_lock);
}
@@ -1072,7 +1056,7 @@ static void show_device(struct netfront_
IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
np->handle,
be_state_name[np->backend_state],
- np->user_state ? "open" : "closed",
+ netif_running(np->netdev) ? "open" : "closed",
np->evtchn,
np->tx,
np->rx);
@@ -1094,6 +1078,141 @@ static struct ethtool_ops network_ethtoo
.set_tx_csum = ethtool_op_set_tx_csum,
};

+#ifdef CONFIG_SYSFS
+static ssize_t show_rxbuf_min(struct class_device *cd, char *buf)
+{
+ struct net_device *netdev = container_of(cd, struct net_device,
+ class_dev);
+ struct netfront_info *info = netdev_priv(netdev);
+
+ return sprintf(buf, "%u\n", info->rx_min_target);
+}
+
+static ssize_t store_rxbuf_min(struct class_device *cd,
+ const char *buf, size_t len)
+{
+ struct net_device *netdev = container_of(cd, struct net_device,
+ class_dev);
+ struct netfront_info *np = netdev_priv(netdev);
+ char *endp;
+ unsigned long target;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ target = simple_strtoul(buf, &endp, 0);
+ if (endp == buf)
+ return -EBADMSG;
+
+ if (target < RX_MIN_TARGET)
+ target = RX_MIN_TARGET;
+ if (target > RX_MAX_TARGET)
+ target = RX_MAX_TARGET;
+
+ spin_lock(&np->rx_lock);
+ if (target > np->rx_max_target)
+ np->rx_max_target = target;
+ np->rx_min_target = target;
+ if (target > np->rx_target)
+ np->rx_target = target;
+
+ network_alloc_rx_buffers(netdev);
+
+ spin_unlock(&np->rx_lock);
+ return len;
+}
+
+static ssize_t show_rxbuf_max(struct class_device *cd, char *buf)
+{
+ struct net_device *netdev = container_of(cd, struct net_device,
+ class_dev);
+ struct netfront_info *info = netdev_priv(netdev);
+
+ return sprintf(buf, "%u\n", info->rx_max_target);
+}
+
+static ssize_t store_rxbuf_max(struct class_device *cd,
+ const char *buf, size_t len)
+{
+ struct net_device *netdev = container_of(cd, struct net_device,
+ class_dev);
+ struct netfront_info *np = netdev_priv(netdev);
+ char *endp;
+ unsigned long target;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ target = simple_strtoul(buf, &endp, 0);
+ if (endp == buf)
+ return -EBADMSG;
+
+ if (target < RX_MIN_TARGET)
+ target = RX_MIN_TARGET;
+ if (target > RX_MAX_TARGET)
+ target = RX_MAX_TARGET;
+
+ spin_lock(&np->rx_lock);
+ if (target < np->rx_min_target)
+ np->rx_min_target = target;
+ np->rx_max_target = target;
+ if (target < np->rx_target)
+ np->rx_target = target;
+
+ network_alloc_rx_buffers(netdev);
+
+ spin_unlock(&np->rx_lock);
+ return len;
+}
+
+static ssize_t show_rxbuf_cur(struct class_device *cd, char *buf)
+{
+ struct net_device *netdev = container_of(cd, struct net_device,
+ class_dev);
+ struct netfront_info *info = netdev_priv(netdev);
+
+ return sprintf(buf, "%u\n", info->rx_target);
+}
+
+static const struct class_device_attribute xennet_attrs[] = {
+ __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min),
+ __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max),
+ __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL),
+};
+
+static int xennet_sysfs_addif(struct net_device *netdev)
+{
+ int i;
+ int error = 0;
+
+ for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
+ error = class_device_create_file(&netdev->class_dev,
+ &xennet_attrs[i]);
+ if (error)
+ goto fail;
+ }
+ return 0;
+
+ fail:
+ while (--i >= 0)
+ class_device_remove_file(&netdev->class_dev,
+ &xennet_attrs[i]);
+ return error;
+}
+
+static void xennet_sysfs_delif(struct net_device *netdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
+ class_device_remove_file(&netdev->class_dev,
+ &xennet_attrs[i]);
+ }
+}
+
+#endif /* CONFIG_SYSFS */
+
+
/*
* Nothing to do here. Virtual interface is point-to-point and the
* physical interface is probably promiscuous anyway.
@@ -1107,23 +1226,22 @@ static void network_set_multicast_list(s
* @param val return parameter for created device
* @return 0 on success, error code otherwise
*/
-static int create_netdev(int handle, struct xenbus_device *dev,
- struct net_device **val)
+static struct net_device * __devinit create_netdev(int handle,
+ struct xenbus_device *dev)
{
int i, err = 0;
struct net_device *netdev = NULL;
struct netfront_info *np = NULL;

- if ((netdev = alloc_etherdev(sizeof(struct netfront_info))) == NULL) {
+ netdev = alloc_etherdev(sizeof(struct netfront_info));
+ if (!netdev) {
printk(KERN_WARNING "%s> alloc_etherdev failed.\n",
__FUNCTION__);
- err = -ENOMEM;
- goto exit;
+ return ERR_PTR(-ENOMEM);
}

np = netdev_priv(netdev);
np->backend_state = BEST_CLOSED;
- np->user_state = UST_CLOSED;
np->handle = handle;
np->xbdev = dev;

@@ -1163,7 +1281,7 @@ static int create_netdev(int handle, str
printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
gnttab_free_grant_references(np->gref_tx_head);
err = -ENOMEM;
- goto exit;
+ goto exit_free_tx;
}

netdev->open = network_open;
@@ -1180,30 +1298,32 @@ static int create_netdev(int handle, str
SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &dev->dev);

- if ((err = register_netdev(netdev)) != 0) {
+ err = register_netdev(netdev);
+ if (err) {
printk(KERN_WARNING "%s> register_netdev err=%d\n",
__FUNCTION__, err);
- goto exit_free_grefs;
- }
-
- if ((err = xennet_proc_addif(netdev)) != 0) {
- unregister_netdev(netdev);
- goto exit_free_grefs;
+ goto exit_free_rx;
+ }
+
+ err = xennet_sysfs_addif(netdev);
+ if (err) {
+ /* This can be non-fatal: it only means no tuning parameters */
+ printk(KERN_WARNING "%s> add sysfs failed err=%d\n",
+ __FUNCTION__, err);
}

np->netdev = netdev;

+ return netdev;
+
+
+ exit_free_rx:
+ gnttab_free_grant_references(np->gref_rx_head);
+ exit_free_tx:
+ gnttab_free_grant_references(np->gref_tx_head);
exit:
- if (err != 0)
- kfree(netdev);
- else if (val != NULL)
- *val = netdev;
- return err;
-
- exit_free_grefs:
- gnttab_free_grant_references(np->gref_tx_head);
- gnttab_free_grant_references(np->gref_rx_head);
- goto exit;
+ free_netdev(netdev);
+ return ERR_PTR(err);
}

/*
@@ -1245,7 +1365,7 @@ static void netfront_closing(struct xenb
}


-static int netfront_remove(struct xenbus_device *dev)
+static int __devexit netfront_remove(struct xenbus_device *dev)
{
struct netfront_info *info = dev->data;

@@ -1260,16 +1380,9 @@ static int netfront_remove(struct xenbus

static void close_netdev(struct netfront_info *info)
{
- spin_lock_irq(&info->netdev->xmit_lock);
- netif_stop_queue(info->netdev);
- spin_unlock_irq(&info->netdev->xmit_lock);
-
-#ifdef CONFIG_PROC_FS
- xennet_proc_delif(info->netdev);
-#endif
-
del_timer_sync(&info->rx_refill_timer);

+ xennet_sysfs_delif(info->netdev);
unregister_netdev(info->netdev);
}

@@ -1325,7 +1438,7 @@ static struct xenbus_driver netfront = {
.owner = THIS_MODULE,
.ids = netfront_ids,
.probe = netfront_probe,
- .remove = netfront_remove,
+ .remove = __devexit_p(netfront_remove),
.resume = netfront_resume,
.otherend_changed = backend_changed,
};
@@ -1339,14 +1452,12 @@ static struct notifier_block notifier_in

static int __init netif_init(void)
{
- int err = 0;
+ if (!is_running_on_xen())
+ return -ENODEV;

if (xen_start_info->flags & SIF_INITDOMAIN)
return 0;

- if ((err = xennet_proc_init()) != 0)
- return err;
-
IPRINTK("Initialising virtual ethernet driver.\n");

(void)register_inetaddr_notifier(&notifier_inetdev);
@@ -1356,7 +1467,7 @@ module_init(netif_init);
module_init(netif_init);


-static void netif_exit(void)
+static void __exit netif_exit(void)
{
unregister_inetaddr_notifier(&notifier_inetdev);

@@ -1365,167 +1476,3 @@ module_exit(netif_exit);
module_exit(netif_exit);

MODULE_LICENSE("Dual BSD/GPL");
-
-
-/* ** /proc **/
-
-
-#ifdef CONFIG_PROC_FS
-
-#define TARGET_MIN 0UL
-#define TARGET_MAX 1UL
-#define TARGET_CUR 2UL
-
-static int xennet_proc_read(
- char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- struct net_device *dev =
- (struct net_device *)((unsigned long)data & ~3UL);
- struct netfront_info *np = netdev_priv(dev);
- int len = 0, which_target = (long)data & 3;
-
- switch (which_target) {
- case TARGET_MIN:
- len = sprintf(page, "%d\n", np->rx_min_target);
- break;
- case TARGET_MAX:
- len = sprintf(page, "%d\n", np->rx_max_target);
- break;
- case TARGET_CUR:
- len = sprintf(page, "%d\n", np->rx_target);
- break;
- }
-
- *eof = 1;
- return len;
-}
-
-static int xennet_proc_write(
- struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev =
- (struct net_device *)((unsigned long)data & ~3UL);
- struct netfront_info *np = netdev_priv(dev);
- int which_target = (long)data & 3;
- char string[64];
- long target;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (count <= 1)
- return -EBADMSG; /* runt */
- if (count > sizeof(string))
- return -EFBIG; /* too long */
-
- if (copy_from_user(string, buffer, count))
- return -EFAULT;
- string[sizeof(string)-1] = '\0';
-
- target = simple_strtol(string, NULL, 10);
- if (target < RX_MIN_TARGET)
- target = RX_MIN_TARGET;
- if (target > RX_MAX_TARGET)
- target = RX_MAX_TARGET;
-
- spin_lock(&np->rx_lock);
-
- switch (which_target) {
- case TARGET_MIN:
- if (target > np->rx_max_target)
- np->rx_max_target = target;
- np->rx_min_target = target;
- if (target > np->rx_target)
- np->rx_target = target;
- break;
- case TARGET_MAX:
- if (target < np->rx_min_target)
- np->rx_min_target = target;
- np->rx_max_target = target;
- if (target < np->rx_target)
- np->rx_target = target;
- break;
- case TARGET_CUR:
- break;
- }
-
- network_alloc_rx_buffers(dev);
-
- spin_unlock(&np->rx_lock);
-
- return count;
-}
-
-static int xennet_proc_init(void)
-{
- if (proc_mkdir("xen/net", NULL) == NULL)
- return -ENOMEM;
- return 0;
-}
-
-static int xennet_proc_addif(struct net_device *dev)
-{
- struct proc_dir_entry *dir, *min, *max, *cur;
- char name[30];
-
- sprintf(name, "xen/net/%s", dev->name);
-
- dir = proc_mkdir(name, NULL);
- if (!dir)
- goto nomem;
-
- min = create_proc_entry("rxbuf_min", 0644, dir);
- max = create_proc_entry("rxbuf_max", 0644, dir);
- cur = create_proc_entry("rxbuf_cur", 0444, dir);
- if (!min || !max || !cur)
- goto nomem;
-
- min->read_proc = xennet_proc_read;
- min->write_proc = xennet_proc_write;
- min->data = (void *)((unsigned long)dev | TARGET_MIN);
-
- max->read_proc = xennet_proc_read;
- max->write_proc = xennet_proc_write;
- max->data = (void *)((unsigned long)dev | TARGET_MAX);
-
- cur->read_proc = xennet_proc_read;
- cur->write_proc = xennet_proc_write;
- cur->data = (void *)((unsigned long)dev | TARGET_CUR);
-
- return 0;
-
- nomem:
- xennet_proc_delif(dev);
- return -ENOMEM;
-}
-
-static void xennet_proc_delif(struct net_device *dev)
-{
- char name[30];
-
- sprintf(name, "xen/net/%s/rxbuf_min", dev->name);
- remove_proc_entry(name, NULL);
-
- sprintf(name, "xen/net/%s/rxbuf_max", dev->name);
- remove_proc_entry(name, NULL);
-
- sprintf(name, "xen/net/%s/rxbuf_cur", dev->name);
- remove_proc_entry(name, NULL);
-
- sprintf(name, "xen/net/%s", dev->name);
- remove_proc_entry(name, NULL);
-}
-
-#endif
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon May 22 14:13:38 2006 -0600
@@ -271,6 +271,9 @@ static int capabilities_read(char *page,

static int __init privcmd_init(void)
{
+ if (!is_running_on_xen())
+ return -ENODEV;
+
/* Set of hypercalls that privileged applications may execute. */
set_bit(__HYPERVISOR_acm_op, hypercall_permission_map);
set_bit(__HYPERVISOR_dom0_op, hypercall_permission_map);
@@ -293,13 +296,3 @@ static int __init privcmd_init(void)
}

__initcall(privcmd_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Mon May 22 14:13:38 2006 -0600
@@ -45,8 +45,6 @@ typedef struct tpmif_st {
long int tpm_instance;
unsigned long mmap_vstart;

- struct work_struct work;
-
grant_handle_t shmem_handle;
grant_ref_t shmem_ref;
struct page *pagerange;
@@ -82,13 +80,3 @@ extern int num_frontends;
#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))

#endif /* __TPMIF__BACKEND__COMMON_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Mon May 22 14:13:38 2006 -0600
@@ -152,10 +152,8 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
return 0;
}

-static void __tpmif_disconnect_complete(void *arg)
+void tpmif_disconnect_complete(tpmif_t *tpmif)
{
- tpmif_t *tpmif = (tpmif_t *) arg;
-
if (tpmif->irq)
unbind_from_irqhandler(tpmif->irq, tpmif);

@@ -167,29 +165,13 @@ static void __tpmif_disconnect_complete(
free_tpmif(tpmif);
}

-void tpmif_disconnect_complete(tpmif_t * tpmif)
-{
- INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
- schedule_work(&tpmif->work);
-}
-
void __init tpmif_interface_init(void)
{
tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
0, 0, NULL, NULL);
}

-void __init tpmif_interface_exit(void)
+void __exit tpmif_interface_exit(void)
{
kmem_cache_destroy(tpmif_cachep);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Mon May 22 14:13:38 2006 -0600
@@ -1063,7 +1063,7 @@ static int __init tpmback_init(void)

module_init(tpmback_init);

-static void __exit tpmback_exit(void)
+void __exit tpmback_exit(void)
{
vtpm_release_packets(NULL, 0);
tpmif_xenbus_exit();
@@ -1071,16 +1071,4 @@ static void __exit tpmback_exit(void)
misc_deregister(&vtpms_miscdevice);
}

-module_exit(tpmback_exit);
-
MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon May 22 14:13:38 2006 -0600
@@ -150,7 +150,7 @@ static void frontend_changed(struct xenb
break;

case XenbusStateClosing:
- xenbus_switch_state(dev, XenbusStateClosing);
+ be->tpmif->tpm_instance = -1;
break;

case XenbusStateClosed:
@@ -304,13 +304,3 @@ void tpmif_xenbus_exit(void)
{
xenbus_unregister_driver(&tpmback);
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c Mon May 22 14:13:38 2006 -0600
@@ -68,13 +68,3 @@ void unlock_vm_area(struct vm_struct *ar
preempt_enable();
}
EXPORT_SYMBOL_GPL(unlock_vm_area);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Mon May 22 14:13:38 2006 -0600
@@ -133,13 +133,3 @@ EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
EXPORT_SYMBOL_GPL(xenbus_unmap_ring);

MODULE_LICENSE("Dual BSD/GPL");
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon May 22 14:13:38 2006 -0600
@@ -279,14 +279,3 @@ XenbusState xenbus_read_driver_state(con
return result;
}
EXPORT_SYMBOL_GPL(xenbus_read_driver_state);
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Mon May 22 14:13:38 2006 -0600
@@ -206,13 +206,3 @@ int xb_init_comms(void)

return 0;
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Mon May 22 14:13:38 2006 -0600
@@ -41,13 +41,3 @@ extern wait_queue_head_t xb_waitq;
extern wait_queue_head_t xb_waitq;

#endif /* _XENBUS_COMMS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon May 22 14:13:38 2006 -0600
@@ -243,13 +243,3 @@ xenbus_dev_init(void)
}

__initcall(xenbus_dev_init);
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon May 22 14:13:38 2006 -0600
@@ -966,10 +966,8 @@ static int __init xenbus_probe_init(void

DPRINTK("");

- if (xen_init() < 0) {
- DPRINTK("failed");
+ if (!is_running_on_xen())
return -ENODEV;
- }

/* Register ourselves with the kernel bus subsystem */
bus_register(&xenbus_frontend.bus);
@@ -1069,10 +1067,8 @@ static int __init wait_for_devices(void)
{
unsigned long timeout = jiffies + 10*HZ;

- if (xen_init() < 0) {
- DPRINTK("failed");
+ if (!is_running_on_xen())
return -ENODEV;
- }

while (time_before(jiffies, timeout)) {
if (all_devices_ready())
@@ -1085,14 +1081,3 @@ static int __init wait_for_devices(void)
}

late_initcall(wait_for_devices);
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon May 22 14:13:38 2006 -0600
@@ -844,13 +844,3 @@ int xs_init(void)

return 0;
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 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 Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon May 22 14:13:38 2006 -0600
@@ -361,13 +361,3 @@ HYPERVISOR_xenoprof_op(


#endif /* __HYPERCALL_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 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 Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Mon May 22 14:13:38 2006 -0600
@@ -118,7 +118,7 @@ u64 jiffies_to_st(unsigned long jiffies)
#define MULTI_UVMDOMID_INDEX 4
#endif

-#define xen_init() (0)
+#define is_running_on_xen() 1

static inline int
HYPERVISOR_yield(
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon May 22 14:13:38 2006 -0600
@@ -289,9 +289,10 @@ extern int page_is_ram(unsigned long pag
#endif
#define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START)

+#ifdef CONFIG_XEN_COMPAT_030002
#undef LOAD_OFFSET
#define LOAD_OFFSET 0
-
+#endif /* CONFIG_XEN_COMPAT_030002 */

#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon May 22 14:13:38 2006 -0600
@@ -10,10 +10,32 @@

static char * __init machine_specific_memory_setup(void)
{
- unsigned long max_pfn = xen_start_info->nr_pages;
+ int rc;
+ struct xen_memory_map memmap;
+ /*
+ * This is rather large for a stack variable but this early in
+ * the boot process we know we have plenty slack space.
+ */
+ struct e820entry map[E820MAX];

- e820.nr_map = 0;
- add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, map);
+
+ rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+ if ( rc == -ENOSYS ) {
+ memmap.nr_entries = 1;
+ map[0].addr = 0ULL;
+ map[0].size = xen_start_info->nr_pages << PAGE_SHIFT;
+ /* 8MB slack (to balance backend allocations). */
+ map[0].size += 8 << 20;
+ map[0].type = E820_RAM;
+ rc = 0;
+ }
+ BUG_ON(rc);
+
+ sanitize_e820_map(map, (char *)&memmap.nr_entries);
+
+ BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);

return "Xen";
}
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Mon May 22 14:13:38 2006 -0600
@@ -53,7 +53,7 @@ extern start_info_t *xen_start_info;

void force_evtchn_callback(void);

-int xen_init(void);
+#define is_running_on_xen() running_on_xen

/* Turn jiffies into Xen system time. XXX Implement me. */
#define jiffies_to_st(j) 0
@@ -158,7 +158,7 @@ xen_create_contiguous_region(unsigned lo
unsigned int order, unsigned int address_bits)
{
int ret = 0;
- if (running_on_xen) {
+ if (is_running_on_xen()) {
ret = __xen_create_contiguous_region(vstart, order,
address_bits);
}
@@ -169,7 +169,7 @@ static inline void
static inline void
xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
{
- if (running_on_xen)
+ if (is_running_on_xen())
__xen_destroy_contiguous_region(vstart, order);
}

diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h Mon May 22 14:13:38 2006 -0600
@@ -42,12 +42,7 @@
#endif

#ifndef __ASSEMBLY__
-#ifdef MODULE
-extern int is_running_on_xen(void);
-#define running_on_xen (is_running_on_xen())
-#else
extern int running_on_xen;
-#endif

#define XEN_HYPER_SSM_I asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
#define XEN_HYPER_GET_IVR asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
diff -r fbf676a36ee4 -r 72c5d8206d48 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 Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Mon May 22 14:13:38 2006 -0600
@@ -355,19 +355,9 @@ HYPERVISOR_callback_op(

static inline int
HYPERVISOR_xenoprof_op(
- int op, unsigned long arg1, unsigned long arg2)
-{
- return _hypercall3(int, xenoprof_op, op, arg1, arg2);
+ int op, void *arg)
+{
+ return _hypercall2(int, xenoprof_op, op, arg);
}

#endif /* __HYPERCALL_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Mon May 22 14:13:38 2006 -0600
@@ -260,8 +260,10 @@ static inline pgd_t __pgd(unsigned long
#define __PAGE_OFFSET 0xffff880000000000
#endif /* !__ASSEMBLY__ */

+#ifdef CONFIG_XEN_COMPAT_030002
#undef LOAD_OFFSET
#define LOAD_OFFSET 0
+#endif /* CONFIG_XEN_COMPAT_030002 */

/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/balloon.h
--- a/linux-2.6-xen-sparse/include/xen/balloon.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/balloon.h Mon May 22 14:13:38 2006 -0600
@@ -61,13 +61,3 @@ extern spinlock_t balloon_lock;
#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)

#endif /* __ASM_BALLOON_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/xen/driver_util.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/driver_util.h Mon May 22 14:13:38 2006 -0600
@@ -14,13 +14,3 @@ extern void unlock_vm_area(struct vm_str
extern void unlock_vm_area(struct vm_struct *area);

#endif /* __ASM_XEN_DRIVER_UTIL_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/evtchn.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/evtchn.h Mon May 22 14:13:38 2006 -0600
@@ -112,13 +112,3 @@ extern void notify_remote_via_irq(int ir
extern void notify_remote_via_irq(int irq);

#endif /* __ASM_EVTCHN_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/foreign_page.h
--- a/linux-2.6-xen-sparse/include/xen/foreign_page.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/foreign_page.h Mon May 22 14:13:38 2006 -0600
@@ -28,13 +28,3 @@
( (void (*) (struct page *)) (page)->mapping )

#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Mon May 22 14:13:38 2006 -0600
@@ -148,13 +148,3 @@ gnttab_set_unmap_op(struct gnttab_unmap_
}

#endif /* __ASM_GNTTAB_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/net_driver_util.h
--- a/linux-2.6-xen-sparse/include/xen/net_driver_util.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/net_driver_util.h Mon May 22 14:13:38 2006 -0600
@@ -46,13 +46,3 @@ int xen_net_read_mac(struct xenbus_devic


#endif /* _ASM_XEN_NET_DRIVER_UTIL_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/public/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h Mon May 22 14:13:38 2006 -0600
@@ -89,13 +89,3 @@ struct ioctl_evtchn_notify {
_IOC(_IOC_NONE, 'E', 5, 0)

#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/public/privcmd.h
--- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h Mon May 22 14:13:38 2006 -0600
@@ -75,13 +75,3 @@ typedef struct privcmd_mmapbatch {
_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))

#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/xen_proc.h
--- a/linux-2.6-xen-sparse/include/xen/xen_proc.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xen_proc.h Mon May 22 14:13:38 2006 -0600
@@ -11,13 +11,3 @@ extern void remove_xen_proc_entry(
const char *name);

#endif /* __ASM_XEN_PROC_H__ */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Mon May 22 08:53:26 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Mon May 22 14:13:38 2006 -0600
@@ -294,13 +294,3 @@ void xenbus_dev_fatal(struct xenbus_devi


#endif /* _XEN_XENBUS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fbf676a36ee4 -r 72c5d8206d48 patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch Mon May 22 08:53:26 2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Mon May 22 14:13:38 2006 -0600
@@ -225,19 +225,21 @@ diff -pruN ../pristine-linux-2.6.16.13/d
struct oprofile_operations oprofile_ops;

unsigned long oprofile_started;
-@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
+@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
*/
static int timer = 0;

-+extern unsigned int adomains;
-+extern int active_domains[MAX_OPROF_DOMAINS];
-+
-+int oprofile_set_active(void)
++int oprofile_set_active(int active_domains[], unsigned int adomains)
+{
-+ if (oprofile_ops.set_active)
-+ return oprofile_ops.set_active(active_domains, adomains);
-+
-+ return -EINVAL;
++ int err;
++
++ if (!oprofile_ops.set_active)
++ return -EINVAL;
++
++ down(&start_sem);
++ err = oprofile_ops.set_active(active_domains, adomains);
++ up(&start_sem);
++ return err;
+}
+
int oprofile_setup(void)
@@ -251,7 +253,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d

int oprofile_set_backtrace(unsigned long depth);
+
-+int oprofile_set_active(void);
++int oprofile_set_active(int active_domains[], unsigned int adomains);

#endif /* OPROF_H */
diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
@@ -280,7 +282,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
unsigned long fs_buffer_size = 131072;
unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file *
+@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file *
static struct file_operations dump_fops = {
.write = dump_write,
};
@@ -288,63 +290,92 @@ diff -pruN ../pristine-linux-2.6.16.13/d
+
+#define TMPBUFSIZE 512
+
-+unsigned int adomains = 0;
-+long active_domains[MAX_OPROF_DOMAINS];
++static unsigned int adomains = 0;
++static int active_domains[MAX_OPROF_DOMAINS + 1];
++static DEFINE_MUTEX(adom_mutex);
+
+static ssize_t adomain_write(struct file * file, char const __user * buf,
+ size_t count, loff_t * offset)
+{
-+ char tmpbuf[TMPBUFSIZE];
-+ char * startp = tmpbuf;
-+ char * endp = tmpbuf;
++ char *tmpbuf;
++ char *startp, *endp;
+ int i;
+ unsigned long val;
++ ssize_t retval = count;
+
+ if (*offset)
+ return -EINVAL;
-+ if (!count)
-+ return 0;
+ if (count > TMPBUFSIZE - 1)
+ return -EINVAL;
+
-+ memset(tmpbuf, 0x0, TMPBUFSIZE);
-+
-+ if (copy_from_user(tmpbuf, buf, count))
++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++ return -ENOMEM;
++
++ if (copy_from_user(tmpbuf, buf, count)) {
++ kfree(tmpbuf);
+ return -EFAULT;
-+
-+ for (i = 0; i < MAX_OPROF_DOMAINS; i++)
-+ active_domains[i] = -1;
-+ adomains = 0;
-+
-+ while (1) {
-+ val = simple_strtol(startp, &endp, 0);
++ }
++ tmpbuf[count] = 0;
++
++ mutex_lock(&adom_mutex);
++
++ startp = tmpbuf;
++ /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
++ for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
++ val = simple_strtoul(startp, &endp, 0);
+ if (endp == startp)
+ break;
-+ while (ispunct(*endp))
++ while (ispunct(*endp) || isspace(*endp))
+ endp++;
-+ active_domains[adomains++] = val;
-+ if (adomains >= MAX_OPROF_DOMAINS)
-+ break;
++ active_domains[i] = val;
++ if (active_domains[i] != val)
++ /* Overflow, force error below */
++ i = MAX_OPROF_DOMAINS + 1;
+ startp = endp;
+ }
-+ if (oprofile_set_active())
-+ return -EINVAL;
-+ return count;
++ /* Force error on trailing junk */
++ adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
++
++ kfree(tmpbuf);
++
++ if (adomains > MAX_OPROF_DOMAINS
++ || oprofile_set_active(active_domains, adomains)) {
++ adomains = 0;
++ retval = -EINVAL;
++ }
++
++ mutex_unlock(&adom_mutex);
++ return retval;
+}
+
+static ssize_t adomain_read(struct file * file, char __user * buf,
+ size_t count, loff_t * offset)
+{
-+ char tmpbuf[TMPBUFSIZE];
-+ size_t len = 0;
++ char * tmpbuf;
++ size_t len;
+ int i;
-+ /* This is all screwed up if we run out of space */
-+ for (i = 0; i < adomains; i++)
-+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len,
-+ "%u ", (unsigned int)active_domains[i]);
-+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
-+ return simple_read_from_buffer((void __user *)buf, count,
-+ offset, tmpbuf, len);
++ ssize_t retval;
++
++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++ return -ENOMEM;
++
++ mutex_lock(&adom_mutex);
++
++ len = 0;
++ for (i = 0; i < adomains; i++)
++ len += snprintf(tmpbuf + len,
++ len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
++ "%u ", active_domains[i]);
++ WARN_ON(len > TMPBUFSIZE);
++ if (len != 0 && len <= TMPBUFSIZE)
++ tmpbuf[len-1] = '\n';
++
++ mutex_unlock(&adom_mutex);
++
++ retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
++
++ kfree(tmpbuf);
++ return retval;
+}
+
+
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/README
--- a/tools/examples/README Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/README Mon May 22 14:13:38 2006 -0600
@@ -13,6 +13,10 @@ block-common.sh - sourced by block,
block-common.sh - sourced by block, block-*
block-enbd - binds/unbinds network block devices
block-nbd - binds/unbinds network block devices
+external-device-migrate - called by xend for migrating external devices
+locking.sh - locking functions to prevent concurrent access to
+ critical sections inside script files
+logging.sh - logging function to log output using syslog
network-bridge - xen network start/stop script when using bridging
network-nat - xen network start/stop script when using NAT
network-route - xen network start/stop script when using routing
@@ -20,7 +24,14 @@ vif-common.sh - sourced by vif-bri
vif-common.sh - sourced by vif-bridge
vif-nat - xen virtual network start/stop script in NAT mode
vif-route - xen virtual network start/stop script in routed mode
-xen-backend.agent - calls block, vif-* scripts to add, remove, hotplug
+vtpm - called by xen-backend.agent to bind/unbind vTPM devices
+vtpm-addtodb - script for adding a vTPM instance to the vTPM table
+vtpm-common.sh - common code for vTPM handling
+vtpm-delete - remove an entry from the vTPM table given the
+ domain's name
+vtpm-hotplug-common.sh - sourced by vtpm
+vtpm-migration.sh - sourced by external-device-migrate
+xen-backend.agent - calls block, vif-*, vtpm scripts to add, remove, hotplug
devices
xen-backend.rules - hotplug script rules
xend-config.sxp - default xend configuration file
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/external-device-migrate Mon May 22 14:13:38 2006 -0600
@@ -27,59 +27,85 @@ dir=$(dirname "$0")
. "$dir/logging.sh"


-function usage() {
- echo " Pass the following command line paremeters to the script:"
- echo ""
- echo "-step <n> : n-th migration step"
- echo "-host <host> : the destination host"
- echo "-domname <domain name> : name of the domain that is migrating"
- echo "-type <device type> : the type of device that is migrating"
- echo "-recover : indicates recovery request; an error"
- echo " occurred during migration"
- echo "-help : display this help screen"
+function ext_dev_migrate_usage() {
+cat <<EOF
+Pass the following command line parameters to the script:
+
+-step <n> : n-th migration step
+-host <host> : the destination host
+-domname <domain name> : name of the domain that is migrating
+-type <device type> : the type of device that is migrating
+-subtype <dev. subtype>: the subtype of the device
+-recover : indicates recovery request; an error
+ occurred during migration
+-help : display this help screen
+EOF
}

-while [ 1 ]; do
- if [ "$1" == "-step" ]; then
+# Parse the command line paramters. The following parameters must be
+# passed as the first ones in the sequence:
+# -step [required]
+# -host [required]
+# -domname [required]
+# -type [required]
+# -subtype [optional]
+# -recover [optional]
+# The remaining ones will be passed to the called function.
+function evaluate_params()
+{
+ local step host domname typ recover filename func stype
+ stype=""
+ while [ 1 ]; do
+ if [ "$1" == "-step" ]; then
+ shift
+ step=$1
+ elif [ "$1" == "-host" ]; then
+ shift
+ host=$1
+ elif [ "$1" == "-domname" ]; then
+ shift
+ domname=$1
+ elif [ "$1" == "-type" ]; then
+ shift
+ typ=$1
+ elif [ "$1" == "-subtype" ]; then
+ shift
+ stype="_$1"
+ elif [ "$1" == "-recover" ]; then
+ recover=1
+ elif [ "$1" == "-help" ]; then
+ ext_dev_migrate_usage
+ exit
+ else
+ break
+ fi
shift
- step=$1
- elif [ "$1" == "-host" ]; then
- shift
- host=$1
- elif [ "$1" == "-domname" ]; then
- shift
- domname=$1
- elif [ "$1" == "-type" ]; then
- shift
- typ=$1
- elif [ "$1" == "-recover" ]; then
- recover=1
- elif [ "$1" == "-help" ]; then
- usage
+ done
+
+ if [. "$step" == "" -o \
+ "$host" == "" -o \
+ "$typ" == "" -o \
+ "$domname" == "" ]; then
+ echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
+ echo ""
+ echo "$0 -help for usage."
exit
+ fi
+
+ filename="$dir/$typ$stype-migration.sh"
+ if [ ! -r $filename ]; then
+ echo "Error: Could not find script '$filename'"
+ return
+ fi
+ . "$filename"
+
+ if [ "$recover" == "1" ]; then
+ func="$typ"_recover
+ eval $func $host $domname $step $*
else
- break
+ func="$typ"_migration_step
+ eval $func $host $domname $step $*
fi
- shift
-done
+}

-if [. "$step" == "" -o \
- "$host" == "" -o \
- "$typ" == "" -o \
- "$domname" == "" ]; then
- echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
-set
- echo ""
- echo "$0 --help for usage."
- exit
-fi
-
-. "$dir/$typ-migration.sh"
-
-if [ "$recover" == "1" ]; then
- func="$typ"_recover
- eval $func $host $domname $step
-else
- func="$typ"_migration_step
- eval $func $host $domname $step
-fi
+evaluate_params $*
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/network-bridge
--- a/tools/examples/network-bridge Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/network-bridge Mon May 22 14:13:38 2006 -0600
@@ -59,7 +59,7 @@ findCommand "$@"
findCommand "$@"
evalVariables "$@"

-vifnum=${vifnum:-$(ip route list | awk '/^default / { sub(/eth/,"",$NF); print $NF }')}
+vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')}
bridge=${bridge:-xenbr${vifnum}}
netdev=${netdev:-eth${vifnum}}
antispoof=${antispoof:-no}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/vtpm
--- a/tools/examples/vtpm Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/vtpm Mon May 22 14:13:38 2006 -0600
@@ -23,5 +23,6 @@ if [ $vtpm_fatal_error -eq 0 ]; then
if [ $vtpm_fatal_error -eq 0 ]; then
log debug "Successful vTPM operation '$command'."
success
+else
+ fatal "Error while executing vTPM operation '$command'."
fi
-
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/vtpm-common.sh Mon May 22 14:13:38 2006 -0600
@@ -64,8 +64,10 @@ fi
# Returns '0' if instance number could not be found, otherwise
# it returns the instance number in the variable 'instance'
function vtpmdb_find_instance () {
- local vmname=$1
- local ret=0
+ local vmname ret instance
+ vmname=$1
+ ret=0
+
instance=$(cat $VTPMDB | \
awk -vvmname=$vmname \
'{ \
@@ -86,8 +88,9 @@ function vtpmdb_find_instance () {
# Check whether a particular instance number is still available
# returns "0" if it is not available, "1" otherwise.
function vtpmdb_is_free_instancenum () {
- local instance=$1
- local avail=1
+ local instance instances avail i
+ instance=$1
+ avail=1
#Allowed instance number range: 1-255
if [ $instance -eq 0 -o $instance -gt 255 ]; then
avail=0
@@ -113,9 +116,7 @@ function vtpmdb_is_free_instancenum () {
# Get an available instance number given the database
# Returns an unused instance number
function vtpmdb_get_free_instancenum () {
- local ctr
- local instances
- local don
+ local ctr instances don found
instances=$(cat $VTPMDB | \
gawk \
'{ \
@@ -126,7 +127,6 @@ function vtpmdb_get_free_instancenum ()
ctr=1
don=0
while [ $don -eq 0 ]; do
- local found
found=0
for i in $instances; do
if [ $i -eq $ctr ]; then
@@ -147,8 +147,9 @@ function vtpmdb_get_free_instancenum ()

# Add a domain name and instance number to the DB file
function vtpmdb_add_instance () {
- local vmname=$1
- local inst=$2
+ local res vmname inst
+ vmname=$1
+ inst=$2

if [ ! -f $VTPMDB ]; then
echo "#Database for VM to vTPM association" > $VTPMDB
@@ -165,9 +166,10 @@ function vtpmdb_add_instance () {
#Validate whether an entry is the same as passed to this
#function
function vtpmdb_validate_entry () {
- local rc=0
- local vmname=$1
- local inst=$2
+ local res rc vmname inst
+ rc=0
+ vmname=$1
+ inst=$2

res=$(cat $VTPMDB | \
gawk -vvmname=$vmname \
@@ -188,9 +190,9 @@ function vtpmdb_validate_entry () {
}')

if [ "$res" == "1" ]; then
- let rc=1
+ rc=1
elif [ "$res" == "2" ]; then
- let rc=2
+ rc=2
fi
echo "$rc"
}
@@ -199,9 +201,11 @@ function vtpmdb_validate_entry () {
#Remove an entry from the vTPM database given its domain name
#and instance number
function vtpmdb_remove_entry () {
- local vmname=$1
- local instance=$2
- local VTPMDB_TMP="$VTPMDB".tmp
+ local vmname instance VTPMDB_TMP
+ vmname=$1
+ instance=$2
+ VTPMDB_TMP="$VTPMDB".tmp
+
$(cat $VTPMDB | \
gawk -vvmname=$vmname \
'{ \
@@ -219,13 +223,14 @@ function vtpmdb_remove_entry () {


# Find the reason for the creation of this device:
-# Set global REASON variable to 'resume' or 'create'
+# Returns 'resume' or 'create'
function vtpm_get_create_reason () {
- local resume=$(xenstore-read $XENBUS_PATH/resume)
+ local resume
+ resume=$(xenstore-read $XENBUS_PATH/resume)
if [ "$resume" == "True" ]; then
- REASON="resume"
- else
- REASON="create"
+ echo "resume"
+ else
+ echo "create"
fi
}

@@ -234,10 +239,9 @@ function vtpm_get_create_reason () {
# If no entry in the TPM database is found, the instance is
# created and an entry added to the database.
function vtpm_create_instance () {
- local domname=$(xenstore_read "$XENBUS_PATH"/domain)
- local res
- local instance
- vtpm_get_create_reason
+ local res instance domname reason
+ domname=$(xenstore_read "$XENBUS_PATH"/domain)
+ reason=$(vtpm_get_create_reason)

claim_lock vtpmdb
instance=$(vtpmdb_find_instance $domname)
@@ -252,20 +256,20 @@ function vtpm_create_instance () {
else
instance=$(vtpmdb_get_free_instancenum)
fi
- vtpmdb_add_instance $domname $instance
- if [ "$REASON" == "create" ]; then
+ if [ "$reason" == "create" ]; then
vtpm_create $instance
- elif [ "$REASON" == "resume" ]; then
+ else
vtpm_resume $instance $domname
- else
- #default case for 'now'
- vtpm_create $instance
+ fi
+ if [ $vtpm_fatal_error -eq 0 ]; then
+ vtpmdb_add_instance $domname $instance
fi
fi

release_lock vtpmdb

- if [ "$REASON" == "create" ]; then
+ if [ $vtpm_fatal_error -eq 0 -a \
+ "$reason" == "create" ]; then
vtpm_reset $instance
fi
xenstore_write $XENBUS_PATH/instance $instance
@@ -276,15 +280,18 @@ function vtpm_create_instance () {
#Since it is assumed that the VM will appear again, the
#entry is kept in the VTPMDB file.
function vtpm_remove_instance () {
- local domname=$(xenstore_read "$XENBUS_PATH"/domain)
-
- claim_lock vtpmdb
-
- instance=$(vtpmdb_find_instance $domname)
-
- if [ "$instance" != "0" ]; then
- if [ "$REASON" == "suspend" ]; then
- vtpm_suspend $instance
+ local instance reason domname
+ domname=$(xenstore_read "$XENBUS_PATH"/domain)
+
+ if [ "$doname" != "" ]; then
+ claim_lock vtpmdb
+
+ instance=$(vtpmdb_find_instance $domname)
+
+ if [ "$instance" != "0" ]; then
+ if [ "$reason" == "suspend" ]; then
+ vtpm_suspend $instance
+ fi
fi
fi

@@ -295,7 +302,7 @@ function vtpm_remove_instance () {
#Remove an entry in the VTPMDB file given the domain's name
#1st parameter: The name of the domain
function vtpm_delete_instance () {
- local rc
+ local instance

claim_lock vtpmdb

@@ -313,20 +320,21 @@ function vtpm_delete_instance () {
# "0" : this is not an address of this machine
# "1" : this is an address local to this machine
function isLocalAddress() {
- local addr=$(ping $1 -c 1 | \
- gawk '{ print substr($3,2,length($3)-2); exit }')
+ local addr res
+ addr=$(ping $1 -c 1 | \
+ gawk '{ print substr($3,2,length($3)-2); exit }')
if [ "$addr" == "" ]; then
echo "-1"
return
fi
- local res=$(ifconfig | grep "inet addr" | \
- gawk -vaddr=$addr \
- '{ \
- if ( addr == substr($2, 6)) {\
- print "1"; \
- } \
- }' \
- )
+ res=$(ifconfig | grep "inet addr" | \
+ gawk -vaddr=$addr \
+ '{ \
+ if ( addr == substr($2, 6)) {\
+ print "1"; \
+ } \
+ }' \
+ )
if [ "$res" == "" ]; then
echo "0"
return
@@ -341,7 +349,8 @@ function isLocalAddress() {
# 2nd: name of the domain to migrate
# 3rd: the migration step to perform
function vtpm_migration_step() {
- local instance=$(vtpmdb_find_instance $2)
+ local instance res
+ instance=$(vtpmdb_find_instance $2)
if [ "$instance" == "" ]; then
echo "Error: Translation of domain name ($2) to instance failed. Check /etc/xen/vtpm.db"
log err "Error during translation of domain name"
@@ -360,6 +369,7 @@ function vtpm_migration_step() {
# 2nd: name of the domain that was to be migrated
# 3rd: the last successful migration step that was done
function vtpm_recover() {
+ local res
res=$(isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate_recover $1 $2 $3
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/xmexample.hvm Mon May 22 14:13:38 2006 -0600
@@ -29,6 +29,10 @@ memory = 128

# A name for your domain. All domains must have different names.
name = "ExampleHVMDomain"
+
+# 128-bit UUID for the domain. The default behavior is to generate a new UUID
+# on each call to 'xm create'.
+#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"

#-----------------------------------------------------------------------------
# the number of cpus guest platform has, default=1
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/xmexample1
--- a/tools/examples/xmexample1 Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/xmexample1 Mon May 22 14:13:38 2006 -0600
@@ -25,6 +25,10 @@ memory = 64

# A name for your domain. All domains must have different names.
name = "ExampleDomain"
+
+# 128-bit UUID for the domain. The default behavior is to generate a new UUID
+# on each call to 'xm create'.
+#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"

# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/xmexample2
--- a/tools/examples/xmexample2 Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/xmexample2 Mon May 22 14:13:38 2006 -0600
@@ -54,6 +54,10 @@ memory = 64
# A name for the new domain. All domains have to have different names,
# so we use the vmid to create a name.
name = "VM%d" % vmid
+
+# 128-bit UUID for the domain. The default behavior is to generate a new UUID
+# on each call to 'xm create'.
+#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"

# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/examples/xmexample3
--- a/tools/examples/xmexample3 Mon May 22 08:53:26 2006 -0600
+++ b/tools/examples/xmexample3 Mon May 22 14:13:38 2006 -0600
@@ -54,6 +54,10 @@ memory = 64
# A name for the new domain. All domains have to have different names,
# so we use the vmid to create a name.
name = "VM%d" % vmid
+
+# 128-bit UUID for the domain. The default behavior is to generate a new UUID
+# on each call to 'xm create'.
+#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"

# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/firmware/acpi/acpi_dsdt.asl
--- a/tools/firmware/acpi/acpi_dsdt.asl Mon May 22 08:53:26 2006 -0600
+++ b/tools/firmware/acpi/acpi_dsdt.asl Mon May 22 14:13:38 2006 -0600
@@ -36,6 +36,16 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1,
Processor (CPU2, 0x02, 0x00000000, 0x00) {}
Processor (CPU3, 0x03, 0x00000000, 0x00) {}
}
+
+/* Poweroff support - ties in with qemu emulation */
+
+ Name (\_S5, Package (0x04)
+ {
+ 0x07,
+ 0x07,
+ 0x00,
+ 0x00
+ })

Scope (\_SB)
{
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/firmware/acpi/acpi_dsdt.c
--- a/tools/firmware/acpi/acpi_dsdt.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/firmware/acpi/acpi_dsdt.c Mon May 22 14:13:38 2006 -0600
@@ -1,161 +1,160 @@
/*
*
* Intel ACPI Component Architecture
- * ASL Optimizing Compiler / AML Disassembler version 20050513 [Jun 8 2005]
+ * ASL Optimizing Compiler / AML Disassembler version 20050624 [Aug 24 2005]
* Copyright (C) 2000 - 2005 Intel Corporation
* Supports ACPI Specification Revision 3.0
*
- * Compilation of "acpi_dsdt.asl" - Wed Jun 15 09:19:49 2005
+ * Compilation of "acpi_dsdt.asl" - Thu May 4 17:42:00 2006
*
* C source code output
*
*/
unsigned char AmlCode[] =
{
- 0x44,0x53,0x44,0x54,0x87,0x04,0x00,0x00, /* 00000000 "DSDT...." */
- 0x01,0x19,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x44,0x53,0x44,0x54,0x7C,0x04,0x00,0x00, /* 00000000 "DSDT|..." */
+ 0x01,0x72,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".rINTEL " */
0x58,0x45,0x4E,0x20,0x20,0x20,0x20,0x20, /* 00000010 "XEN " */
0x02,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
- 0x13,0x05,0x05,0x20,0x08,0x5C,0x50,0x4D, /* 00000020 "... .\PM" */
- 0x42,0x53,0x0B,0x00,0x0C,0x08,0x5C,0x50, /* 00000028 "BS....\P" */
- 0x4D,0x4C,0x4E,0x0A,0x08,0x08,0x5C,0x49, /* 00000030 "MLN...\I" */
- 0x4F,0x42,0x31,0x0A,0x00,0x08,0x5C,0x49, /* 00000038 "OB1...\I" */
- 0x4F,0x4C,0x31,0x0A,0x00,0x08,0x5C,0x41, /* 00000040 "OL1...\A" */
- 0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,0xFE, /* 00000048 "PCB....." */
- 0x08,0x5C,0x41,0x50,0x43,0x4C,0x0C,0x00, /* 00000050 ".\APCL.." */
- 0x00,0x01,0x00,0x08,0x5C,0x50,0x55,0x49, /* 00000058 "....\PUI" */
- 0x44,0x0A,0x00,0x10,0x3A,0x5C,0x5F,0x50, /* 00000060 "D...:\_P" */
- 0x52,0x5F,0x5B,0x83,0x0B,0x43,0x50,0x55, /* 00000068 "R_[...CPU" */
- 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x5B, /* 00000070 "0......[." */
- 0x83,0x0B,0x43,0x50,0x55,0x31,0x01,0x00, /* 00000078 "..CPU1.." */
- 0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x43, /* 00000080 "....[...C" */
- 0x50,0x55,0x32,0x02,0x00,0x00,0x00,0x00, /* 00000088 "PU2....." */
- 0x00,0x5B,0x83,0x0B,0x43,0x50,0x55,0x33, /* 00000090 ".[...CPU3" */
- 0x03,0x00,0x00,0x00,0x00,0x00,0x10,0x48, /* 00000098 ".......H" */
- 0x3E,0x5C,0x5F,0x53,0x42,0x5F,0x5B,0x82, /* 000000A0 ">\_SB_[.." */
- 0x4F,0x3D,0x50,0x43,0x49,0x30,0x08,0x5F, /* 000000A8 "O=PCI0._" */
- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03, /* 000000B0 "HID.A..." */
- 0x08,0x5F,0x55,0x49,0x44,0x0A,0x00,0x08, /* 000000B8 "._UID..." */
- 0x5F,0x41,0x44,0x52,0x0A,0x00,0x08,0x5F, /* 000000C0 "_ADR..._" */
- 0x42,0x42,0x4E,0x0A,0x00,0x14,0x4A,0x06, /* 000000C8 "BBN...J." */
- 0x5F,0x43,0x52,0x53,0x00,0x08,0x50,0x52, /* 000000D0 "_CRS..PR" */
- 0x54,0x30,0x11,0x48,0x05,0x0A,0x54,0x88, /* 000000D8 "T0.H..T." */
- 0x0D,0x00,0x02,0x0F,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
- 0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x47, /* 000000E8 ".......G" */
- 0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88, /* 000000F0 "........" */
- 0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,0x00, /* 000000F8 "........" */
- 0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x88, /* 00000100 "........" */
- 0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,0x00, /* 00000108 "........" */
- 0x0D,0xFF,0x0F,0x00,0x00,0x00,0x03,0x87, /* 00000110 "........" */
- 0x17,0x00,0x00,0x0C,0x02,0x00,0x00,0x00, /* 00000118 "........" */
- 0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0F, /* 00000120 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06, /* 00000128 "........" */
- 0x00,0x79,0x00,0xA4,0x50,0x52,0x54,0x30, /* 00000130 ".y..PRT0" */
- 0x08,0x41,0x49,0x52,0x30,0x12,0x47,0x05, /* 00000138 ".AIR0.G." */
- 0x06,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x1F, /* 00000140 "........" */
- 0x00,0x0A,0x02,0x0A,0x00,0x0A,0x17,0x12, /* 00000148 "........" */
- 0x0D,0x04,0x0C,0xFF,0xFF,0x1F,0x00,0x0A, /* 00000150 "........" */
- 0x03,0x0A,0x00,0x0A,0x13,0x12,0x0D,0x04, /* 00000158 "........" */
- 0x0C,0xFF,0xFF,0x1D,0x00,0x0A,0x01,0x0A, /* 00000160 "........" */
- 0x00,0x0A,0x13,0x12,0x0D,0x04,0x0C,0xFF, /* 00000168 "........" */
- 0xFF,0x1D,0x00,0x0A,0x00,0x0A,0x00,0x0A, /* 00000170 "........" */
- 0x10,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x1D, /* 00000178 "........" */
- 0x00,0x0A,0x02,0x0A,0x00,0x0A,0x12,0x12, /* 00000180 "........" */
- 0x0D,0x04,0x0C,0xFF,0xFF,0x1D,0x00,0x0A, /* 00000188 "........" */
- 0x03,0x0A,0x00,0x0A,0x17,0x14,0x0B,0x5F, /* 00000190 "......._" */
- 0x50,0x52,0x54,0x00,0xA4,0x41,0x49,0x52, /* 00000198 "PRT..AIR" */
- 0x30,0x5B,0x82,0x44,0x2E,0x49,0x53,0x41, /* 000001A0 "0[..D.ISA" */
- 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 000001A8 "_._ADR.." */
- 0x00,0x01,0x00,0x5B,0x82,0x47,0x0B,0x53, /* 000001B0 "...[..G.S" */
- 0x59,0x53,0x52,0x08,0x5F,0x48,0x49,0x44, /* 000001B8 "YSR._HID" */
- 0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55, /* 000001C0 ".A...._U" */
- 0x49,0x44,0x0A,0x01,0x08,0x43,0x52,0x53, /* 000001C8 "ID...CRS" */
- 0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01, /* 000001D0 "_.N...G." */
- 0x10,0x00,0x10,0x00,0x00,0x10,0x47,0x01, /* 000001D8 "......G." */
- 0x22,0x00,0x22,0x00,0x00,0x0C,0x47,0x01, /* 000001E0 ""."...G." */
- 0x30,0x00,0x30,0x00,0x00,0x10,0x47,0x01, /* 000001E8 "0.0...G." */
- 0x44,0x00,0x44,0x00,0x00,0x1C,0x47,0x01, /* 000001F0 "D.D...G." */
- 0x62,0x00,0x62,0x00,0x00,0x02,0x47,0x01, /* 000001F8 "b.b...G." */
- 0x65,0x00,0x65,0x00,0x00,0x0B,0x47,0x01, /* 00000200 "e.e...G." */
- 0x72,0x00,0x72,0x00,0x00,0x0E,0x47,0x01, /* 00000208 "r.r...G." */
- 0x80,0x00,0x80,0x00,0x00,0x01,0x47,0x01, /* 00000210 "......G." */
- 0x84,0x00,0x84,0x00,0x00,0x03,0x47,0x01, /* 00000218 "......G." */
- 0x88,0x00,0x88,0x00,0x00,0x01,0x47,0x01, /* 00000220 "......G." */
- 0x8C,0x00,0x8C,0x00,0x00,0x03,0x47,0x01, /* 00000228 "......G." */
- 0x90,0x00,0x90,0x00,0x00,0x10,0x47,0x01, /* 00000230 "......G." */
- 0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47,0x01, /* 00000238 "......G." */
- 0xE0,0x00,0xE0,0x00,0x00,0x10,0x47,0x01, /* 00000240 "......G." */
- 0xA0,0x08,0xA0,0x08,0x00,0x04,0x47,0x01, /* 00000248 "......G." */
- 0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01, /* 00000250 "......G." */
- 0xD0,0x04,0xD0,0x04,0x00,0x02,0x79,0x00, /* 00000258 "......y." */
- 0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4, /* 00000260 ".._CRS.." */
- 0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50, /* 00000268 "CRS_[..+P" */
- 0x49,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000270 "IC_._HID" */
- 0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52,0x53, /* 00000278 ".A.._CRS" */
- 0x11,0x18,0x0A,0x15,0x47,0x01,0x20,0x00, /* 00000280 "....G. ." */
- 0x20,0x00,0x01,0x02,0x47,0x01,0xA0,0x00, /* 00000288 " ...G..." */
- 0xA0,0x00,0x01,0x02,0x22,0x04,0x00,0x79, /* 00000290 "...."..y" */
- 0x00,0x5B,0x82,0x47,0x05,0x44,0x4D,0x41, /* 00000298 ".[..G.DMA" */
- 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000002A0 "0._HID.A" */
- 0xD0,0x02,0x00,0x08,0x5F,0x43,0x52,0x53, /* 000002A8 "...._CRS" */
- 0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04, /* 000002B0 ".A..=*.." */
- 0x47,0x01,0x00,0x00,0x00,0x00,0x00,0x10, /* 000002B8 "G......." */
- 0x47,0x01,0x81,0x00,0x81,0x00,0x00,0x03, /* 000002C0 "G......." */
- 0x47,0x01,0x87,0x00,0x87,0x00,0x00,0x01, /* 000002C8 "G......." */
- 0x47,0x01,0x89,0x00,0x89,0x00,0x00,0x03, /* 000002D0 "G......." */
- 0x47,0x01,0x8F,0x00,0x8F,0x00,0x00,0x01, /* 000002D8 "G......." */
- 0x47,0x01,0xC0,0x00,0xC0,0x00,0x00,0x20, /* 000002E0 "G...... " */
- 0x47,0x01,0x80,0x04,0x80,0x04,0x00,0x10, /* 000002E8 "G......." */
- 0x79,0x00,0x5B,0x82,0x25,0x54,0x4D,0x52, /* 000002F0 "y.[..%TMR" */
- 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000002F8 "_._HID.A" */
- 0xD0,0x01,0x00,0x08,0x5F,0x43,0x52,0x53, /* 00000300 "...._CRS" */
- 0x11,0x10,0x0A,0x0D,0x47,0x01,0x40,0x00, /* 00000308 "....G.@." */
- 0x40,0x00,0x00,0x04,0x22,0x01,0x00,0x79, /* 00000310 "@..."..y" */
- 0x00,0x5B,0x82,0x25,0x52,0x54,0x43,0x5F, /* 00000318 ".[..%RTC_" */
- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000320 "._HID.A." */
- 0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000328 "..._CRS." */
- 0x10,0x0A,0x0D,0x47,0x01,0x70,0x00,0x70, /* 00000330 "...G.p.p" */
- 0x00,0x00,0x02,0x22,0x00,0x01,0x79,0x00, /* 00000338 "..."..y." */
- 0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,0x08, /* 00000340 "[.."SPKR." */
- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x08, /* 00000348 "_HID.A.." */
- 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x0D, /* 00000350 ".._CRS.." */
- 0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,0x00, /* 00000358 "..G.a.a." */
- 0x00,0x01,0x79,0x00,0x5B,0x82,0x31,0x50, /* 00000360 "..y.[..1P" */
- 0x53,0x32,0x4D,0x08,0x5F,0x48,0x49,0x44, /* 00000368 "S2M._HID" */
- 0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43, /* 00000370 ".A...._C" */
- 0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14, /* 00000378 "ID.A...." */
- 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000380 "._STA..." */
- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x08, /* 00000388 ".._CRS.." */
- 0x0A,0x05,0x22,0x00,0x10,0x79,0x00,0x5B, /* 00000390 ".."..y.[." */
- 0x82,0x42,0x04,0x50,0x53,0x32,0x4B,0x08, /* 00000398 ".B.PS2K." */
- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 000003A0 "_HID.A.." */
- 0x03,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41, /* 000003A8 ".._CID.A" */
- 0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53,0x54, /* 000003B0 "....._ST" */
- 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 000003B8 "A....._C" */
- 0x52,0x53,0x11,0x18,0x0A,0x15,0x47,0x01, /* 000003C0 "RS....G." */
- 0x60,0x00,0x60,0x00,0x00,0x01,0x47,0x01, /* 000003C8 "`.`...G." */
- 0x64,0x00,0x64,0x00,0x00,0x01,0x22,0x02, /* 000003D0 "d.d..."." */
- 0x00,0x79,0x00,0x5B,0x82,0x3A,0x46,0x44, /* 000003D8 ".y.[..:FD" */
- 0x43,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000003E0 "C0._HID." */
- 0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,0x53, /* 000003E8 "A....._S" */
- 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 000003F0 "TA....._" */
- 0x43,0x52,0x53,0x11,0x1B,0x0A,0x18,0x47, /* 000003F8 "CRS....G" */
- 0x01,0xF0,0x03,0xF0,0x03,0x01,0x06,0x47, /* 00000400 ".......G" */
- 0x01,0xF7,0x03,0xF7,0x03,0x01,0x01,0x22, /* 00000408 "......."" */
- 0x40,0x00,0x2A,0x04,0x00,0x79,0x00,0x5B, /* 00000410 "@.*..y.[." */
- 0x82,0x36,0x55,0x41,0x52,0x31,0x08,0x5F, /* 00000418 ".6UAR1._" */
- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000420 "HID.A..." */
- 0x08,0x5F,0x55,0x49,0x44,0x0A,0x01,0x14, /* 00000428 "._UID..." */
- 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000430 "._STA..." */
- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000438 ".._CRS.." */
- 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000440 "..G....." */
- 0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B, /* 00000448 ".."..y.[." */
- 0x82,0x36,0x55,0x41,0x52,0x32,0x08,0x5F, /* 00000450 ".6UAR2._" */
- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000458 "HID.A..." */
- 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000460 "._UID..." */
- 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000468 "._STA..." */
- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000470 ".._CRS.." */
- 0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02, /* 00000478 "..G....." */
- 0x01,0x08,0x22,0x08,0x00,0x79,0x00,
+ 0x24,0x06,0x05,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "$.. .PMB" */
+ 0x53,0x0B,0x00,0x0C,0x08,0x50,0x4D,0x4C, /* 00000028 "S....PML" */
+ 0x4E,0x0A,0x08,0x08,0x49,0x4F,0x42,0x31, /* 00000030 "N...IOB1" */
+ 0x00,0x08,0x49,0x4F,0x4C,0x31,0x00,0x08, /* 00000038 "..IOL1.." */
+ 0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0, /* 00000040 "APCB...." */
+ 0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00, /* 00000048 "..APCL.." */
+ 0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44, /* 00000050 "....PUID" */
+ 0x00,0x10,0x39,0x5F,0x50,0x52,0x5F,0x5B, /* 00000058 "..9_PR_[." */
+ 0x83,0x0B,0x43,0x50,0x55,0x30,0x00,0x00, /* 00000060 "..CPU0.." */
+ 0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x43, /* 00000068 "....[...C" */
+ 0x50,0x55,0x31,0x01,0x00,0x00,0x00,0x00, /* 00000070 "PU1....." */
+ 0x00,0x5B,0x83,0x0B,0x43,0x50,0x55,0x32, /* 00000078 ".[...CPU2" */
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x5B,0x83, /* 00000080 "......[.." */
+ 0x0B,0x43,0x50,0x55,0x33,0x03,0x00,0x00, /* 00000088 ".CPU3..." */
+ 0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F, /* 00000090 "...._S5_" */
+ 0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00, /* 00000098 "........" */
+ 0x00,0x10,0x4A,0x3D,0x5F,0x53,0x42,0x5F, /* 000000A0 "..J=_SB_" */
+ 0x5B,0x82,0x42,0x3D,0x50,0x43,0x49,0x30, /* 000000A8 "[..B=PCI0" */
+ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000000B0 "._HID.A." */
+ 0x0A,0x03,0x08,0x5F,0x55,0x49,0x44,0x00, /* 000000B8 "..._UID." */
+ 0x08,0x5F,0x41,0x44,0x52,0x00,0x08,0x5F, /* 000000C0 "._ADR.._" */
+ 0x42,0x42,0x4E,0x00,0x14,0x4A,0x06,0x5F, /* 000000C8 "BBN..J._" */
+ 0x43,0x52,0x53,0x00,0x08,0x50,0x52,0x54, /* 000000D0 "CRS..PRT" */
+ 0x30,0x11,0x48,0x05,0x0A,0x54,0x88,0x0D, /* 000000D8 "0.H..T.." */
+ 0x00,0x02,0x0F,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
+ 0xFF,0x00,0x00,0x00,0x00,0x01,0x47,0x01, /* 000000E8 "......G." */
+ 0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D, /* 000000F0 "........" */
+ 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D, /* 00000100 "........" */
+ 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x0D, /* 00000108 "........" */
+ 0xFF,0x0F,0x00,0x00,0x00,0x03,0x87,0x17, /* 00000110 "........" */
+ 0x00,0x00,0x0C,0x02,0x00,0x00,0x00,0x00, /* 00000118 "........" */
+ 0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0F,0x00, /* 00000120 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00, /* 00000128 "........" */
+ 0x79,0x00,0xA4,0x50,0x52,0x54,0x30,0x08, /* 00000130 "y..PRT0." */
+ 0x41,0x49,0x52,0x30,0x12,0x4F,0x04,0x06, /* 00000138 "AIR0.O.." */
+ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x1F,0x00, /* 00000140 "........" */
+ 0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C,0x04, /* 00000148 "........" */
+ 0x0C,0xFF,0xFF,0x1F,0x00,0x0A,0x03,0x00, /* 00000150 "........" */
+ 0x0A,0x13,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000158 "........" */
+ 0x1D,0x00,0x01,0x00,0x0A,0x13,0x12,0x0B, /* 00000160 "........" */
+ 0x04,0x0C,0xFF,0xFF,0x1D,0x00,0x00,0x00, /* 00000168 "........" */
+ 0x0A,0x10,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000170 "........" */
+ 0x1D,0x00,0x0A,0x02,0x00,0x0A,0x12,0x12, /* 00000178 "........" */
+ 0x0C,0x04,0x0C,0xFF,0xFF,0x1D,0x00,0x0A, /* 00000180 "........" */
+ 0x03,0x00,0x0A,0x17,0x14,0x0B,0x5F,0x50, /* 00000188 "......_P" */
+ 0x52,0x54,0x00,0xA4,0x41,0x49,0x52,0x30, /* 00000190 "RT..AIR0" */
+ 0x5B,0x82,0x42,0x2E,0x49,0x53,0x41,0x5F, /* 00000198 "[..B.ISA_" */
+ 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000001A0 "._ADR..." */
+ 0x01,0x00,0x5B,0x82,0x46,0x0B,0x53,0x59, /* 000001A8 "..[..F.SY" */
+ 0x53,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000001B0 "SR._HID." */
+ 0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49, /* 000001B8 "A...._UI" */
+ 0x44,0x01,0x08,0x43,0x52,0x53,0x5F,0x11, /* 000001C0 "D..CRS_." */
+ 0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10,0x00, /* 000001C8 "N...G..." */
+ 0x10,0x00,0x00,0x10,0x47,0x01,0x22,0x00, /* 000001D0 "....G."." */
+ 0x22,0x00,0x00,0x0C,0x47,0x01,0x30,0x00, /* 000001D8 ""...G.0." */
+ 0x30,0x00,0x00,0x10,0x47,0x01,0x44,0x00, /* 000001E0 "0...G.D." */
+ 0x44,0x00,0x00,0x1C,0x47,0x01,0x62,0x00, /* 000001E8 "D...G.b." */
+ 0x62,0x00,0x00,0x02,0x47,0x01,0x65,0x00, /* 000001F0 "b...G.e." */
+ 0x65,0x00,0x00,0x0B,0x47,0x01,0x72,0x00, /* 000001F8 "e...G.r." */
+ 0x72,0x00,0x00,0x0E,0x47,0x01,0x80,0x00, /* 00000200 "r...G..." */
+ 0x80,0x00,0x00,0x01,0x47,0x01,0x84,0x00, /* 00000208 "....G..." */
+ 0x84,0x00,0x00,0x03,0x47,0x01,0x88,0x00, /* 00000210 "....G..." */
+ 0x88,0x00,0x00,0x01,0x47,0x01,0x8C,0x00, /* 00000218 "....G..." */
+ 0x8C,0x00,0x00,0x03,0x47,0x01,0x90,0x00, /* 00000220 "....G..." */
+ 0x90,0x00,0x00,0x10,0x47,0x01,0xA2,0x00, /* 00000228 "....G..." */
+ 0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0,0x00, /* 00000230 "....G..." */
+ 0xE0,0x00,0x00,0x10,0x47,0x01,0xA0,0x08, /* 00000238 "....G..." */
+ 0xA0,0x08,0x00,0x04,0x47,0x01,0xC0,0x0C, /* 00000240 "....G..." */
+ 0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0,0x04, /* 00000248 "....G..." */
+ 0xD0,0x04,0x00,0x02,0x79,0x00,0x14,0x0B, /* 00000250 "....y..." */
+ 0x5F,0x43,0x52,0x53,0x00,0xA4,0x43,0x52, /* 00000258 "_CRS..CR" */
+ 0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43, /* 00000260 "S_[..+PIC" */
+ 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41, /* 00000268 "_._HID.A" */
+ 0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 00000270 ".._CRS.." */
+ 0x0A,0x15,0x47,0x01,0x20,0x00,0x20,0x00, /* 00000278 "..G. . ." */
+ 0x01,0x02,0x47,0x01,0xA0,0x00,0xA0,0x00, /* 00000280 "..G....." */
+ 0x01,0x02,0x22,0x04,0x00,0x79,0x00,0x5B, /* 00000288 ".."..y.[." */
+ 0x82,0x47,0x05,0x44,0x4D,0x41,0x30,0x08, /* 00000290 ".G.DMA0." */
+ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x02, /* 00000298 "_HID.A.." */
+ 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x41, /* 000002A0 ".._CRS.A" */
+ 0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01, /* 000002A8 "..=*..G." */
+ 0x00,0x00,0x00,0x00,0x00,0x10,0x47,0x01, /* 000002B0 "......G." */
+ 0x81,0x00,0x81,0x00,0x00,0x03,0x47,0x01, /* 000002B8 "......G." */
+ 0x87,0x00,0x87,0x00,0x00,0x01,0x47,0x01, /* 000002C0 "......G." */
+ 0x89,0x00,0x89,0x00,0x00,0x03,0x47,0x01, /* 000002C8 "......G." */
+ 0x8F,0x00,0x8F,0x00,0x00,0x01,0x47,0x01, /* 000002D0 "......G." */
+ 0xC0,0x00,0xC0,0x00,0x00,0x20,0x47,0x01, /* 000002D8 "..... G." */
+ 0x80,0x04,0x80,0x04,0x00,0x10,0x79,0x00, /* 000002E0 "......y." */
+ 0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F,0x08, /* 000002E8 "[..%TMR_." */
+ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 000002F0 "_HID.A.." */
+ 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 000002F8 ".._CRS.." */
+ 0x0A,0x0D,0x47,0x01,0x40,0x00,0x40,0x00, /* 00000300 "..G.@.@." */
+ 0x00,0x04,0x22,0x01,0x00,0x79,0x00,0x5B, /* 00000308 ".."..y.[." */
+ 0x82,0x25,0x52,0x54,0x43,0x5F,0x08,0x5F, /* 00000310 ".%RTC_._" */
+ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00, /* 00000318 "HID.A..." */
+ 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000320 "._CRS..." */
+ 0x0D,0x47,0x01,0x70,0x00,0x70,0x00,0x00, /* 00000328 ".G.p.p.." */
+ 0x02,0x22,0x00,0x01,0x79,0x00,0x5B,0x82, /* 00000330 "."..y.[.." */
+ 0x22,0x53,0x50,0x4B,0x52,0x08,0x5F,0x48, /* 00000338 ""SPKR._H" */
+ 0x49,0x44,0x0C,0x41,0xD0,0x08,0x00,0x08, /* 00000340 "ID.A...." */
+ 0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A, /* 00000348 "_CRS...." */
+ 0x47,0x01,0x61,0x00,0x61,0x00,0x00,0x01, /* 00000350 "G.a.a..." */
+ 0x79,0x00,0x5B,0x82,0x31,0x50,0x53,0x32, /* 00000358 "y.[..1PS2" */
+ 0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000360 "M._HID.A" */
+ 0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49,0x44, /* 00000368 "...._CID" */
+ 0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F, /* 00000370 ".A....._" */
+ 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000378 "STA....." */
+ 0x5F,0x43,0x52,0x53,0x11,0x08,0x0A,0x05, /* 00000380 "_CRS...." */
+ 0x22,0x00,0x10,0x79,0x00,0x5B,0x82,0x42, /* 00000388 ""..y.[..B" */
+ 0x04,0x50,0x53,0x32,0x4B,0x08,0x5F,0x48, /* 00000390 ".PS2K._H" */
+ 0x49,0x44,0x0C,0x41,0xD0,0x03,0x03,0x08, /* 00000398 "ID.A...." */
+ 0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 000003A0 "_CID.A.." */
+ 0x0B,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 000003A8 "..._STA." */
+ 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 000003B0 "...._CRS" */
+ 0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00, /* 000003B8 "....G.`." */
+ 0x60,0x00,0x00,0x01,0x47,0x01,0x64,0x00, /* 000003C0 "`...G.d." */
+ 0x64,0x00,0x00,0x01,0x22,0x02,0x00,0x79, /* 000003C8 "d..."..y" */
+ 0x00,0x5B,0x82,0x3A,0x46,0x44,0x43,0x30, /* 000003D0 ".[..:FDC0" */
+ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000003D8 "._HID.A." */
+ 0x07,0x00,0x14,0x09,0x5F,0x53,0x54,0x41, /* 000003E0 "...._STA" */
+ 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 000003E8 "....._CR" */
+ 0x53,0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0, /* 000003F0 "S....G.." */
+ 0x03,0xF0,0x03,0x01,0x06,0x47,0x01,0xF7, /* 000003F8 ".....G.." */
+ 0x03,0xF7,0x03,0x01,0x01,0x22,0x40,0x00, /* 00000400 "....."@." */
+ 0x2A,0x04,0x00,0x79,0x00,0x5B,0x82,0x35, /* 00000408 "*..y.[..5" */
+ 0x55,0x41,0x52,0x31,0x08,0x5F,0x48,0x49, /* 00000410 "UAR1._HI" */
+ 0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F, /* 00000418 "D.A...._" */
+ 0x55,0x49,0x44,0x01,0x14,0x09,0x5F,0x53, /* 00000420 "UID..._S" */
+ 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000428 "TA....._" */
+ 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000430 "CRS....G" */
+ 0x01,0xF8,0x03,0xF8,0x03,0x01,0x08,0x22, /* 00000438 "......."" */
+ 0x10,0x00,0x79,0x00,0x5B,0x82,0x36,0x55, /* 00000440 "..y.[..6U" */
+ 0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44, /* 00000448 "AR2._HID" */
+ 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000450 ".A...._U" */
+ 0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53, /* 00000458 "ID...._S" */
+ 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000460 "TA....._" */
+ 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000468 "CRS....G" */
+ 0x01,0xF8,0x02,0xF8,0x02,0x01,0x08,0x22, /* 00000470 "......."" */
+ 0x08,0x00,0x79,0x00,
};
int DsdtLen=sizeof(AmlCode);
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/firmware/acpi/acpi_fadt.h
--- a/tools/firmware/acpi/acpi_fadt.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/firmware/acpi/acpi_fadt.h Mon May 22 14:13:38 2006 -0600
@@ -59,7 +59,7 @@
#define ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID ACPI_SYSTEM_IO
#define ACPI_PM1A_EVT_BLK_BIT_WIDTH 0x00
#define ACPI_PM1A_EVT_BLK_BIT_OFFSET 0x00
-#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000000000
+#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000008000

//
// PM1B Event Register Block Generic Address Information
@@ -73,7 +73,7 @@
// PM1A Control Register Block Generic Address Information
//
#define ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID ACPI_SYSTEM_IO
-#define ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x10
+#define ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x08
#define ACPI_PM1A_CNT_BLK_BIT_OFFSET 0x00
#define ACPI_PM1A_CNT_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/cirrus_vga.c Mon May 22 14:13:38 2006 -0600
@@ -28,6 +28,9 @@
*/
#include "vl.h"
#include "vga_int.h"
+#ifndef _WIN32
+#include <sys/mman.h>
+#endif

/*
* TODO:
@@ -269,7 +272,8 @@ typedef struct CirrusVGAState {
int last_hw_cursor_y_end;
int real_vram_size; /* XXX: suppress that */
CPUWriteMemoryFunc **cirrus_linear_write;
- int set_mapping;
+ unsigned long map_addr;
+ unsigned long map_end;
} CirrusVGAState;

typedef struct PCICirrusVGAState {
@@ -1187,6 +1191,17 @@ cirrus_hook_write_sr(CirrusVGAState * s,
s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
break;
case 0x07: // Extended Sequencer Mode
+ /* Win2K seems to assume that the VRAM is set to 0xff
+ * whenever VGA/SVGA mode changes
+ */
+ if ((s->sr[0x07] ^ reg_value) & CIRRUS_SR7_BPP_SVGA)
+ memset(s->vram_ptr, 0xff, s->real_vram_size);
+ s->sr[0x07] = reg_value;
+#ifdef DEBUG_CIRRUS
+ printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
+ reg_index, reg_value);
+#endif
+ break;
case 0x08: // EEPROM Control
case 0x09: // Scratch Register 0
case 0x0a: // Scratch Register 1
@@ -2444,14 +2459,97 @@ static CPUWriteMemoryFunc *cirrus_linear
cirrus_linear_bitblt_writel,
};

+extern FILE *logfile;
+#if defined(__i386__) || defined (__x86_64__)
+static void * set_vram_mapping(unsigned long begin, unsigned long end)
+{
+ unsigned long * extent_start = NULL;
+ unsigned long nr_extents;
+ void *vram_pointer = NULL;
+ int i;
+
+ /* align begin and end address */
+ begin = begin & TARGET_PAGE_MASK;
+ end = begin + VGA_RAM_SIZE;
+ end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
+ nr_extents = (end - begin) >> TARGET_PAGE_BITS;
+
+ extent_start = malloc(sizeof(unsigned long) * nr_extents );
+ if (extent_start == NULL)
+ {
+ fprintf(stderr, "Failed malloc on set_vram_mapping\n");
+ return NULL;
+ }
+
+ memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
+
+ for (i = 0; i < nr_extents; i++)
+ {
+ extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
+ }
+
+ set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
+
+ if ( (vram_pointer = xc_map_foreign_batch(xc_handle, domid,
+ PROT_READ|PROT_WRITE,
+ extent_start,
+ nr_extents)) == NULL)
+ {
+ fprintf(logfile,
+ "xc_map_foreign_batch vgaram returned error %d\n", errno);
+ return NULL;
+ }
+
+ memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
+
+ free(extent_start);
+
+ return vram_pointer;
+}
+
+static int unset_vram_mapping(unsigned long begin, unsigned long end)
+{
+ unsigned long * extent_start = NULL;
+ unsigned long nr_extents;
+ int i;
+
+ /* align begin and end address */
+
+ end = begin + VGA_RAM_SIZE;
+ begin = begin & TARGET_PAGE_MASK;
+ end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
+ nr_extents = (end - begin) >> TARGET_PAGE_BITS;
+
+ extent_start = malloc(sizeof(unsigned long) * nr_extents );
+
+ if (extent_start == NULL)
+ {
+ fprintf(stderr, "Failed malloc on set_mm_mapping\n");
+ return -1;
+ }
+
+ memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
+
+ for (i = 0; i < nr_extents; i++)
+ extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
+
+ unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
+
+ free(extent_start);
+
+ return 0;
+}
+
+#elif defined(__ia64__)
+static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
+static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
+#endif
+extern int vga_accelerate;
+
/* Compute the memory access functions */
static void cirrus_update_memory_access(CirrusVGAState *s)
{
unsigned mode;
- extern void * set_vram_mapping(unsigned long addr, unsigned long end);
-
- extern int unset_vram_mapping(unsigned long addr, unsigned long end);
- extern int vga_accelerate;

if ((s->sr[0x17] & 0x44) == 0x44) {
goto generic_io;
@@ -2466,18 +2564,21 @@ static void cirrus_update_memory_access(

mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
- if (!s->set_mapping) {
- void * vram_pointer;
- s->set_mapping = 1;
- vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
- if (!vram_pointer){
+ if ( vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end ) {
+ if (!s->map_addr) {
+ void *vram_pointer, *old_vram;
+
+ vram_pointer =
+ set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
+ if (!vram_pointer) {
fprintf(stderr, "NULL vram_pointer\n");
- } else
- {
- vga_update_vram((VGAState *)s, vram_pointer,
+ } else {
+ old_vram = vga_update_vram((VGAState *)s, vram_pointer,
VGA_RAM_SIZE);
+ qemu_free(old_vram);
}
+ s->map_addr = s->cirrus_lfb_addr;
+ s->map_end = s->cirrus_lfb_end;
}
}
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
@@ -2486,13 +2587,19 @@ static void cirrus_update_memory_access(
} else {
generic_io:
if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
- if(s->set_mapping) {
+ if(s->map_addr) {
int error;
- s->set_mapping = 0;
+ void *old_vram = NULL;
+
error = unset_vram_mapping(s->cirrus_lfb_addr,
s->cirrus_lfb_end);
if (!error)
- vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
+ old_vram =
+ vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
+
+ if (old_vram)
+ munmap(old_vram, s->map_addr - s->map_end);
+ s->map_addr = s->map_end = 0;
}
}

@@ -3021,10 +3128,6 @@ static void cirrus_init_common(CirrusVGA
}
s->cr[0x27] = device_id;

- /* Win2K seems to assume that the pattern buffer is at 0xff
- initially ! */
- memset(s->vram_ptr, 0xff, s->real_vram_size);
-
s->cirrus_hidden_dac_lockindex = 5;
s->cirrus_hidden_dac_data = 0;

@@ -3091,6 +3194,12 @@ static void cirrus_pci_lfb_map(PCIDevice
s->cirrus_linear_io_addr);
s->cirrus_lfb_addr = addr;
s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
+
+ if ( vga_accelerate && s->map_addr &&
+ (s->cirrus_lfb_addr != s->map_addr) &&
+ (s->cirrus_lfb_end != s->map_end))
+ fprintf(logfile, "cirrus vga map change while on lfb mode\n");
+
cpu_register_physical_memory(addr + 0x1000000, 0x400000,
s->cirrus_linear_bitblt_io_addr);
}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/mc146818rtc.c
--- a/tools/ioemu/hw/mc146818rtc.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/mc146818rtc.c Mon May 22 14:13:38 2006 -0600
@@ -178,10 +178,27 @@ static inline int from_bcd(RTCState *s,
}
}

+static void send_timeoffset_msg(time_t delta)
+{
+
+/* This routine is used to inform another entity that the
+ base time offset has changed. For instance, if you
+ were using xenstore, you might want to write to the store
+ at this point. Or, you might use some other method.
+ Whatever you might choose, here's a hook point to implement it.
+
+ One item of note is that this delta is in addition to
+ any existing offset you might be already using. */
+
+ return;
+}
+
static void rtc_set_time(RTCState *s)
{
struct tm *tm = &s->current_tm;
-
+ time_t before, after;
+
+ before = mktime(tm);
tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
@@ -193,6 +210,12 @@ static void rtc_set_time(RTCState *s)
tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
+
+ /* Compute, and send, the additional time delta
+ We could compute the total time delta, but this is
+ sufficient, and simple. */
+ after = mktime(tm);
+ send_timeoffset_msg(after-before);
}

static void rtc_copy_date(RTCState *s)
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/pc.c Mon May 22 14:13:38 2006 -0600
@@ -118,7 +118,7 @@ static void cmos_init_hd(int type_ofs, i
}

/* hd_table must contain 4 block drivers */
-static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table)
+static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table, time_t timeoffset)
{
RTCState *s = rtc_state;
int val;
@@ -129,6 +129,7 @@ static void cmos_init(uint64_t ram_size,

/* set the CMOS date */
time(&ti);
+ ti += timeoffset;
if (rtc_utc)
tm = gmtime(&ti);
else
@@ -373,18 +374,20 @@ static int serial_io[MAX_SERIAL_PORTS] =
static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };

+extern int acpi_init(unsigned int base);
+
#define NOBIOS 1

/* PC hardware initialisation */
void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
+ const char *initrd_filename, time_t timeoffset)
+{
+ SerialState *sp;
char buf[1024];
int ret, linux_boot, initrd_size, i, nb_nics1;
PCIBus *pci_bus;
- extern void * shared_vram;

linux_boot = (kernel_filename != NULL);

@@ -511,14 +514,14 @@ void pc_init(uint64_t ram_size, int vga_
if (cirrus_vga_enabled) {
if (pci_enabled) {
pci_cirrus_vga_init(pci_bus,
- ds, shared_vram, ram_size,
+ ds, NULL, ram_size,
vga_ram_size);
} else {
- isa_cirrus_vga_init(ds, shared_vram, ram_size,
+ isa_cirrus_vga_init(ds, NULL, ram_size,
vga_ram_size);
}
} else {
- vga_initialize(pci_bus, ds, shared_vram, ram_size,
+ vga_initialize(pci_bus, ds, NULL, ram_size,
vga_ram_size);
}

@@ -533,7 +536,9 @@ void pc_init(uint64_t ram_size, int vga_

for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+ sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+ if (i == SUMMA_PORT)
+ summa_init(sp, serial_hds[i]);
}
}

@@ -573,7 +578,8 @@ void pc_init(uint64_t ram_size, int vga_

floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);

- cmos_init(ram_size, boot_device, bs_table);
+ cmos_init(ram_size, boot_device, bs_table, timeoffset);
+ acpi_init(0x8000);

/* must be done after all PCI devices are instanciated */
/* XXX: should be done in the Bochs BIOS */
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/pckbd.c
--- a/tools/ioemu/hw/pckbd.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/pckbd.c Mon May 22 14:13:38 2006 -0600
@@ -156,10 +156,23 @@ typedef struct KBDState {
int mouse_dz;
uint8_t mouse_buttons;
CharDriverState *chr;
- void *cookie;
+ SerialState *serial;
} KBDState;

KBDState kbd_state;
+
+#define MODE_STREAM_SWITCH 0
+#define MODE_STREAM 1
+#define MODE_REMOTE 2
+#define MODE_POINT 3
+
+#define ORIGIN_LOWER_LEFT 0
+#define ORIGIN_UPPER_LEFT 1
+
+struct SummaState {
+ int report_mode;
+ int origin;
+} SummaState;

int summa_ok; /* Allow Summagraphics emulation if true */

@@ -420,15 +433,19 @@ static int kbd_mouse_send_packet(KBDStat
switch(s->mouse_type) {

case TABLET: /* Summagraphics pen tablet */
- dx1 = s->mouse_x;
- dy1 = s->mouse_y;
- dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
- dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
- ser_queue(s->cookie, 0x80 | (s->mouse_buttons & 7));
- ser_queue(s->cookie, dx1 & 0x7f);
- ser_queue(s->cookie, dx1 >> 7);
- ser_queue(s->cookie, dy1 & 0x7f);
- ser_queue(s->cookie, dy1 >> 7);
+ if (SummaState.report_mode == MODE_STREAM) {
+ dx1 = s->mouse_x;
+ dy1 = s->mouse_y;
+ if (SummaState.origin == ORIGIN_LOWER_LEFT)
+ dy1 = mouse_maxy - dy1;
+ dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
+ dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
+ ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7));
+ ser_queue(s->serial, dx1 & 0x7f);
+ ser_queue(s->serial, dx1 >> 7);
+ ser_queue(s->serial, dy1 & 0x7f);
+ ser_queue(s->serial, dy1 >> 7);
+ }
s->mouse_dx = 0;
s->mouse_dy = 0;
s->mouse_dz = 0;
@@ -509,43 +526,101 @@ static void pc_kbd_mouse_event(void *opa
}
}

-static void summa(KBDState *s, int val)
-{
- static int summa = 0;
-
- if (s->mouse_type == TABLET) {
+static void summa(KBDState *s, uint8_t val)
+{
+ static int zflg = 0;
+
+ if (zflg) {
+ zflg = 0;
switch (val) {

- case '?': /* read firmware ID */
- ser_queue(s->cookie, '0');
+ case 'b': /* binary report mode */
break;

- case 'a': /* read config */
- /*
- * Config looks like a movement packet but, because of scaling
- * issues we can't use `kbd_send_packet' to do this.
- */
- ser_queue(s->cookie, 0);
- ser_queue(s->cookie, (SUMMA_MAXX & 0x7f));
- ser_queue(s->cookie, (SUMMA_MAXX >> 7));
- ser_queue(s->cookie, (SUMMA_MAXY & 0x7f));
- ser_queue(s->cookie, (SUMMA_MAXY >> 7));
- break;
-
- default: /* ignore all others */
+ case 't': /* stylus type - we do 4 button cursor */
+ ser_queue(s->serial, 'C');
+ ser_queue(s->serial, 'S');
+ ser_queue(s->serial, 'R');
+ ser_queue(s->serial, '4');
+ ser_queue(s->serial, '\r');
break;

}
return;
}
- if (val == 'B') {
- summa++;
- return;
- } else if (summa && val == 'z') {
+ zflg = 0;
+
+ switch (val) {
+
+ case 'B': /* point mode */
+ /* This is supposed to be `set to point mode' but the Linux driver
+ * is broken and incorrectly sends a reset command (somebody
+ * needs to learn that the address 0 does not necessarily contain
+ * a zero). This is the first valid command that Linux sends
+ * out so we'll treat it as a reset
+ */
+ case '\0': /* reset */
s->mouse_type = TABLET;
- return;
- }
- summa = 0;
+ s->mouse_status |= MOUSE_STATUS_ENABLED;
+ SummaState.origin = ORIGIN_LOWER_LEFT;
+ SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
+ break;
+
+ case 'z': /* start of 2 byte command */
+ zflg++;
+ break;
+
+ case 'x': /* code check */
+ /*
+ * Return checksum
+ */
+ ser_queue(s->serial, '.');
+ ser_queue(s->serial, '#');
+ ser_queue(s->serial, '1');
+ ser_queue(s->serial, '2');
+ ser_queue(s->serial, '3');
+ ser_queue(s->serial, '4');
+ break;
+
+ case '?': /* read firmware ID */
+ ser_queue(s->serial, '0');
+ break;
+
+ case 'a': /* read config */
+ /*
+ * Config looks like a movement packet but, because of scaling
+ * issues we can't use `kbd_send_packet' to do this.
+ */
+ ser_queue(s->serial, 0x94);
+ ser_queue(s->serial, (SUMMA_MAXX & 0x7f));
+ ser_queue(s->serial, (SUMMA_MAXX >> 7));
+ ser_queue(s->serial, (SUMMA_MAXY & 0x7f));
+ ser_queue(s->serial, (SUMMA_MAXY >> 7));
+ break;
+
+ case 'b': /* origin at upper left */
+ SummaState.origin = ORIGIN_UPPER_LEFT;
+ break;
+
+ case 'c': /* origin at lower left */
+ SummaState.origin = ORIGIN_LOWER_LEFT;
+ break;
+
+ case '@': /* stream mode */
+ SummaState.report_mode = MODE_STREAM;
+ break;
+
+ case 'D': /* remote request mode */
+ SummaState.report_mode = MODE_REMOTE;
+ break;
+
+ case 'P': /* trigger, e.g. send report now */
+ case 'R': /* report rate = max/2 */
+ default: /* ignore all others */
+ break;
+
+ }
+
return;
}

@@ -560,13 +635,13 @@ int summa_write(CharDriverState *chr, co
return len;
}

-void summa_init(void *cookie, CharDriverState *chr)
+void summa_init(SerialState *serial, CharDriverState *chr)
{

if (summa_ok == 0)
return;
kbd_state.chr = chr;
- kbd_state.cookie = (void *)cookie;
+ kbd_state.serial = serial;
chr->chr_write = summa_write;
chr->opaque = (void *)&kbd_state;
return;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/serial.c Mon May 22 14:13:38 2006 -0600
@@ -310,7 +310,6 @@ SerialState *serial_init(int base, int i
register_ioport_write(base, 8, 1, serial_ioport_write, s);
register_ioport_read(base, 8, 1, serial_ioport_read, s);
s->chr = chr;
- summa_init(s, chr);
qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
qemu_chr_add_event_handler(chr, serial_event);
return s;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/vga.c Mon May 22 14:13:38 2006 -0600
@@ -1946,11 +1946,11 @@ void vga_bios_init(VGAState *s)

}

+/* when used on xen environment, the vga_ram_base is not used */
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
int i, j, v, b;
- extern void* shared_vram;

for(i = 0;i < 256; i++) {
v = 0;
@@ -1979,11 +1979,7 @@ void vga_common_init(VGAState *s, Displa

/* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
* when guest write vga mem, so allocate a new one */
-#if defined(__i386__) || defined(__x86_64__)
- s->vram_ptr = shared_vram;
-#else
s->vram_ptr = qemu_malloc(vga_ram_size);
-#endif
check_sse2();
s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
if (s->vram_shadow == NULL)
@@ -2090,12 +2086,14 @@ int vga_initialize(PCIBus *bus, DisplayS
return 0;
}

-int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
-{
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
+{
+ uint8_t *old_pointer;
+
if (s->vram_size != vga_ram_size)
{
fprintf(stderr, "No support to change vga_ram_size\n");
- return -1;
+ return NULL;
}

if ( !vga_ram_base )
@@ -2104,15 +2102,16 @@ int vga_update_vram(VGAState *s, void *v
if (!vga_ram_base)
{
fprintf(stderr, "reallocate error\n");
- return -1;
+ return NULL;
}
}

/* XXX lock needed? */
memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
+ old_pointer = s->vram_ptr;
s->vram_ptr = vga_ram_base;

- return 0;
+ return old_pointer;
}

/********************************************************/
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/vga_int.h
--- a/tools/ioemu/hw/vga_int.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/hw/vga_int.h Mon May 22 14:13:38 2006 -0600
@@ -165,6 +165,6 @@ void vga_draw_cursor_line_32(uint8_t *d1
unsigned int color0, unsigned int color1,
unsigned int color_xor);

-int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/target-i386-dm/Makefile Mon May 22 14:13:38 2006 -0600
@@ -278,7 +278,7 @@ endif
# Hardware support
VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o pc.o port-e9.o
-VL_OBJS+= cirrus_vga.o pcnet.o
+VL_OBJS+= cirrus_vga.o pcnet.o acpi.o
VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o

ifeq ($(TARGET_ARCH), ppc)
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/vl.c Mon May 22 14:13:38 2006 -0600
@@ -75,8 +75,6 @@
#endif
#endif /* CONFIG_SDL */

-#include "xenctrl.h"
-#include "xs.h"
#include "exec-all.h"

//#define DO_TB_FLUSH
@@ -149,12 +147,7 @@ TextConsole *vga_console;
TextConsole *vga_console;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
int xc_handle;
-unsigned long *vgapage_array;
-unsigned long *freepage_array;
-unsigned long free_pages;
-void *vtop_table;
-unsigned long toptab;
-unsigned long vgaram_pages;
+time_t timeoffset = 0;

/***********************************************************/
/* x86 ISA bus support */
@@ -2255,9 +2248,10 @@ void help(void)
"-s wait gdb connection to port %d\n"
"-p port ioreq port for xen\n"
"-d domain domain that we're serving\n"
- "-domain-namn domain name that we're serving\n"
+ "-domain-name domain name that we're serving\n"
"-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
"-L path set the directory for the BIOS and VGA BIOS\n"
+ "-timeoffset time offset (in seconds) from local time (Xen)\n"
#ifdef USE_CODE_COPY
"-no-code-copy disable code copy acceleration\n"
#endif
@@ -2355,6 +2349,7 @@ enum {
QEMU_OPTION_monitor,
QEMU_OPTION_domainname,
QEMU_OPTION_serial,
+ QEMU_OPTION_timeoffset,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
QEMU_OPTION_vgaacc,
@@ -2428,6 +2423,7 @@ const QEMUOption qemu_options[] = {
{ "std-vga", 0, QEMU_OPTION_std_vga },
{ "monitor", 1, QEMU_OPTION_monitor },
{ "domain-name", 1, QEMU_OPTION_domainname },
+ { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset },
{ "serial", 1, QEMU_OPTION_serial },
{ "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
{ "full-screen", 0, QEMU_OPTION_full_screen },
@@ -2456,35 +2452,8 @@ static uint8_t *signal_stack;

#include <xg_private.h>

-#if defined(__i386__) || defined (__x86_64__)
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-
-#ifdef __i386__
-#define _LEVEL_3_ 0
-#else
-#define _LEVEL_3_ 1
-#endif
-
-#if _LEVEL_3_
-#define L3_PROT (_PAGE_PRESENT)
-#define L1_PAGETABLE_ENTRIES 512
-#else
-#define L1_PAGETABLE_ENTRIES 1024
-#endif
-
-inline int
-get_vl2_table(unsigned long count, unsigned long start)
-{
-#if _LEVEL_3_
- return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
-#else
- return 0;
-#endif
-}
-
/* FIXME Flush the shadow page */
-static int unset_mm_mapping(int xc_handle,
+int unset_mm_mapping(int xc_handle,
uint32_t domid,
unsigned long nr_pages,
unsigned int address_bits,
@@ -2517,13 +2486,12 @@ static int unset_mm_mapping(int xc_handl
return err;
}

-static int set_mm_mapping(int xc_handle,
+int set_mm_mapping(int xc_handle,
uint32_t domid,
unsigned long nr_pages,
unsigned int address_bits,
unsigned long *extent_start)
{
- int i;
xc_dominfo_t info;
int err = 0;

@@ -2563,91 +2531,6 @@ static int set_mm_mapping(int xc_handle,

return 0;
}
-
-
-void * set_vram_mapping(unsigned long begin, unsigned long end)
-{
- unsigned long * extent_start = NULL;
- unsigned long nr_extents;
- void *vram_pointer = NULL;
- int i;
-
- /* align begin and end address */
- begin = begin & PAGE_MASK;
- end = begin + VGA_RAM_SIZE;
- end = (end + PAGE_SIZE -1 )& PAGE_MASK;
- nr_extents = (end - begin) >> PAGE_SHIFT;
-
- extent_start = malloc(sizeof(unsigned long) * nr_extents );
- if (extent_start == NULL)
- {
- fprintf(stderr, "Failed malloc on set_vram_mapping\n");
- return NULL;
- }
-
- memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
-
- for (i = 0; i < nr_extents; i++)
- {
- extent_start[i] = (begin + i * PAGE_SIZE) >> PAGE_SHIFT;
- }
-
- set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-
- if ( (vram_pointer = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- extent_start,
- nr_extents)) == NULL)
- {
- fprintf(logfile,
- "xc_map_foreign_batch vgaram returned error %d\n", errno);
- return NULL;
- }
-
- memset(vram_pointer, 0, nr_extents * PAGE_SIZE);
-
- free(extent_start);
-
- return vram_pointer;
-}
-
-int unset_vram_mapping(unsigned long begin, unsigned long end)
-{
- unsigned long * extent_start = NULL;
- unsigned long nr_extents;
- int i;
-
- /* align begin and end address */
-
- end = begin + VGA_RAM_SIZE;
- begin = begin & PAGE_MASK;
- end = (end + PAGE_SIZE -1 ) & PAGE_MASK;
- nr_extents = (end - begin) >> PAGE_SHIFT;
-
- extent_start = malloc(sizeof(unsigned long) * nr_extents );
-
- if (extent_start == NULL)
- {
- fprintf(stderr, "Failed malloc on set_mm_mapping\n");
- return -1;
- }
-
- memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
-
- for (i = 0; i < nr_extents; i++)
- extent_start[i] = (begin + (i * PAGE_SIZE)) >> PAGE_SHIFT;
-
- unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-
- free(extent_start);
-
- return 0;
-}
-
-#elif defined(__ia64__)
-void set_vram_mapping(unsigned long addr, unsigned long end) {}
-void unset_vram_mapping(unsigned long addr, unsigned long end) {}
-#endif

int main(int argc, char **argv)
{
@@ -2673,10 +2556,8 @@ int main(int argc, char **argv)
int serial_device_index;
char qemu_dm_logfilename[64];
const char *loadvm = NULL;
- unsigned long nr_pages, extra_pages, ram_pages, *page_array;
- xc_dominfo_t info;
+ unsigned long nr_pages, *page_array;
extern void *shared_page;
- extern void *shared_vram;

#if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */
@@ -2707,7 +2588,8 @@ int main(int argc, char **argv)
pstrcpy(monitor_device, sizeof(monitor_device), "vc");

pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
- for(i = 1; i < MAX_SERIAL_PORTS; i++)
+ pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
+ for(i = 2; i < MAX_SERIAL_PORTS; i++)
serial_devices[i][0] = '\0';
serial_device_index = 0;

@@ -3058,7 +2940,10 @@ int main(int argc, char **argv)
case QEMU_OPTION_domainname:
strncat(domain_name, optarg, sizeof(domain_name) - 20);
break;
-
+ case QEMU_OPTION_timeoffset:
+ timeoffset = strtol(optarg, NULL, 0);
+ break;
+
}
}
}
@@ -3133,28 +3018,9 @@ int main(int argc, char **argv)
/* init the memory */
phys_ram_size = ram_size + vga_ram_size + bios_size;

- ram_pages = ram_size/PAGE_SIZE;
-#if defined(__i386__) || defined(__x86_64__)
- vgaram_pages = (vga_ram_size -1) / PAGE_SIZE + 1;
- free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
- extra_pages = vgaram_pages + free_pages;
-#else
- /* Test vga acceleration later */
- extra_pages = 0;
-#endif
+ nr_pages = ram_size/PAGE_SIZE;

xc_handle = xc_interface_open();
-
- xc_domain_getinfo(xc_handle, domid, 1, &info);
-
- nr_pages = info.nr_pages + extra_pages;
-
- if ( xc_domain_setmaxmem(xc_handle, domid,
- (nr_pages) * PAGE_SIZE/1024 ) != 0)
- {
- fprintf(logfile, "set maxmem returned error %d\n", errno);
- exit(-1);
- }

if ( (page_array = (unsigned long *)
malloc(nr_pages * sizeof(unsigned long))) == NULL)
@@ -3163,24 +3029,16 @@ int main(int argc, char **argv)
exit(-1);
}

- if (xc_domain_memory_increase_reservation(xc_handle, domid,
- extra_pages , 0, 0, NULL) != 0)
- {
- fprintf(logfile, "increase reservation returned error %d\n", errno);
- exit(-1);
- }
-
#if defined(__i386__) || defined(__x86_64__)
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
{
fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
exit(-1);
}
-
if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- ram_pages - 1)) == 0 )
+ nr_pages - 1)) == 0 )
{
fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
exit(-1);
@@ -3188,31 +3046,11 @@ int main(int argc, char **argv)

shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ|PROT_WRITE,
- page_array[ram_pages - 1]);
-
- vgapage_array = &page_array[nr_pages - vgaram_pages];
-
- if ( (shared_vram = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- vgapage_array,
- vgaram_pages)) == 0)
- {
- fprintf(logfile,
- "xc_map_foreign_batch vgaram returned error %d\n", errno);
- exit(-1);
- }
-
- memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
- toptab = page_array[ram_pages] << PAGE_SHIFT;
-
- vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[ram_pages]);
-
- freepage_array = &page_array[nr_pages - extra_pages];
+ page_array[nr_pages - 1]);
+
#elif defined(__ia64__)
- if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, ram_pages)
- != ram_pages )
+ if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, nr_pages)
+ != nr_pages)
{
fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
exit(-1);
@@ -3221,7 +3059,7 @@ int main(int argc, char **argv)
if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- ram_pages)) == 0 )
+ nr_pages)) == 0 )
{
fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
exit(-1);
@@ -3229,7 +3067,7 @@ int main(int argc, char **argv)

if ( xc_ia64_get_pfn_list(xc_handle, domid,
page_array,
- ram_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
+ nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
{
fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
exit(-1);
@@ -3396,7 +3234,7 @@ int main(int argc, char **argv)
#if defined(TARGET_I386)
pc_init(ram_size, vga_ram_size, boot_device,
ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
+ kernel_filename, kernel_cmdline, initrd_filename, timeoffset);
#elif defined(TARGET_PPC)
ppc_init(ram_size, vga_ram_size, boot_device,
ds, fd_filename, snapshot,
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/ioemu/vl.h Mon May 22 14:13:38 2006 -0600
@@ -38,6 +38,8 @@
#include <fcntl.h>
#include <sys/stat.h>
#include "audio/audio.h"
+#include "xenctrl.h"
+#include "xs.h"

#ifndef O_LARGEFILE
#define O_LARGEFILE 0
@@ -113,6 +115,19 @@ void qemu_system_shutdown_request(void);

void main_loop_wait(int timeout);

+int unset_mm_mapping(int xc_handle,
+ uint32_t domid,
+ unsigned long nr_pages,
+ unsigned int address_bits,
+ unsigned long *extent_start);
+int set_mm_mapping(int xc_handle,
+ uint32_t domid,
+ unsigned long nr_pages,
+ unsigned int address_bits,
+ unsigned long *extent_start);
+
+extern int xc_handle;
+extern int domid;
extern int audio_enabled;
extern int sb16_enabled;
extern int adlib_enabled;
@@ -223,6 +238,7 @@ void console_select(unsigned int index);
/* serial ports */

#define MAX_SERIAL_PORTS 4
+#define SUMMA_PORT 1

extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];

@@ -618,12 +634,6 @@ extern const char* keyboard_layout;
extern const char* keyboard_layout;
extern int repeat_key;

-/* Mice */
-
-void summa_init(void *cookie, CharDriverState *chr);
-
-extern int summa_ok;
-
/* mc146818rtc.c */

typedef struct RTCState RTCState;
@@ -637,6 +647,12 @@ typedef struct SerialState SerialState;
typedef struct SerialState SerialState;
SerialState *serial_init(int base, int irq, CharDriverState *chr);
void ser_queue(SerialState *s, unsigned char c);
+
+/* Mice */
+
+void summa_init(SerialState *serial, CharDriverState *chr);
+
+extern int summa_ok;

/* i8259.c */

@@ -663,7 +679,7 @@ void pc_init(uint64_t ram_size, int vga_
void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
+ const char *initrd_filename, time_t timeoffset);

/* ppc.c */
void ppc_init (int ram_size, int vga_ram_size, int boot_device,
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xc_acm.c
--- a/tools/libxc/xc_acm.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xc_acm.c Mon May 22 14:13:38 2006 -0600
@@ -1,13 +1,10 @@
/******************************************************************************
+ * xc_acm.c
*
- * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005, 2006 IBM Corporation, R Sailer
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- *
- * Authors:
- * Reiner Sailer <sailer@watson.ibm.com>
- * Stefan Berger <stefanb@watson.ibm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -17,29 +14,23 @@

#include "xc_private.h"

-int xc_acm_op(int xc_handle, struct acm_op *op)
+
+int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size)
{
int ret = -1;
DECLARE_HYPERCALL;

- op->interface_version = ACM_INTERFACE_VERSION;
+ hypercall.op = __HYPERVISOR_acm_op;
+ hypercall.arg[0] = cmd;
+ hypercall.arg[1] = (unsigned long) arg;

- hypercall.op = __HYPERVISOR_acm_op;
- hypercall.arg[0] = (unsigned long) op;
-
- if (mlock(op, sizeof(*op)) != 0) {
- PERROR("Could not lock memory for Xen policy hypercall");
- goto out1;
+ if (mlock(arg, arg_size) != 0) {
+ PERROR("xc_acm_op: arg mlock failed");
+ goto out;
}
-
ret = do_xen_hypercall(xc_handle, &hypercall);
- ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
- if (ret < 0) {
- goto out2;
- }
- out2:
- safe_munlock(op, sizeof(*op));
- out1:
+ safe_munlock(arg, arg_size);
+ out:
return ret;
}

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xc_linux_build.c Mon May 22 14:13:38 2006 -0600
@@ -327,6 +327,13 @@ static int setup_pg_tables_pae(int xc_ha
*vl1e &= ~_PAGE_RW;
}
vl1e++;
+ }
+
+ /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */
+ if ( (vl3tab[3] & _PAGE_PRESENT) == 0 )
+ {
+ alloc_pt(l2tab, vl2tab, pl2tab);
+ vl3tab[3] = l2tab | L3_PROT;
}

munmap(vl1tab, PAGE_SIZE);
@@ -727,25 +734,28 @@ static int setup_guest(int xc_handle,
v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1);
if ( (v_end - vstack_end) < (512UL << 10) )
v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
-#if defined(__i386__)
- if ( dsi.pae_kernel )
- {
- /* FIXME: assumes one L2 pgtable @ 0xc0000000 */
- if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT_PAE)-1)) >>
- L2_PAGETABLE_SHIFT_PAE) + 2) <= nr_pt_pages )
- break;
- }
- else
- {
- if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
- L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
- break;
- }
-#endif
-#if defined(__x86_64__)
#define NR(_l,_h,_s) \
(((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
((_l) & ~((1UL<<(_s))-1))) >> (_s))
+#if defined(__i386__)
+ if ( dsi.pae_kernel )
+ {
+ if ( (1 + /* # L3 */
+ NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
+ NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */
+ /* Include a fourth mid-level page directory for Xen. */
+ (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE)))
+ <= nr_pt_pages )
+ break;
+ }
+ else
+ {
+ if ( (1 + /* # L2 */
+ NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
+ <= nr_pt_pages )
+ break;
+ }
+#elif defined(__x86_64__)
if ( (1 + /* # L4 */
NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
@@ -794,9 +804,11 @@ static int setup_guest(int xc_handle,
goto error_out;
}

- (load_funcs.loadimage)(image, image_size,
+ rc = (load_funcs.loadimage)(image, image_size,
xc_handle, dom, page_array,
&dsi);
+ if ( rc != 0 )
+ goto error_out;

if ( load_initrd(xc_handle, dom, initrd,
vinitrd_start - dsi.v_start, page_array) )
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xc_load_elf.c Mon May 22 14:13:38 2006 -0600
@@ -58,10 +58,10 @@ static int parseelfimage(const char *ima
Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
Elf_Phdr *phdr;
Elf_Shdr *shdr;
- unsigned long kernstart = ~0UL, kernend=0UL;
+ unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
const char *shstrtab;
char *guestinfo=NULL, *p;
- int h;
+ int h, virt_base_defined, elf_pa_off_defined;

if ( !IS_ELF(*ehdr) )
{
@@ -148,40 +148,65 @@ static int parseelfimage(const char *ima

dsi->xen_guest_string = guestinfo;

+ /* Initial guess for virt_base is 0 if it is not explicitly defined. */
+ p = strstr(guestinfo, "VIRT_BASE=");
+ virt_base_defined = (p != NULL);
+ virt_base = virt_base_defined ? strtoul(p+10, &p, 0) : 0;
+
+ /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
+ p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
+ elf_pa_off_defined = (p != NULL);
+ elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
+
+ if ( elf_pa_off_defined && !virt_base_defined )
+ goto bad_image;
+
for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
- if ( phdr->p_paddr < kernstart )
- kernstart = phdr->p_paddr;
- if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
- kernend = phdr->p_paddr + phdr->p_memsz;
- }
+ vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+ if ( (vaddr + phdr->p_memsz) < vaddr )
+ goto bad_image;
+ if ( vaddr < kernstart )
+ kernstart = vaddr;
+ if ( (vaddr + phdr->p_memsz) > kernend )
+ kernend = vaddr + phdr->p_memsz;
+ }
+
+ /*
+ * Legacy compatibility and images with no __xen_guest section: assume
+ * header addresses are virtual addresses, and that guest memory should be
+ * mapped starting at kernel load address.
+ */
+ dsi->v_start = virt_base_defined ? virt_base : kernstart;
+ dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start;
+
+ dsi->v_kernentry = ehdr->e_entry;
+ if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
+ dsi->v_kernentry = strtoul(p+11, &p, 0);

if ( (kernstart > kernend) ||
- (ehdr->e_entry < kernstart) ||
- (ehdr->e_entry > kernend) )
- {
- ERROR("Malformed ELF image.");
- return -EINVAL;
- }
-
- dsi->v_start = kernstart;
- if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
- dsi->v_start = strtoul(p+10, &p, 0);
+ (dsi->v_kernentry < kernstart) ||
+ (dsi->v_kernentry > kernend) ||
+ (dsi->v_start > kernstart) )
+ goto bad_image;

if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
dsi->load_symtab = 1;

dsi->v_kernstart = kernstart;
dsi->v_kernend = kernend;
- dsi->v_kernentry = ehdr->e_entry;
dsi->v_end = dsi->v_kernend;

loadelfsymtab(image, 0, 0, NULL, dsi);

return 0;
+
+ bad_image:
+ ERROR("Malformed ELF image.");
+ return -EINVAL;
}

static int
@@ -204,9 +229,11 @@ loadelfimage(

for ( done = 0; done < phdr->p_filesz; done += chunksz )
{
- pa = (phdr->p_paddr + done) - dsi->v_start;
+ pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
+ if ( va == NULL )
+ return -1;
chunksz = phdr->p_filesz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
@@ -217,9 +244,11 @@ loadelfimage(

for ( ; done < phdr->p_memsz; done += chunksz )
{
- pa = (phdr->p_paddr + done) - dsi->v_start;
+ pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
+ if ( va == NULL )
+ return -1;
chunksz = phdr->p_memsz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xc_ptrace.c Mon May 22 14:13:38 2006 -0600
@@ -157,6 +157,27 @@ static long nr_pages
static long nr_pages = 0;
static unsigned long *page_array = NULL;

+
+/*
+ * Translates physical addresses to machine addresses for HVM
+ * guests. For paravirtual domains the function will just return the
+ * given address.
+ *
+ * This function should be used when reading page directories/page
+ * tables.
+ *
+ */
+static unsigned long
+to_ma(int cpu,
+ unsigned long in_addr)
+{
+ unsigned long maddr = in_addr;
+
+ if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+ maddr = page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
+ return maddr;
+}
+
static void *
map_domain_va_32(
int xc_handle,
@@ -164,66 +185,34 @@ map_domain_va_32(
void *guest_va,
int perm)
{
- unsigned long pde, page;
- unsigned long va = (unsigned long)guest_va;
-
- static unsigned long cr3_phys[MAX_VIRT_CPUS];
- static uint32_t *cr3_virt[MAX_VIRT_CPUS];
- static unsigned long pde_phys[MAX_VIRT_CPUS];
- static uint32_t *pde_virt[MAX_VIRT_CPUS];
- static unsigned long page_phys[MAX_VIRT_CPUS];
- static uint32_t *page_virt[MAX_VIRT_CPUS];
- static int prev_perm[MAX_VIRT_CPUS];
-
- if (ctxt[cpu].ctrlreg[3] == 0)
- return NULL;
- if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
- {
- cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
- if ( cr3_virt[cpu] )
- munmap(cr3_virt[cpu], PAGE_SIZE);
- cr3_virt[cpu] = xc_map_foreign_range(
- xc_handle, current_domid, PAGE_SIZE, PROT_READ,
- cr3_phys[cpu] >> PAGE_SHIFT);
- if ( cr3_virt[cpu] == NULL )
- return NULL;
- }
- if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
- return NULL;
- if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
- pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
- if ( pde != pde_phys[cpu] )
- {
- pde_phys[cpu] = pde;
- if ( pde_virt[cpu] )
- munmap(pde_virt[cpu], PAGE_SIZE);
- pde_virt[cpu] = xc_map_foreign_range(
- xc_handle, current_domid, PAGE_SIZE, PROT_READ,
- pde_phys[cpu] >> PAGE_SHIFT);
- if ( pde_virt[cpu] == NULL )
- return NULL;
- }
- if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
- return NULL;
- if (ctxt[cpu].flags & VGCF_HVM_GUEST)
- page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
- if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
- {
- page_phys[cpu] = page;
- if ( page_virt[cpu] )
- munmap(page_virt[cpu], PAGE_SIZE);
- page_virt[cpu] = xc_map_foreign_range(
- xc_handle, current_domid, PAGE_SIZE, perm,
- page_phys[cpu] >> PAGE_SHIFT);
- if ( page_virt[cpu] == NULL )
- {
- page_phys[cpu] = 0;
- return NULL;
- }
- prev_perm[cpu] = perm;
- }
-
- return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
+ unsigned long l1p, p, va = (unsigned long)guest_va;
+ uint32_t *l2, *l1;
+ static void *v[MAX_VIRT_CPUS];
+
+ l2 = xc_map_foreign_range(
+ xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
+ if ( l2 == NULL )
+ return NULL;
+
+ l1p = to_ma(cpu, l2[l2_table_offset(va)]);
+ munmap(l2, PAGE_SIZE);
+ if ( !(l1p & _PAGE_PRESENT) )
+ return NULL;
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l1p >> PAGE_SHIFT);
+ if ( l1 == NULL )
+ return NULL;
+
+ p = to_ma(cpu, l1[l1_table_offset(va)]);
+ munmap(l1, PAGE_SIZE);
+ if ( !(p & _PAGE_PRESENT) )
+ return NULL;
+ if ( v[cpu] != NULL )
+ munmap(v[cpu], PAGE_SIZE);
+ v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
+ if ( v[cpu] == NULL )
+ return NULL;
+
+ return (void *)((unsigned long)v[cpu] | (va & (PAGE_SIZE - 1)));
}


@@ -236,37 +225,40 @@ map_domain_va_pae(
{
unsigned long l2p, l1p, p, va = (unsigned long)guest_va;
uint64_t *l3, *l2, *l1;
- static void *v;
+ static void *v[MAX_VIRT_CPUS];

l3 = xc_map_foreign_range(
xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
if ( l3 == NULL )
return NULL;

- l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
- l2p = page_array[l2p];
- l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
+ l2p = to_ma(cpu, l3[l3_table_offset_pae(va)]);
munmap(l3, PAGE_SIZE);
+ if ( !(l2p & _PAGE_PRESENT) )
+ return NULL;
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
if ( l2 == NULL )
return NULL;

- l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
- l1p = page_array[l1p];
- l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+ l1p = to_ma(cpu, l2[l2_table_offset_pae(va)]);
munmap(l2, PAGE_SIZE);
+ if ( !(l1p & _PAGE_PRESENT) )
+ return NULL;
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
if ( l1 == NULL )
return NULL;

- p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
- p = page_array[p];
- if ( v != NULL )
- munmap(v, PAGE_SIZE);
- v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+ p = to_ma(cpu, l1[l1_table_offset_pae(va)]);
munmap(l1, PAGE_SIZE);
- if ( v == NULL )
- return NULL;
-
- return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+ if ( !(p & _PAGE_PRESENT) )
+ return NULL;
+ if ( v[cpu] != NULL )
+ munmap(v[cpu], PAGE_SIZE);
+ v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
+ if ( v[cpu] == NULL )
+ return NULL;
+
+ return (void *)((unsigned long)v[cpu] | (va & (PAGE_SIZE - 1)));
}

#ifdef __x86_64__
@@ -279,7 +271,7 @@ map_domain_va_64(
{
unsigned long l3p, l2p, l1p, l1e, p, va = (unsigned long)guest_va;
uint64_t *l4, *l3, *l2, *l1;
- static void *v;
+ static void *v[MAX_VIRT_CPUS];

if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
return map_domain_va_32(xc_handle, cpu, guest_va, perm);
@@ -289,44 +281,50 @@ map_domain_va_64(
if ( l4 == NULL )
return NULL;

- l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
- l3p = page_array[l3p];
- l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p);
+ l3p = to_ma(cpu, l4[l4_table_offset(va)]);
munmap(l4, PAGE_SIZE);
+ if ( !(l3p & _PAGE_PRESENT) )
+ return NULL;
+ l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p >> PAGE_SHIFT);
if ( l3 == NULL )
return NULL;

- l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
- l2p = page_array[l2p];
- l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
+ l2p = to_ma(cpu, l3[l3_table_offset(va)]);
munmap(l3, PAGE_SIZE);
+ if ( !(l2p & _PAGE_PRESENT) )
+ return NULL;
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
if ( l2 == NULL )
return NULL;

l1 = NULL;
- l1e = l2[l2_table_offset(va)];
+ l1e = to_ma(cpu, l2[l2_table_offset(va)]);
+ if ( !(l1e & _PAGE_PRESENT) )
+ {
+ munmap(l2, PAGE_SIZE);
+ return NULL;
+ }
l1p = l1e >> PAGE_SHIFT;
if (l1e & 0x80) { /* 2M pages */
- p = (l1p + l1_table_offset(va));
+ p = to_ma(cpu, (l1p + l1_table_offset(va)) << PAGE_SHIFT);
} else { /* 4K pages */
- l1p = page_array[l1p];
- l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+ l1p = to_ma(cpu, l1p);
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
munmap(l2, PAGE_SIZE);
if ( l1 == NULL )
return NULL;

- p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
- }
- p = page_array[p];
- if ( v != NULL )
- munmap(v, PAGE_SIZE);
- v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+ p = to_ma(cpu, l1[l1_table_offset(va)]);
+ }
+ if ( v[cpu] != NULL )
+ munmap(v[cpu], PAGE_SIZE);
+ v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
if (l1)
munmap(l1, PAGE_SIZE);
- if ( v == NULL )
- return NULL;
-
- return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+ if ( v[cpu] == NULL )
+ return NULL;
+
+ return (void *)((unsigned long)v[cpu] | (va & (PAGE_SIZE - 1)));
}
#endif

@@ -381,7 +379,7 @@ map_domain_va(
if ( v != NULL )
munmap(v, PAGE_SIZE);

- page = page_array[va >> PAGE_SHIFT] << PAGE_SHIFT;
+ page = to_ma(cpu, page_array[va >> PAGE_SHIFT]);

v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
perm, page >> PAGE_SHIFT);
@@ -510,6 +508,11 @@ xc_ptrace(
break;

case PTRACE_GETFPREGS:
+ if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
+ goto out_error;
+ memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof (elf_fpregset_t));
+ break;
+
case PTRACE_GETFPXREGS:
if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
goto out_error;
@@ -518,7 +521,7 @@ xc_ptrace(

case PTRACE_SETREGS:
if (current_isfile)
- goto out_unspported; /* XXX not yet supported */
+ goto out_unsupported; /* XXX not yet supported */
SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
&ctxt[cpu])))
@@ -526,8 +529,8 @@ xc_ptrace(
break;

case PTRACE_SINGLESTEP:
- if (!current_isfile)
- goto out_unspported; /* XXX not yet supported */
+ if (current_isfile)
+ goto out_unsupported; /* XXX not yet supported */
/* XXX we can still have problems if the user switches threads
* during single-stepping - but that just seems retarded
*/
@@ -540,7 +543,7 @@ xc_ptrace(
case PTRACE_CONT:
case PTRACE_DETACH:
if (current_isfile)
- goto out_unspported; /* XXX not yet supported */
+ goto out_unsupported; /* XXX not yet supported */
if ( request != PTRACE_SINGLESTEP )
{
FOREACH_CPU(cpumap, index) {
@@ -603,7 +606,7 @@ xc_ptrace(
case PTRACE_POKEUSER:
case PTRACE_SYSCALL:
case PTRACE_KILL:
- goto out_unspported; /* XXX not yet supported */
+ goto out_unsupported; /* XXX not yet supported */

case PTRACE_TRACEME:
printf("PTRACE_TRACEME is an invalid request under Xen\n");
@@ -618,7 +621,7 @@ xc_ptrace(
errno = EINVAL;
return retval;

- out_unspported:
+ out_unsupported:
#ifdef DEBUG
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xc_tbuf.c
--- a/tools/libxc/xc_tbuf.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xc_tbuf.c Mon May 22 14:13:38 2006 -0600
@@ -16,7 +16,7 @@

#include "xc_private.h"

-int xc_tbuf_enable(int xc_handle, int enable)
+static int tbuf_enable(int xc_handle, int enable)
{
DECLARE_DOM0_OP;

@@ -30,7 +30,7 @@ int xc_tbuf_enable(int xc_handle, int en
return xc_dom0_op(xc_handle, &op);
}

-int xc_tbuf_set_size(int xc_handle, uint32_t size)
+int xc_tbuf_set_size(int xc_handle, unsigned long size)
{
DECLARE_DOM0_OP;

@@ -42,7 +42,7 @@ int xc_tbuf_set_size(int xc_handle, uint
return xc_dom0_op(xc_handle, &op);
}

-int xc_tbuf_get_size(int xc_handle, uint32_t *size)
+int xc_tbuf_get_size(int xc_handle, unsigned long *size)
{
int rc;
DECLARE_DOM0_OP;
@@ -57,10 +57,17 @@ int xc_tbuf_get_size(int xc_handle, uint
return rc;
}

-int xc_tbuf_get_mfn(int xc_handle, unsigned long *mfn)
+int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn,
+ unsigned long *size)
{
+ DECLARE_DOM0_OP;
int rc;
- DECLARE_DOM0_OP;
+
+ if ( xc_tbuf_set_size(xc_handle, cnt) != 0 )
+ return -1;
+
+ if ( tbuf_enable(xc_handle, 1) != 0 )
+ return -1;

op.cmd = DOM0_TBUFCONTROL;
op.interface_version = DOM0_INTERFACE_VERSION;
@@ -68,8 +75,17 @@ int xc_tbuf_get_mfn(int xc_handle, unsig

rc = xc_dom0_op(xc_handle, &op);
if ( rc == 0 )
- *mfn = op.u.tbufcontrol.buffer_mfn;
- return rc;
+ {
+ *size = op.u.tbufcontrol.size;
+ *mfn = op.u.tbufcontrol.buffer_mfn;
+ }
+
+ return 0;
+}
+
+int xc_tbuf_disable(int xc_handle)
+{
+ return tbuf_enable(xc_handle, 0);
}

int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask)
@@ -95,3 +111,4 @@ int xc_tbuf_set_evt_mask(int xc_handle,

return do_dom0_op(xc_handle, &op);
}
+
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xenctrl.h Mon May 22 14:13:38 2006 -0600
@@ -9,6 +9,7 @@
#ifndef XENCTRL_H
#define XENCTRL_H

+#include <stddef.h>
#include <stdint.h>
#include <sys/ptrace.h>
#include <xen/xen.h>
@@ -529,15 +530,23 @@ long xc_get_tot_pages(int xc_handle, uin
*/

/**
- * This function enables or disables tracing. Trace buffer memory must
- * be already allocated by setting the size to a non-zero value, otherwise
- * tracing cannot be enabled.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm enable the desired action, 1 for enable, 0 for disable
- * @return 0 on success, -1 on failure.
- */
-int xc_tbuf_enable(int xc_handle, int enable);
+ * xc_tbuf_enable - enable tracing buffers
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm cnt size of tracing buffers to create (in pages)
+ * @parm mfn location to store mfn of the trace buffers to
+ * @parm size location to store the size (in bytes) of a trace buffer to
+ *
+ * Gets the machine address of the trace pointer area and the size of the
+ * per CPU buffers.
+ */
+int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn,
+ unsigned long *size);
+
+/*
+ * Disable tracing buffers.
+ */
+int xc_tbuf_disable(int xc_handle);

/**
* This function sets the size of the trace buffers. Setting the size
@@ -549,7 +558,7 @@ int xc_tbuf_enable(int xc_handle, int en
* @parm size the size in pages per cpu for the trace buffers
* @return 0 on success, -1 on failure.
*/
-int xc_tbuf_set_size(int xc_handle, uint32_t size);
+int xc_tbuf_set_size(int xc_handle, unsigned long size);

/**
* This function retrieves the current size of the trace buffers.
@@ -559,16 +568,7 @@ int xc_tbuf_set_size(int xc_handle, uint
* @parm size will contain the size in bytes for the trace buffers
* @return 0 on success, -1 on failure.
*/
-int xc_tbuf_get_size(int xc_handle, uint32_t *size);
-
-/**
- * This function retrieves the machine frame of the trace buffer.
-
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm mfn will contain the machine frame of the buffer.
- * @return 0 on success, -1 on failure.
- */
-int xc_tbuf_get_mfn(int xc_handle, unsigned long *mfn);
+int xc_tbuf_get_size(int xc_handle, unsigned long *size);

int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask);

@@ -594,6 +594,6 @@ int xc_add_mmu_update(int xc_handle, xc_
unsigned long long ptr, unsigned long long val);
int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);

-int xc_acm_op(int xc_handle, struct acm_op *op);
+int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size);

#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/libxc/xg_private.h Mon May 22 14:13:38 2006 -0600
@@ -136,8 +136,11 @@ struct domain_setup_info
unsigned long v_kernend;
unsigned long v_kernentry;

+ unsigned long elf_paddr_offset;
+
+ unsigned int pae_kernel;
+
unsigned int load_symtab;
- unsigned int pae_kernel;
unsigned long symtab_addr;
unsigned long symtab_len;

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/lowlevel/acm/acm.c
--- a/tools/python/xen/lowlevel/acm/acm.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/lowlevel/acm/acm.c Mon May 22 14:13:38 2006 -0600
@@ -38,7 +38,7 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)
/* generic shared function */
void * __getssid(int domid, uint32_t *buflen)
{
- struct acm_op op;
+ struct acm_getssid getssid;
int xc_handle;
#define SSID_BUFFER_SIZE 4096
void *buf = NULL;
@@ -51,14 +51,13 @@ void * __getssid(int domid, uint32_t *bu
goto out2;
}
memset(buf, 0, SSID_BUFFER_SIZE);
- op.cmd = ACM_GETSSID;
- op.interface_version = ACM_INTERFACE_VERSION;
- op.u.getssid.ssidbuf = buf;
- op.u.getssid.ssidbuf_size = SSID_BUFFER_SIZE;
- op.u.getssid.get_ssid_by = DOMAINID;
- op.u.getssid.id.domainid = domid;
-
- if (xc_acm_op(xc_handle, &op) < 0) {
+ getssid.interface_version = ACM_INTERFACE_VERSION;
+ getssid.ssidbuf = buf;
+ getssid.ssidbuf_size = SSID_BUFFER_SIZE;
+ getssid.get_ssid_by = DOMAINID;
+ getssid.id.domainid = domid;
+
+ if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) {
if (errno == EACCES)
PERROR("ACM operation failed.");
free(buf);
@@ -147,7 +146,7 @@ static PyObject *getdecision(PyObject *
static PyObject *getdecision(PyObject * self, PyObject * args)
{
char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
- struct acm_op op;
+ struct acm_getdecision getdecision;
int xc_handle;

if (!PyArg_ParseTuple(args, "ssss", &arg1_name, &arg1, &arg2_name, &arg2)) {
@@ -163,34 +162,33 @@ static PyObject *getdecision(PyObject *
(strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
return NULL;

- op.cmd = ACM_GETDECISION;
- op.interface_version = ACM_INTERFACE_VERSION;
- op.u.getdecision.hook = SHARING;
+ getdecision.interface_version = ACM_INTERFACE_VERSION;
+ getdecision.hook = SHARING;
if (!strcmp(arg1_name, "domid")) {
- op.u.getdecision.get_decision_by1 = DOMAINID;
- op.u.getdecision.id1.domainid = atoi(arg1);
- } else {
- op.u.getdecision.get_decision_by1 = SSIDREF;
- op.u.getdecision.id1.ssidref = atol(arg1);
+ getdecision.get_decision_by1 = DOMAINID;
+ getdecision.id1.domainid = atoi(arg1);
+ } else {
+ getdecision.get_decision_by1 = SSIDREF;
+ getdecision.id1.ssidref = atol(arg1);
}
if (!strcmp(arg2_name, "domid")) {
- op.u.getdecision.get_decision_by2 = DOMAINID;
- op.u.getdecision.id2.domainid = atoi(arg2);
- } else {
- op.u.getdecision.get_decision_by2 = SSIDREF;
- op.u.getdecision.id2.ssidref = atol(arg2);
- }
-
- if (xc_acm_op(xc_handle, &op) < 0) {
+ getdecision.get_decision_by2 = DOMAINID;
+ getdecision.id2.domainid = atoi(arg2);
+ } else {
+ getdecision.get_decision_by2 = SSIDREF;
+ getdecision.id2.ssidref = atol(arg2);
+ }
+
+ if (xc_acm_op(xc_handle, ACMOP_getdecision, &getdecision, sizeof(getdecision)) < 0) {
if (errno == EACCES)
PERROR("ACM operation failed.");
}

xc_interface_close(xc_handle);

- if (op.u.getdecision.acm_decision == ACM_ACCESS_PERMITTED)
+ if (getdecision.acm_decision == ACM_ACCESS_PERMITTED)
decision = "PERMITTED";
- else if (op.u.getdecision.acm_decision == ACM_ACCESS_DENIED)
+ else if (getdecision.acm_decision == ACM_ACCESS_DENIED)
decision = "DENIED";

return Py_BuildValue("s", decision);
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon May 22 14:13:38 2006 -0600
@@ -1172,7 +1172,7 @@ PyXc_init(XcObject *self, PyObject *args
PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
{
if ((self->xc_handle = xc_interface_open()) == -1) {
- PyErr_SetFromErrno(PyExc_RuntimeError);
+ PyErr_SetFromErrno(xc_error);
return -1;
}

@@ -1245,7 +1245,7 @@ PyMODINIT_FUNC initxc(void)
if (m == NULL)
return;

- xc_error = PyErr_NewException(PKG ".error", NULL, NULL);
+ xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
zero = PyInt_FromLong(0);

/* KAF: This ensures that we get debug output in a timely manner. */
@@ -1254,6 +1254,9 @@ PyMODINIT_FUNC initxc(void)

Py_INCREF(&PyXcType);
PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
+
+ Py_INCREF(xc_error);
+ PyModule_AddObject(m, "Error", xc_error);
}


diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py Mon May 22 14:13:38 2006 -0600
@@ -54,7 +54,7 @@ def read_exact(fd, size, errmsg):



-def save(fd, dominfo, live, dst):
+def save(fd, dominfo, network, live, dst):
write_exact(fd, SIGNATURE, "could not write guest state file: signature")

config = sxp.to_string(dominfo.sxpr())
@@ -66,7 +66,7 @@ def save(fd, dominfo, live, dst):
dominfo.setName('migrating-' + domain_name)

try:
- dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP1, domain_name)
+ dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name)

write_exact(fd, pack("!i", len(config)),
"could not write guest state file: config len")
@@ -88,10 +88,10 @@ def save(fd, dominfo, live, dst):
log.debug("Suspending %d ...", dominfo.getDomid())
dominfo.shutdown('suspend')
dominfo.waitForShutdown()
- dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP2,
+ dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2,
domain_name)
log.info("Domain %d suspended.", dominfo.getDomid())
- dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP3,
+ dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3,
domain_name)
tochild.write("done\n")
tochild.flush()
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/XendDomain.py Mon May 22 14:13:38 2006 -0600
@@ -408,7 +408,7 @@ class XendDomain:
raise XendError("Cannot migrate privileged domain %i" % domid)

""" The following call may raise a XendError exception """
- dominfo.testMigrateDevices(live, dst)
+ dominfo.testMigrateDevices(True, dst)

if port == 0:
port = xroot.get_xend_relocation_port()
@@ -420,7 +420,7 @@ class XendDomain:

sock.send("receive\n")
sock.recv(80)
- XendCheckpoint.save(sock.fileno(), dominfo, live, dst)
+ XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst)


def domain_save(self, domid, dst):
@@ -440,7 +440,7 @@ class XendDomain:
fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
try:
# For now we don't support 'live checkpoint'
- return XendCheckpoint.save(fd, dominfo, False, dst)
+ return XendCheckpoint.save(fd, dominfo, False, False, dst)
finally:
os.close(fd)
except OSError, ex:
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon May 22 14:13:38 2006 -0600
@@ -29,6 +29,7 @@ import string
import string
import time
import threading
+import os

import xen.lowlevel.xc
from xen.util import asserts
@@ -1264,7 +1265,14 @@ class XendDomainInfo:
m = self.image.getDomainMemory(self.info['memory'] * 1024)
balloon.free(m)
xc.domain_setmaxmem(self.domid, m)
- xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
+
+ init_reservation = self.info['memory'] * 1024
+ if os.uname()[4] == 'ia64':
+ # Workaround until ia64 properly supports ballooning.
+ init_reservation = m
+
+ xc.domain_memory_increase_reservation(self.domid, init_reservation,
+ 0, 0)

self.createChannels()

@@ -1443,36 +1451,40 @@ class XendDomainInfo:

## public:

- def testMigrateDevices(self, live, dst):
+ def testMigrateDevices(self, network, dst):
""" Notify all device about intention of migration
@raise: XendError for a device that cannot be migrated
"""
for (n, c) in self.info['device']:
- rc = self.migrateDevice(n, c, live, dst, DEV_MIGRATE_TEST)
+ rc = self.migrateDevice(n, c, network, dst, DEV_MIGRATE_TEST)
if rc != 0:
raise XendError("Device of type '%s' refuses migration." % n)

- def migrateDevices(self, live, dst, step, domName=''):
+ def migrateDevices(self, network, dst, step, domName=''):
"""Notify the devices about migration
"""
ctr = 0
try:
for (n, c) in self.info['device']:
- self.migrateDevice(n, c, live, dst, step, domName)
+ self.migrateDevice(n, c, network, dst, step, domName)
ctr = ctr + 1
except:
for (n, c) in self.info['device']:
if ctr == 0:
step = step - 1
ctr = ctr - 1
- self.recoverMigrateDevice(n, c, live, dst, step, domName)
+ self.recoverMigrateDevice(n, c, network, dst, step, domName)
raise

- def migrateDevice(self, deviceClass, deviceConfig, live, dst, step, domName=''):
- return self.getDeviceController(deviceClass).migrate(deviceConfig, live, dst, step, domName)
-
- def recoverMigrateDevice(self, deviceClass, deviceConfig, live, dst, step, domName=''):
- return self.getDeviceController(deviceClass).recover_migrate(deviceConfig, live, dst, step, domName)
+ def migrateDevice(self, deviceClass, deviceConfig, network, dst,
+ step, domName=''):
+ return self.getDeviceController(deviceClass).migrate(deviceConfig,
+ network, dst, step, domName)
+
+ def recoverMigrateDevice(self, deviceClass, deviceConfig, network,
+ dst, step, domName=''):
+ return self.getDeviceController(deviceClass).recover_migrate(
+ deviceConfig, network, dst, step, domName)

def waitForDevices(self):
"""Wait for this domain's configured devices to connect.
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/image.py Mon May 22 14:13:38 2006 -0600
@@ -19,6 +19,7 @@

import os, string
import re
+import math

import xen.lowlevel.xc
from xen.xend import sxp
@@ -141,11 +142,16 @@ class ImageHandler:
% (self.ostype, self.vm.getDomid(), str(result)))


- def getDomainMemory(self, mem):
+ def getDomainMemory(self, mem_kb):
"""@return The memory required, in KiB, by the domain to store the
- given amount, also in KiB. This is normally just mem, but HVM domains
- have overheads to account for."""
- return mem
+ given amount, also in KiB."""
+ if os.uname()[4] != 'ia64':
+ # A little extra because auto-ballooning is broken w.r.t. HVM
+ # guests. Also, slack is necessary for live migration since that
+ # uses shadow page tables.
+ if 'hvm' in xc.xeninfo()['xen_caps']:
+ mem_kb += 4*1024;
+ return mem_kb

def buildDomain(self):
"""Build the domain. Define in subclass."""
@@ -377,15 +383,20 @@ class HVMImageHandler(ImageHandler):
os.waitpid(self.pid, 0)
self.pid = 0

- def getDomainMemory(self, mem):
+ def getDomainMemory(self, mem_kb):
"""@see ImageHandler.getDomainMemory"""
- page_kb = 4
- extra_pages = 0
if os.uname()[4] == 'ia64':
page_kb = 16
# ROM size for guest firmware, ioreq page and xenstore page
extra_pages = 1024 + 2
- return mem + extra_pages * page_kb
+ else:
+ page_kb = 4
+ # This was derived emperically:
+ # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
+ # + 4 to avoid low-memory condition
+ extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
+ extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
+ return mem_kb + extra_pages * page_kb

def register_shutdown_watch(self):
""" add xen store watch on control/shutdown """
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/server/DevController.py Mon May 22 14:13:38 2006 -0600
@@ -267,9 +267,9 @@ class DevController:

raise NotImplementedError()

- def migrate(self, deviceConfig, live, dst, step, domName):
- """ Migration of a device. The 'live' parameter indicates
- whether the device is live-migrated (live=1). 'dst' then gives
+ def migrate(self, deviceConfig, network, dst, step, domName):
+ """ Migration of a device. The 'network' parameter indicates
+ whether the device is network-migrated (True). 'dst' then gives
the hostname of the machine to migrate to.
This function is called for 4 steps:
If step == 0: Check whether the device is ready to be migrated
@@ -296,7 +296,7 @@ class DevController:
return 0


- def recover_migrate(self, deviceConfig, list, dst, step, domName):
+ def recover_migrate(self, deviceConfig, network, dst, step, domName):
""" Recover from device migration. The given step was the
last one that was successfully executed.
"""
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/server/pciif.py Mon May 22 14:13:38 2006 -0600
@@ -31,6 +31,7 @@ import xen.lowlevel.xc

from xen.util.pci import PciDevice
import resource
+import re

xc = xen.lowlevel.xc.xc()

@@ -106,6 +107,30 @@ class PciController(DevController):

return (0, back, {})

+ def configuration(self, devid):
+ """@see DevController.configuration"""
+
+ result = DevController.configuration(self, devid)
+
+ (num_devs) = self.readBackend(devid, 'num_devs')
+
+ for i in range(int(num_devs)):
+ (dev_config) = self.readBackend(devid, 'dev-%d'%(i))
+
+ pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
+ r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
+ r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
+ r"(?P<func>[0-9a-fA-F]{1,2})", dev_config)
+ if pci_match!=None:
+ pci_dev_info = pci_match.groupdict('0')
+ result.append( ['dev', \
+ ['domain', '0x'+pci_dev_info['domain']], \
+ ['bus', '0x'+pci_dev_info['bus']], \
+ ['slot', '0x'+pci_dev_info['slot']], \
+ ['func', '0x'+pci_dev_info['func']]])
+
+ return result
+
def setupDevice(self, domain, bus, slot, func):
""" Attach I/O resources for device to frontend domain
"""
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/python/xen/xend/server/tpmif.py Mon May 22 14:13:38 2006 -0600
@@ -71,12 +71,12 @@ class TPMifController(DevController):

return result

- def migrate(self, deviceConfig, live, dst, step, domName):
+ def migrate(self, deviceConfig, network, dst, step, domName):
"""@see DevContoller.migrate"""
- if live:
+ if network:
tool = xroot.get_external_migration_tool()
if tool != '':
- log.info("Request to live-migrate device to %s. step=%d.",
+ log.info("Request to network-migrate device to %s. step=%d.",
dst, step)

if step == DEV_MIGRATE_TEST:
@@ -99,12 +99,12 @@ class TPMifController(DevController):
return -1
return 0

- def recover_migrate(self, deviceConfig, live, dst, step, domName):
+ def recover_migrate(self, deviceConfig, network, dst, step, domName):
"""@see DevContoller.recover_migrate"""
- if live:
+ if network:
tool = xroot.get_external_migration_tool()
if tool != '':
- log.info("Request to recover live-migrated device. last good step=%d.",
+ log.info("Request to recover network-migrated device. last good step=%d.",
step)
fd = os.popen("%s -type vtpm -step %d -host %s -domname %s -recover" %
(tool, step, dst, domName),
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/security/Makefile
--- a/tools/security/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/tools/security/Makefile Mon May 22 14:13:38 2006 -0600
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk

CFLAGS += -Werror
CFLAGS += -fno-strict-aliasing
-CFLAGS += -I.
+CFLAGS += -I. -I $(XEN_LIBXC)

CPPFLAGS += -MMD -MF .$*.d
PROG_DEPS = .*.d
@@ -89,7 +89,7 @@ build: mk-symlinks $(ACM_INST_TOOLS) $(A
chmod 700 $(ACM_SCRIPTS)

xensec_tool: $(OBJS_TOOL)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -L$(XEN_LIBXC) -lxenctrl

xensec_xml2bin: $(OBJS_XML2BIN)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/security/secpol_tool.c Mon May 22 14:13:38 2006 -0600
@@ -231,14 +231,16 @@ uint8_t pull_buffer[PULL_CACHE_SIZE];
uint8_t pull_buffer[PULL_CACHE_SIZE];
int acm_domain_getpolicy(int xc_handle)
{
- struct acm_op op;
+ struct acm_getpolicy getpolicy;
int ret;

memset(pull_buffer, 0x00, sizeof(pull_buffer));
- op.cmd = ACM_GETPOLICY;
- op.u.getpolicy.pullcache = (void *) pull_buffer;
- op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
- if ((ret = xc_acm_op(xc_handle, &op)) < 0) {
+ getpolicy.interface_version = ACM_INTERFACE_VERSION;
+ getpolicy.pullcache = (void *) pull_buffer;
+ getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
+
+ if (ret < 0) {
printf("ACM operation failed: errno=%d\n", errno);
if (errno == EACCES)
fprintf(stderr, "ACM operation failed -- need to"
@@ -275,13 +277,13 @@ int acm_domain_loadpolicy(int xc_handle,
goto free_out;
}
if (len == read(fd, buffer, len)) {
- struct acm_op op;
+ struct acm_setpolicy setpolicy;
/* dump it and then push it down into xen/acm */
acm_dump_policy_buffer(buffer, len);
- op.cmd = ACM_SETPOLICY;
- op.u.setpolicy.pushcache = (void *) buffer;
- op.u.setpolicy.pushcache_size = len;
- ret = xc_acm_op(xc_handle, &op);
+ setpolicy.interface_version = ACM_INTERFACE_VERSION;
+ setpolicy.pushcache = (void *) buffer;
+ setpolicy.pushcache_size = len;
+ ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy));

if (ret)
printf
@@ -322,15 +324,15 @@ int acm_domain_dumpstats(int xc_handle)
int acm_domain_dumpstats(int xc_handle)
{
uint8_t stats_buffer[PULL_STATS_SIZE];
- struct acm_op op;
+ struct acm_dumpstats dumpstats;
int ret;
struct acm_stats_buffer *stats;

memset(stats_buffer, 0x00, sizeof(stats_buffer));
- op.cmd = ACM_DUMPSTATS;
- op.u.dumpstats.pullcache = (void *) stats_buffer;
- op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
- ret = xc_acm_op(xc_handle, &op);
+ dumpstats.interface_version = ACM_INTERFACE_VERSION;
+ dumpstats.pullcache = (void *) stats_buffer;
+ dumpstats.pullcache_size = sizeof(stats_buffer);
+ ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));

if (ret < 0) {
printf
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/tests/Makefile
--- a/tools/tests/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/tools/tests/Makefile Mon May 22 14:13:38 2006 -0600
@@ -3,8 +3,6 @@ include $(XEN_ROOT)/tools/Rules.mk
include $(XEN_ROOT)/tools/Rules.mk

TARGET := test_x86_emulator
-
-HOSTCFLAGS += -D__TEST_HARNESS__

.PHONY: all
all: $(TARGET)
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm/Makefile
--- a/tools/vtpm/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm/Makefile Mon May 22 14:13:38 2006 -0600
@@ -21,7 +21,9 @@ build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) b

.PHONY: install
install: build
- $(MAKE) -C $(TPM_EMULATOR_DIR) $@
+ if [ "$(BUILD_EMULATOR)" = "y" ]; then \
+ $(MAKE) -C $(TPM_EMULATOR_DIR) $@ ;\
+ fi
$(MAKE) -C $(VTPM_DIR) $@

.PHONY: clean
@@ -46,20 +48,21 @@ mrproper:
# Create vtpm and TPM emulator dirs
# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch tpm_emulator-0.2b-x86_64.patch
- tar -xzf $(TPM_EMULATOR_TARFILE);
- rm -rf $(TPM_EMULATOR_DIR)
- mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR);
-
- -cd $(TPM_EMULATOR_DIR); \
- patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
- patch -p1 <../tpm_emulator.patch
+ if [ "$(BUILD_EMULATOR)" = "y" ]; then \
+ tar -xzf $(TPM_EMULATOR_TARFILE); \
+ rm -rf $(TPM_EMULATOR_DIR); \
+ mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); \
+ cd $(TPM_EMULATOR_DIR); \
+ patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
+ patch -p1 <../tpm_emulator.patch; \
+ fi

$(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.2b-x86_64.patch vtpm.patch
tar -xzf $(TPM_EMULATOR_TARFILE);
rm -rf $(VTPM_DIR)
mv tpm_emulator-0.2 $(VTPM_DIR);

- -cd $(VTPM_DIR); \
+ cd $(VTPM_DIR); \
patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
patch -p1 <../vtpm.patch

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm/tpm_emulator.patch
--- a/tools/vtpm/tpm_emulator.patch Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm/tpm_emulator.patch Mon May 22 14:13:38 2006 -0600
@@ -52,7 +52,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+CUR_DIR := $(shell pwd)
+LINUX_VERSION := $(shell cat $(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep "2.6" | gawk '{ print $$3 }' )
-+KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen0
++KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen
MOD_SUBDIR := misc
COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm/vtpm.patch Mon May 22 14:13:38 2006 -0600
@@ -1,12 +1,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS vtpm/AUTHORS
--- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/AUTHORS 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/AUTHORS 2006-05-17 09:31:11.000000000 -0700
@@ -1 +1,2 @@
Mario Strasser <mast@gmx.net>
+INTEL Corp <>
diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog vtpm/ChangeLog
--- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/ChangeLog 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/ChangeLog 2006-05-17 09:31:11.000000000 -0700
@@ -1,3 +1,7 @@
+2005-08-16 Intel Corp
+ Moved module out of kernel to run as a ring 3 app
@@ -16,8 +16,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
* all: some typos corrected
* tpm_integrity.c: bug in TPM_Extend fixed
diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2005-09-15 19:21:42.508873032 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c 2005-09-15 19:25:37.319176440 -0700
+--- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -59,10 +59,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
{
- void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
-- "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
+ void *ret = (void*)malloc(new_size);
+ if (!ret) error("GMP: Cannot reallocate memory "
-+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
memcpy(ret, oldptr, old_size);
- kfree(oldptr);
+ free(oldptr);
@@ -80,7 +79,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/

diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
--- orig/tpm_emulator-0.2-x86_64/crypto/rsa.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/crypto/rsa.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/crypto/rsa.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -107,7 +106,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
SHA1_DIGEST_LENGTH) != 0) return -1;
diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.2-x86_64/linux_module.c 2005-09-15 19:22:40.343080896 -0700
+--- orig/tpm_emulator-0.2-x86_64/linux_module.c 2006-05-17 09:34:13.000000000 -0700
+++ vtpm/linux_module.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,163 +0,0 @@
-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
@@ -274,8 +273,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-}
-
diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.2-x86_64/linux_module.h 2005-09-15 19:21:14.844078720 -0700
-+++ vtpm/linux_module.h 2005-09-14 20:27:22.000000000 -0700
+--- orig/tpm_emulator-0.2-x86_64/linux_module.h 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/linux_module.h 2006-05-17 09:31:11.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -376,8 +375,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
#define LE16_TO_CPU(x) __le16_to_cpu(x)

diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.2-x86_64/Makefile 2005-09-15 19:21:14.845078568 -0700
-+++ vtpm/Makefile 2005-09-14 20:27:22.000000000 -0700
+--- orig/tpm_emulator-0.2-x86_64/Makefile 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/Makefile 2006-05-17 09:31:11.000000000 -0700
@@ -1,22 +1,31 @@
# Software-Based Trusted Platform Module (TPM) Emulator for Linux
# Copyright (C) 2004 Mario Strasser <mast@gmx.net>
@@ -410,7 +409,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
+
+CC := gcc
+CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
-+CFLAGS += -I. -Itpm
++CFLAGS += -I. -Itpm -I../../vtpm_manager/manager
+
+# Is the simulator running in it's own vm?
+#CFLAGS += -DVTPM_MULTI_VM
@@ -470,8 +469,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
$(src)/crypto/libgmp.a:
test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
diff -uprN orig/tpm_emulator-0.2-x86_64/README vtpm/README
---- orig/tpm_emulator-0.2-x86_64/README 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/README 2005-09-14 20:27:22.000000000 -0700
+--- orig/tpm_emulator-0.2-x86_64/README 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/README 2006-05-17 09:31:11.000000000 -0700
@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
Copyright
--------------------------------------------------------------------------
@@ -484,7 +483,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
it under the terms of the GNU General Public License as published by
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_audit.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_audit.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -549,7 +548,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_authorization.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_authorization.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -575,7 +574,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_capability.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_capability.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -600,7 +599,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_cmd_handler.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_cmd_handler.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -664,8 +663,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2005-09-15 19:21:14.846078416 -0700
-+++ vtpm/tpm/tpm_crypto.c 2005-09-14 20:27:22.000000000 -0700
+--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/tpm/tpm_crypto.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -689,8 +688,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-15 19:21:14.847078264 -0700
-+++ vtpm/tpm/tpm_data.c 2005-09-14 20:27:22.000000000 -0700
+--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2006-05-17 09:34:13.000000000 -0700
++++ vtpm/tpm/tpm_data.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -760,8 +759,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
+#ifdef VTPM_MUTLI_VM
+ #define DEV_FE "/dev/tpm"
+#else
-+ #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm-to-%d.fifo"
-+ #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo"
++ #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
++ #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
+
+ extern int dmi_id;
+ static char *vtpm_rx_name=NULL;
@@ -1021,7 +1020,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_deprecated.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_deprecated.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1050,7 +1049,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
len = *authContextSize;
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_emulator.h 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_emulator.h 2006-05-17 09:31:11.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1070,7 +1069,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
* tpm_emulator_init - initialises and starts the TPM emulator
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_integrity.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_integrity.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1086,7 +1085,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_structures.h 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_structures.h 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1106,7 +1105,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
/*
diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_testing.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_testing.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1224,7 +1223,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/

diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_ticks.c 2005-09-14 20:27:22.000000000 -0700
++++ vtpm/tpm/tpm_ticks.c 2006-05-17 09:31:11.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1307,139 +1306,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}


-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
---- orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h 1969-12-31 16:00:00.000000000 -0800
-+++ vtpm/tpm/vtpm_manager.h 2005-09-14 20:27:22.000000000 -0700
-@@ -0,0 +1,126 @@
-+// ===================================================================
-+//
-+// Copyright (c) 2005, Intel Corp.
-+// All rights reserved.
-+//
-+// Redistribution and use in source and binary forms, with or without
-+// modification, are permitted provided that the following conditions
-+// are met:
-+//
-+// * Redistributions of source code must retain the above copyright
-+// notice, this list of conditions and the following disclaimer.
-+// * Redistributions in binary form must reproduce the above
-+// copyright notice, this list of conditions and the following
-+// disclaimer in the documentation and/or other materials provided
-+// with the distribution.
-+// * Neither the name of Intel Corporation nor the names of its
-+// contributors may be used to endorse or promote products derived
-+// from this software without specific prior written permission.
-+//
-+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+// OF THE POSSIBILITY OF SUCH DAMAGE.
-+// ===================================================================
-+//
-+// vtpm_manager.h
-+//
-+// Public Interface header for VTPM Manager
-+//
-+// ==================================================================
-+
-+#ifndef __VTPM_MANAGER_H__
-+#define __VTPM_MANAGER_H__
-+
-+#define VTPM_TAG_REQ 0x01c1
-+#define VTPM_TAG_RSP 0x01c4
-+#define COMMAND_BUFFER_SIZE 4096
-+
-+// Header sizes. Note Header MAY include the DMI
-+#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-+#define VTPM_COMMAND_HEADER_SIZE_CLT ( sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-+
-+//************************ Command Codes ****************************
-+#define VTPM_ORD_OPEN 1 // ULM Creates New DMI
-+#define VTPM_ORD_CLOSE 2 // ULM Closes a DMI
-+#define VTPM_ORD_DELETE 3 // ULM Permemently Deletes DMI
-+#define VTPM_ORD_SAVENVM 4 // DMI requests Secrets Unseal
-+#define VTPM_ORD_LOADNVM 5 // DMI requests Secrets Saved
-+#define VTPM_ORD_TPMCOMMAND 6 // DMI issues HW TPM Command
-+
-+//************************ Return Codes ****************************
-+#define VTPM_SUCCESS 0
-+#define VTPM_FAIL 1
-+#define VTPM_UNSUPPORTED 2
-+#define VTPM_FORBIDDEN 3
-+#define VTPM_RESTORE_CONTEXT_FAILED 4
-+#define VTPM_INVALID_REQUEST 5
-+
-+/******************* Command Parameter API *************************
-+
-+VTPM Command Format
-+ dmi: 4 bytes // Source of message.
-+ // WARNING: This is prepended by the channel.
-+ // Thus it is received by VTPM Manager,
-+ // but not sent by DMI
-+ tpm tag: 2 bytes
-+ command size: 4 bytes // Size of command including header but not DMI
-+ ord: 4 bytes // Command ordinal above
-+ parameters: size - 10 bytes // Command Parameter
-+
-+VTPM Response Format
-+ tpm tag: 2 bytes
-+ response_size: 4 bytes
-+ status: 4 bytes
-+ parameters: size - 10 bytes
-+
-+
-+VTPM_Open:
-+ Input Parameters:
-+ Domain_type: 1 byte
-+ domain_id: 4 bytes
-+ instance_id: 4 bytes
-+ Output Parameters:
-+ None
-+
-+VTPM_Close
-+ Input Parameters:
-+ instance_id: 4 bytes
-+ Output Parameters:
-+ None
-+
-+VTPM_Delete
-+ Input Parameters:
-+ instance_id: 4 bytes
-+ Output Parameters:
-+ None
-+
-+VTPM_SaveNVM
-+ Input Parameters:
-+ data: n bytes (Header indicates size of data)
-+ Output Parameters:
-+ None
-+
-+VTPM_LoadNVM
-+ Input Parameters:
-+ None
-+ Output Parameters:
-+ data: n bytes (Header indicates size of data)
-+
-+VTPM_TPMCommand
-+ Input Parameters:
-+ TPM Command Byte Stream: n bytes
-+ Output Parameters:
-+ TPM Reponse Byte Stream: n bytes
-+
-+*********************************************************************/
-+
-+#endif //_VTPM_MANAGER_H_
diff -uprN orig/tpm_emulator-0.2-x86_64/tpmd.c vtpm/tpmd.c
--- orig/tpm_emulator-0.2-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800
-+++ vtpm/tpmd.c 2005-09-15 19:28:55.783005352 -0700
++++ vtpm/tpmd.c 2006-05-17 09:31:11.000000000 -0700
@@ -0,0 +1,207 @@
+/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2005 INTEL Corp
@@ -1471,8 +1340,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
+#ifdef VTPM_MULTI_VM
+ #define DEV_BE "/dev/vtpm"
+#else
-+ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
-+ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
++ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
++ #define GUEST_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
+#endif
+
+ int dmi_id;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/Rules.mk Mon May 22 14:13:38 2006 -0600
@@ -40,6 +40,9 @@ OBJS = $(patsubst %.c,%.o,$(SRCS))
# Project-specific definitions
#

+# Need UNIX98 spec for pthread rwlocks
+CFLAGS += -D_GNU_SOURCE
+
# Logging Level. See utils/tools.h for usage
CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))"

@@ -50,7 +53,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
# Use frontend/backend pairs between manager & DMs?
#CFLAGS += -DVTPM_MULTI_VM

-# vtpm_manager listens on /tmp/in.fifo and /tmp/out.fifo rather than backend
+# vtpm_manager listens on fifo's rather than backend
#CFLAGS += -DDUMMY_BACKEND

# Do not have manager launch DMs.
@@ -59,9 +62,6 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
# Fixed OwnerAuth
#CFLAGS += -DWELL_KNOWN_OWNER_AUTH

-# TPM Hardware Device or TPM Simulator
-#CFLAGS += -DTPM_HWDEV
-
# Include
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/dmictl.c Mon May 22 14:13:38 2006 -0600
@@ -55,66 +55,30 @@
#include "log.h"
#include "hashtable.h"
#include "hashtable_itr.h"
+#include "vtpm_ipc.h"

#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"

-TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
- TPM_RESULT status = TPM_FAIL;
-
+TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) {
if (dmi_res == NULL)
return TPM_SUCCESS;

- status = TCS_CloseContext(dmi_res->TCSContext);
+ TCS_CloseContext(dmi_res->TCSContext);
free ( dmi_res->NVMLocation );
dmi_res->connected = FALSE;

-#ifndef VTPM_MULTI_VM
- free(dmi_res->guest_tx_fname);
- free(dmi_res->vtpm_tx_fname);
-
- close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
- close(dmi_res->vtpm_tx_fh); dmi_res->vtpm_tx_fh = -1;
vtpm_globals->connected_dmis--;

- if (vtpm_globals->connected_dmis == 0) {
- // No more DMI's connected. Close fifo to prevent a broken pipe.
- close(vtpm_globals->guest_rx_fh);
- vtpm_globals->guest_rx_fh = -1;
- }
- #ifndef MANUAL_DM_LAUNCH
- if (dmi_res->dmi_id != VTPM_CTL_DM) {
- if (dmi_res->dmi_pid != 0) {
- vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
- if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
- vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid);
- } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) {
- vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid);
- status = TPM_FAIL;
- }
- } else {
- vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n");
- status = TPM_FAIL;
- }
- }
- #endif
-#endif
-
- return status;
-}
-
-TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
+ return (VTPM_Close_DMI_Extra(dmi_res) );
+}
+
+TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) {

VTPM_DMI_RESOURCE *new_dmi=NULL;
TPM_RESULT status=TPM_FAIL;
BYTE type;
UINT32 dmi_id, domain_id, *dmi_id_key;

-#ifndef VTPM_MULTI_VM
- int fh;
- char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
- struct stat file_info;
-#endif
-
if (param_buf == NULL) { // Assume creation of Dom 0 control
type = 0;
domain_id = VTPM_CTL_DM;
@@ -156,7 +120,7 @@ TPM_RESULT VTPM_Handle_New_DMI( const bu
status = TPM_FAIL;
goto egress;
}
-
+
} else
vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id);

@@ -176,94 +140,16 @@ TPM_RESULT VTPM_Handle_New_DMI( const bu
new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);

- // Measure DMI
- // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
- /*
- fh = open(TPM_EMULATOR_PATH, O_RDONLY);
- stat_ret = fstat(fh, &file_stat);
- if (stat_ret == 0)
- dmi_size = file_stat.st_size;
- else {
- vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
- status = TPM_IOERROR;
- goto abort_egress;
- }
- dmi_buffer
- */
- memset(&new_dmi->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
-
-#ifndef VTPM_MULTI_VM
- if (dmi_id != VTPM_CTL_DM) {
- // Create a pair of fifo pipes
- if( (new_dmi->guest_tx_fname = (char *) malloc(11 + strlen(GUEST_TX_FIFO))) == NULL){
- status = TPM_RESOURCES;
- goto abort_egress;
- }
- sprintf(new_dmi->guest_tx_fname, GUEST_TX_FIFO, (uint32_t) dmi_id);
-
- if ((new_dmi->vtpm_tx_fname = (char *) malloc(11 + strlen(VTPM_TX_FIFO))) == NULL) {
- status = TPM_RESOURCES;
- goto abort_egress;
- }
- sprintf(new_dmi->vtpm_tx_fname, VTPM_TX_FIFO, (uint32_t) dmi_id);
-
- new_dmi->guest_tx_fh = -1;
- new_dmi->vtpm_tx_fh= -1;
-
- if ( stat(new_dmi->guest_tx_fname, &file_info) == -1) {
- if ( mkfifo(new_dmi->guest_tx_fname, S_IWUSR | S_IRUSR ) ){
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n");
- status = TPM_IOERROR;
- goto abort_egress;
- }
- }
-
- if ( (fh = open(new_dmi->vtpm_tx_fname, O_RDWR)) == -1) {
- if ( mkfifo(new_dmi->vtpm_tx_fname, S_IWUSR | S_IRUSR ) ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n");
- status = TPM_IOERROR;
- goto abort_egress;
- }
- }
-
- // Launch DMI
- sprintf(dmi_id_str, "%d", (int) dmi_id);
-#ifdef MANUAL_DM_LAUNCH
- vtpmlogerror(VTPM_LOG_VTPM, "FAKING starting vtpm with dmi=%s\n", dmi_id_str);
- new_dmi->dmi_pid = 0;
-#else
- pid_t pid = fork();
-
- if (pid == -1) {
- vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
- status = TPM_RESOURCES;
- goto abort_egress;
- } else if (pid == 0) {
- if ( stat(new_dmi->NVMLocation, &file_info) == -1)
- execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
- else
- execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
-
- // Returning from these at all is an error.
- vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
- } else {
- new_dmi->dmi_pid = pid;
- vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
- }
-#endif // MANUAL_DM_LAUNCH
- }
-#else // VTPM_MUTLI_VM
- // FIXME: Measure DMI through call to Measurement agent in platform.
-#endif
-
- vtpm_globals->DMI_table_dirty = TRUE;
new_dmi->connected = TRUE;
- status=TPM_SUCCESS;
+
+ // Design specific new DMI code.
+ // Includes: create IPCs, Measuring DMI, and maybe launching DMI
+ status = VTPM_New_DMI_Extra(new_dmi);
goto egress;

abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status));
- close_dmi( new_dmi );
+ close_dmi(new_dmi );

egress:
return status;
@@ -293,7 +179,7 @@ TPM_RESULT VTPM_Handle_Close_DMI( const
goto abort_egress;
}

- if (!dmi_res->connected) {
+ if (!dmi_res->connected) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/securestorage.c Mon May 22 14:13:38 2006 -0600
@@ -197,9 +197,6 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
&vtpm_globals->storageKey,
&sealed_NVM) );

- // Mark DMI Table so new save state info will get pushed to disk on return.
- vtpm_globals->DMI_table_dirty = TRUE;
-
// Write sealed blob off disk from NVMLocation
// TODO: How to properly return from these. Do we care if we return failure
// after writing the file? We can't get the old one back.
@@ -303,7 +300,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
}


-TPM_RESULT VTPM_SaveService(void) {
+TPM_RESULT VTPM_SaveManagerData(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, dmis=-1;

@@ -317,7 +314,7 @@ TPM_RESULT VTPM_SaveService(void) {
struct hashtable_itr *dmi_itr;
VTPM_DMI_RESOURCE *dmi_res;

- UINT32 boot_key_size, flat_dmis_size;
+ UINT32 boot_key_size = 0, flat_dmis_size = 0;

// Initially fill these with buffer sizes for each data type. Later fill
// in actual size, once flattened.
@@ -347,11 +344,11 @@ TPM_RESULT VTPM_SaveService(void) {
BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);

// Per DMI values to be saved (if any exit)
- if (hashtable_count(vtpm_globals->dmi_map) > 0) {
-
- flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
- (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
- flat_dmis = (BYTE *) malloc( flat_dmis_size );
+ if (hashtable_count(vtpm_globals->dmi_map) > 1) {
+
+ flat_dmis = (BYTE *) malloc(
+ (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
+ (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info

dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
@@ -387,8 +384,6 @@ TPM_RESULT VTPM_SaveService(void) {
goto abort_egress;
}

- vtpm_globals->DMI_table_dirty = FALSE;
-
goto egress;

abort_egress:
@@ -400,11 +395,11 @@ TPM_RESULT VTPM_SaveService(void) {
free(flat_dmis);
close(fh);

- vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
- return status;
-}
-
-TPM_RESULT VTPM_LoadService(void) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Manager state (status = %d, dmis = %d)\n", (int) status, dmis);
+ return status;
+}
+
+TPM_RESULT VTPM_LoadManagerData(void) {

TPM_RESULT status=TPM_SUCCESS;
int fh, stat_ret, dmis=0;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Mon May 22 14:13:38 2006 -0600
@@ -39,17 +39,7 @@

#include <stdio.h>
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <string.h>
-
-#ifndef VTPM_MULTI_VM
-#include <pthread.h>
-#include <errno.h>
-#include <aio.h>
-#include <time.h>
-#endif

#include "vtpm_manager.h"
#include "vtpmpriv.h"
@@ -63,16 +53,6 @@

VTPM_GLOBALS *vtpm_globals=NULL;

-#ifdef VTPM_MULTI_VM
- #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, fmt, ##args );
- #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
- #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, fmt, ##args );
-#else
- #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%d]: " fmt, threadType, ##args );
- #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
- #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%d]: " fmt, threadType, ##args );
-#endif
-
// --------------------------- Well Known Auths --------------------------
const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -95,7 +75,7 @@ static int equals32(void *k1, void *k2)

// --------------------------- Functions ------------------------------

-TPM_RESULT VTPM_Create_Service(){
+TPM_RESULT VTPM_Create_Manager(){

TPM_RESULT status = TPM_SUCCESS;

@@ -184,562 +164,21 @@ TPM_RESULT VTPM_Create_Service(){
NULL,
&vtpm_globals->bootKey,
TRUE ) );
+
+ printf("***************************** FIXME: SAVE NEW STATE *******\n");
goto egress;

abort_egress:
exit(1);

egress:
- vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM service (Status = %d).\n", status);
+ vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager (Status = %d).\n", status);
return status;

}

-
-//////////////////////////////////////////////////////////////////////////////
-#ifdef VTPM_MULTI_VM
-int VTPM_Service_Handler(){
-#else
-void *VTPM_Service_Handler(void *threadTypePtr){
-#endif
- TPM_RESULT status = TPM_FAIL; // Should never return
- UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full;
- BYTE *cmd_header, *in_param, *out_message;
- buffer_t *command_buf=NULL, *result_buf=NULL;
- TPM_TAG tag;
- TPM_COMMAND_CODE ord;
- VTPM_DMI_RESOURCE *dmi_res;
- int size_read, size_write, i;
-
-#ifndef VTPM_MULTI_VM
- UINT32 dmi_cmd_size;
- BYTE *dmi_cmd;
- int threadType = *(int *) threadTypePtr;
-
- // async io structures
- struct aiocb dmi_aio;
- struct aiocb *dmi_aio_a[1];
- dmi_aio_a[0] = &dmi_aio;
-#endif
-
-#ifdef DUMMY_BACKEND
- int dummy_rx;
-#endif
-
- cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
- command_buf = (buffer_t *) malloc(sizeof(buffer_t));
- result_buf = (buffer_t *) malloc(sizeof(buffer_t));
-
-#ifndef VTPM_MULTI_VM
- TPM_RESULT *ret_value = (TPM_RESULT *) malloc(sizeof(TPM_RESULT));
-#endif
-
- int *tx_fh, // Pointer to the filehandle this function will write to
- *rx_fh; // Pointer to the filehandle this function will read from
- // For a multi VM VTPM system, this function tx/rx with the BE
- // via vtpm_globals->be_fh.
- // For a single VM system, the BE_LISTENER_THREAD tx/rx with theBE
- // via vtpm_globals->be_fh, and the DMI_LISTENER_THREAD rx from
- // vtpm_globals->vtpm_rx_fh and tx to dmi_res->vtpm_tx_fh
-
- // Set rx_fh to point to the correct fh based on this mode.
-#ifdef VTPM_MULTI_VM
- rx_fh = &vtpm_globals->be_fh;
-#else
- if (threadType == BE_LISTENER_THREAD) {
- #ifdef DUMMY_BACKEND
- dummy_rx = -1;
- rx_fh = &dummy_rx;
- #else
- rx_fh = &vtpm_globals->be_fh;
- #endif
- } else { // DMI_LISTENER_THREAD
- rx_fh = &vtpm_globals->vtpm_rx_fh;
- }
-#endif
-
- // Set tx_fh to point to the correct fh based on this mode (If static)
- // Create any fifos that these fh will use.
-#ifndef VTPM_MULTI_VM
- int fh;
- if (threadType == BE_LISTENER_THREAD) {
- tx_fh = &vtpm_globals->be_fh;
- if ( (fh = open(GUEST_RX_FIFO, O_RDWR)) == -1) {
- if ( mkfifo(GUEST_RX_FIFO, S_IWUSR | S_IRUSR ) ){
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", GUEST_RX_FIFO);
- *ret_value = TPM_FAIL;
- pthread_exit(ret_value);
- }
- } else
- close(fh);
-
- } else { // else DMI_LISTENER_THREAD
- // tx_fh will be set once the DMI is identified
- // But we need to make sure the read pip is created.
- if ( (fh = open(VTPM_RX_FIFO, O_RDWR)) == -1) {
- if ( mkfifo(VTPM_RX_FIFO, S_IWUSR | S_IRUSR ) ){
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", VTPM_RX_FIFO);
- *ret_value = TPM_FAIL;
- pthread_exit(ret_value);
- }
- } else
- close(fh);
-
- }
-#else
- tx_fh = &vtpm_globals->be_fh;
-#endif
-
- ////////////////////////// Main Loop //////////////////////////////////
- while(1) {
-
-#ifdef VTPM_MULTI_VM
- vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
-#else
- if (threadType == BE_LISTENER_THREAD) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for Guest requests & ctrl messages.\n");
- } else
- vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
-#endif
-
- // Check status of rx_fh. If necessary attempt to re-open it.
- char* s = NULL;
- if (*rx_fh < 0) {
-#ifdef VTPM_MULTI_VM
- s = VTPM_BE_DEV;
-#else
- if (threadType == BE_LISTENER_THREAD)
- #ifdef DUMMY_BACKEND
- s = "/tmp/in.fifo";
- #else
- s = VTPM_BE_DEV;
- #endif
- else // DMI Listener
- s = VTPM_RX_FIFO;
- *rx_fh = open(s, O_RDWR);
-#endif
- }
-
- // Respond to failures to open rx_fh
- if (*rx_fh < 0) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
-#ifdef VTPM_MULTI_VM
- return TPM_IOERROR;
-#else
- *ret_value = TPM_IOERROR;
- pthread_exit(ret_value);
-#endif
- }
-
- // Read command header from rx_fh
- size_read = read(*rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
- if (size_read > 0) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[.%d}: 0x", size_read);
- for (i=0; i<size_read; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't read from BE. Aborting... \n");
- close(*rx_fh);
- *rx_fh = -1;
- goto abort_command;
- }
-
- if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read);
- goto abort_command;
- }
-
- // Unpack header
- BSG_UnpackList(cmd_header, 4,
- BSG_TYPE_UINT32, &dmi,
- BSG_TPM_TAG, &tag,
- BSG_TYPE_UINT32, &in_param_size,
- BSG_TPM_COMMAND_CODE, &ord );
-
- // Using the header info, read from rx_fh the parameters of the command
- // Note that in_param_size is in the client's context
- cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
- if (cmd_size > 0) {
- in_param = (BYTE *) malloc(cmd_size);
- size_read = read( *rx_fh, in_param, cmd_size);
- if (size_read > 0) {
- for (i=0; i<size_read; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
-
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from cmd. Aborting... \n");
- close(*rx_fh);
- *rx_fh = -1;
- goto abort_command;
- }
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- if (size_read < (int) cmd_size) {
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
- goto abort_command;
- }
- } else {
- in_param = NULL;
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- }
-
-#ifndef VTPM_MULTI_VM
- // It's illegal to receive a Dom0 command from a DMI.
- if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from DMI interface. Aborting...\n");
- goto abort_command;
- }
-#endif
-
- // Fetch infomation about the DMI issuing the request.
- dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi);
- if (dmi_res == NULL) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent DMI in domain: %d. Aborting...\n", dmi);
- goto abort_command;
- }
- if (!dmi_res->connected) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to disconnected DMI in domain: %d. Aborting...\n", dmi);
- goto abort_command;
- }
-
-#ifndef VTPM_MULTI_VM
- // Now that we know which DMI this is, we can set the tx_fh handle.
- if (threadType != BE_LISTENER_THREAD)
- tx_fh = &dmi_res->vtpm_tx_fh;
- // else we set this before the while loop since it doesn't change.
-#endif
-
- // Init the buffers used to handle the command and the response
- if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) ||
- (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
- goto abort_command;
- }
-
- // Dispatch it as either control or user request.
- if (tag == VTPM_TAG_REQ) {
- if (dmi_res->dmi_id == VTPM_CTL_DM){
- switch (ord) {
- case VTPM_ORD_OPEN:
- status = VTPM_Handle_New_DMI(command_buf);
- break;
-
- case VTPM_ORD_CLOSE:
- status = VTPM_Handle_Close_DMI(command_buf);
- break;
-
- case VTPM_ORD_DELETE:
- status = VTPM_Handle_Delete_DMI(command_buf);
- break;
- default:
- status = TPM_BAD_ORDINAL;
- } // switch
- } else {
-
- switch (ord) {
- case VTPM_ORD_SAVENVM:
- status= VTPM_Handle_Save_NVM(dmi_res,
- command_buf,
- result_buf);
- break;
- case VTPM_ORD_LOADNVM:
- status= VTPM_Handle_Load_NVM(dmi_res,
- command_buf,
- result_buf);
- break;
-
- case VTPM_ORD_TPMCOMMAND:
- status= VTPM_Handle_TPM_Command(dmi_res,
- command_buf,
- result_buf);
- break;
-
- default:
- status = TPM_BAD_ORDINAL;
- } // switch
- }
- } else { // This is not a VTPM Command at all.
- // This happens in two cases.
- // MULTI_VM = A DMI illegally sent a raw TPM command to the manager
- // Single VM:
- // BE_LISTENER_THREAD: Guest issued a TPM command.
- // Send this to DMI and wait for response
- // DMI_LISTENER_THREAD: A DMI illegally sent a raw TPM command.
-
-#ifdef VTPM_MULTI_VM
- // Raw TPM commands are not supported from the DMI
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
- for (i=0; i<cmd_size; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
-
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- status = TPM_FAIL;
-
-#else
- // If BE_LISTENER_THREAD then this is a TPM command from a guest
- if (threadType == BE_LISTENER_THREAD) {
- // Dom0 can't talk to the BE, so this must be a broken FE/BE or badness
- if (dmi == 0) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n");
- status = TPM_FAIL;
- } else {
- vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
-
- // open the dmi_res->guest_tx_fh to send command to DMI
- if (dmi_res->guest_tx_fh < 0)
- dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY | O_NONBLOCK);
-
- // handle failed opens dmi_res->guest_tx_fh
- if (dmi_res->guest_tx_fh < 0){
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh to dmi.\n");
- status = TPM_IOERROR;
- goto abort_with_error;
- }
-
- //Forward TPM CMD stamped with dmi_id to DMI for handling
- if (cmd_size) {
- dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size);
- dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size;
- memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
- memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, in_param, cmd_size);
- size_write = write(dmi_res->guest_tx_fh, dmi_cmd, dmi_cmd_size);
-
- if (size_write > 0) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
- for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; i++) {
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
- }
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
- close(dmi_res->guest_tx_fh);
- dmi_res->guest_tx_fh = -1;
- status = TPM_IOERROR;
- goto abort_with_error;
- }
- free(dmi_cmd);
- } else {
- dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
- size_write = write(dmi_res->guest_tx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
- if (size_write > 0) {
- for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
-
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
- close(dmi_res->guest_tx_fh);
- dmi_res->guest_tx_fh = -1;
- status = TPM_IOERROR;
- goto abort_with_error;
- }
- }
-
- if (size_write != (int) dmi_cmd_size)
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size);
- buffer_free(command_buf);
-
- // Open vtpm_globals->guest_rx_fh to receive DMI response
- if (vtpm_globals->guest_rx_fh < 0)
- vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY);
-
- // Handle open failures
- if (vtpm_globals->guest_rx_fh < 0){
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh to dmi.\n");
- status = TPM_IOERROR;
- goto abort_with_error;
- }
-
- // Read header for response to TPM command from DMI
- size_read = read( vtpm_globals->guest_rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
- if (size_read > 0) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
- for (i=0; i<size_read; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
-
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n");
- close(vtpm_globals->guest_rx_fh);
- vtpm_globals->guest_rx_fh = -1;
- status = TPM_IOERROR;
- goto abort_with_error;
- }
-
- if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
- //vtpmdeepsublog("\n");
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n");
- status = TPM_IOERROR;
- goto abort_with_error;
- }
-
- // Unpack response from DMI for TPM command
- BSG_UnpackList(cmd_header, 4,
- BSG_TYPE_UINT32, &dmi,
- BSG_TPM_TAG, &tag,
- BSG_TYPE_UINT32, &in_param_size,
- BSG_TPM_COMMAND_CODE, &status );
-
- // If response has parameters, read them.
- // Note that in_param_size is in the client's context
- cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
- if (cmd_size > 0) {
- in_param = (BYTE *) malloc(cmd_size);
- size_read = read( vtpm_globals->guest_rx_fh, in_param, cmd_size);
- if (size_read > 0) {
- for (i=0; i<size_read; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
-
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
- close(vtpm_globals->guest_rx_fh);
- vtpm_globals->guest_rx_fh = -1;
- status = TPM_IOERROR;
- goto abort_with_error;
- }
- vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
-
- if (size_read < (int)cmd_size) {
- vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
- status = TPM_IOERROR;
- goto abort_with_error;
- }
- } else {
- in_param = NULL;
- vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
- }
-
- if (buffer_init_convert(result_buf, cmd_size, in_param) != TPM_SUCCESS) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
- status = TPM_FAIL;
- goto abort_with_error;
- }
-
- vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n");
- } // end else for if (dmi==0)
-
- } else { // This is a DMI lister thread. Thus this is from a DMI
- // Raw TPM commands are not supported from the DMI
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
- for (i=0; i<cmd_size; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
-
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- status = TPM_FAIL;
- } // end else for if BE Listener
-#endif
-
- } // end else for is VTPM Command
-
- // This marks the beginning of preparing response to be sent out.
- // Errors while handling responses jump here to reply with error messages
- // NOTE: Currently there are no recoverable errors in multi-VM mode. If one
- // is added to the code, this ifdef should be removed.
- // Also note this is NOT referring to errors in commands, but rather
- // this is about I/O errors and such.
-#ifndef VTPM_MULTI_VM
- abort_with_error:
-#endif
-
- // Open tx_fh in preperation to send reponse back
- if (*tx_fh < 0) {
-#ifdef VTPM_MULTI_VM
- *tx_fh = open(VTPM_BE_DEV, O_RDWR);
-#else
- if (threadType == BE_LISTENER_THREAD)
- #ifdef DUMMY_BACKEND
- *tx_fh = open("/tmp/out.fifo", O_RDWR);
- #else
- *tx_fh = open(VTPM_BE_DEV, O_RDWR);
- #endif
- else // DMI Listener
- *tx_fh = open(dmi_res->vtpm_tx_fname, O_WRONLY);
-#endif
- }
-
-
- // Handle failed open
- if (*tx_fh < 0) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh.\n");
-#ifdef VTPM_MULTI_VM
- return TPM_IOERROR;
-#else
- *ret_value = TPM_IOERROR;
- pthread_exit(ret_value);
-#endif
- }
-
- // Prepend VTPM header with destination DM stamped
- out_param_size = buffer_len(result_buf);
- out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
- out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
- out_message = (BYTE *) malloc (out_message_size_full);
-
- BSG_PackList(out_message, 4,
- BSG_TYPE_UINT32, (BYTE *) &dmi,
- BSG_TPM_TAG, (BYTE *) &tag,
- BSG_TYPE_UINT32, (BYTE *) &out_message_size,
- BSG_TPM_RESULT, (BYTE *) &status);
-
- if (buffer_len(result_buf) > 0)
- memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
-
-
- //Note: Send message + dmi_id
- size_write = write(*tx_fh, out_message, out_message_size_full );
- if (size_write > 0) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
- for (i=0; i < out_message_size_full; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
-
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- } else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to BE. Aborting... \n");
- close(*tx_fh);
- *tx_fh = -1;
- goto abort_command;
- }
- free(out_message);
-
- if (size_write < (int)out_message_size_full) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Unable to write full command to BE (%d/%d)\n", size_write, out_message_size_full);
- goto abort_command;
- }
-
- // On certain failures an error message cannot be sent.
- // This marks the beginning of cleanup in preperation for the next command.
- abort_command:
- //free buffers
- bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
- //free(in_param); // This was converted to command_buf. No need to free
- if (command_buf != result_buf)
- buffer_free(result_buf);
-
- buffer_free(command_buf);
-
-#ifndef VTPM_MULTI_VM
- if (threadType != BE_LISTENER_THREAD) {
-#endif
- if ( (vtpm_globals->DMI_table_dirty) &&
- (VTPM_SaveService() != TPM_SUCCESS) ) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n");
- }
-#ifndef VTPM_MULTI_VM
- }
-#endif
-
- } // End while(1)
-
-}
-
-
///////////////////////////////////////////////////////////////////////////////
-TPM_RESULT VTPM_Init_Service() {
+TPM_RESULT VTPM_Init_Manager() {
TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize;
@@ -749,19 +188,13 @@ TPM_RESULT VTPM_Init_Service() {
goto abort_egress;
}
memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS));
- vtpm_globals->be_fh = -1;
-
-#ifndef VTPM_MULTI_VM
- vtpm_globals->vtpm_rx_fh = -1;
- vtpm_globals->guest_rx_fh = -1;
+
vtpm_globals->connected_dmis = 0;
-#endif
+
if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){
status = TPM_FAIL;
goto abort_egress;
}
-
- vtpm_globals->DMI_table_dirty = FALSE;

// Create new TCS Object
vtpm_globals->manager_tcs_handle = 0;
@@ -783,13 +216,14 @@ TPM_RESULT VTPM_Init_Service() {
&vtpm_globals->keyAuth) );
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;

- // If failed, create new Service.
- serviceStatus = VTPM_LoadService();
+ // If failed, create new Manager.
+ serviceStatus = VTPM_LoadManagerData();
if (serviceStatus == TPM_IOERROR) {
- vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n");
- TPMTRYRETURN( VTPM_Create_Service() );
+ vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
+ TPMTRYRETURN( VTPM_Create_Manager() );
+ TPMTRYRETURN( VTPM_SaveManagerData() );
} else if (serviceStatus != TPM_SUCCESS) {
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file");
exit(1);
}

@@ -805,8 +239,6 @@ TPM_RESULT VTPM_Init_Service() {

// Create entry for Dom0 for control messages
TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
-
- // --------------------- Command handlers ---------------------------

goto egress;

@@ -815,8 +247,9 @@ TPM_RESULT VTPM_Init_Service() {

return(status);
}
-
-void VTPM_Stop_Service() {
+
+///////////////////////////////////////////////////////////////////////////////
+void VTPM_Stop_Manager() {
VTPM_DMI_RESOURCE *dmi_res;
struct hashtable_itr *dmi_itr;

@@ -832,7 +265,7 @@ void VTPM_Stop_Service() {
free (dmi_itr);
}

- if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
+ if ( VTPM_SaveManagerData() != TPM_SUCCESS )
vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");

TCS_CloseContext(vtpm_globals->manager_tcs_handle);
@@ -841,7 +274,6 @@ void VTPM_Stop_Service() {
hashtable_destroy(vtpm_globals->dmi_map, 1);
free(vtpm_globals);

- close(vtpm_globals->be_fh);
Crypto_Exit();

vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Mon May 22 14:13:38 2006 -0600
@@ -40,32 +40,30 @@
#ifndef __VTPM_MANAGER_H__
#define __VTPM_MANAGER_H__

-#include "tcg.h"
-
#define VTPM_TAG_REQ 0x01c1
#define VTPM_TAG_RSP 0x01c4
#define COMMAND_BUFFER_SIZE 4096

// Header sizes. Note Header MAY include the DMI
-#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-#define VTPM_COMMAND_HEADER_SIZE_CLT ( sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-
-// ********************** Public Functions *************************
-TPM_RESULT VTPM_Init_Service(); // Start VTPM Service
-void VTPM_Stop_Service(); // Stop VTPM Service
-#ifdef VTPM_MULTI_VM
-int VTPM_Service_Handler();
-#else
-void *VTPM_Service_Handler(void *threadTypePtr);
-#endif
+#define VTPM_COMMAND_HEADER_SIZE_CLT ( 2 + 4 + 4)
+// sizeof(TPM_TAG + UINT32 + TPM_COMMAND_CODE)
+#define VTPM_COMMAND_HEADER_SIZE_SRV ( 4 + VTPM_COMMAND_HEADER_SIZE_CLT )
+// sizeof( UINT32 + VTPM_COMMAND_HEADER_SIZE_CLT)

//************************ Command Codes ****************************
-#define VTPM_ORD_OPEN 1 // ULM Creates New DMI
-#define VTPM_ORD_CLOSE 2 // ULM Closes a DMI
-#define VTPM_ORD_DELETE 3 // ULM Permemently Deletes DMI
-#define VTPM_ORD_SAVENVM 4 // DMI requests Secrets Unseal
-#define VTPM_ORD_LOADNVM 5 // DMI requests Secrets Saved
-#define VTPM_ORD_TPMCOMMAND 6 // DMI issues HW TPM Command
+#define VTPM_ORD_BASE 0x0000
+#define VTPM_PRIV_MASK 0x01000000 // Priviledged VTPM Command
+#define VTPM_PRIV_BASE (VTPM_ORD_BASE | VTPM_PRIV_MASK)
+
+// Non-priviledged VTPM Commands (From DMI's)
+#define VTPM_ORD_SAVENVM (VTPM_ORD_BASE + 1) // DMI Saves Secrets
+#define VTPM_ORD_LOADNVM (VTPM_ORD_BASE + 2) // DMI Loads Secrets
+#define VTPM_ORD_TPMCOMMAND (VTPM_ORD_BASE + 3) // DMI issues HW TPM Command
+
+// Priviledged VTPM Commands (From management console)
+#define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
+#define VTPM_ORD_CLOSE (VTPM_PRIV_BASE + 2) // Closes a DMI
+#define VTPM_ORD_DELETE (VTPM_PRIV_BASE + 3) // Permemently Deletes DMI

//************************ Return Codes ****************************
#define VTPM_SUCCESS 0
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmd.c Mon May 22 14:13:38 2006 -0600
@@ -38,21 +38,67 @@
// ===================================================================

#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <signal.h>
-#include <sys/types.h>
-#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "tcg.h"
#include "log.h"
-
-#ifndef VTPM_MULTI_VM
- #include <pthread.h>
-#endif
+#include "vtpm_ipc.h"
+
+
+#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+
+#define VTPM_BE_FNAME "/dev/vtpm"
+#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo"
+#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo"
+#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
+#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
+#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
+#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
+#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo"
+#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo"
+
+
+#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
+#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
+
+#define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo"
+#define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo"
+
+
+struct vtpm_thread_params_s {
+ vtpm_ipc_handle_t *tx_ipc_h;
+ vtpm_ipc_handle_t *rx_ipc_h;
+ BOOL fw_tpm;
+ vtpm_ipc_handle_t *fw_tx_ipc_h;
+ vtpm_ipc_handle_t *fw_rx_ipc_h;
+ BOOL is_priv;
+ char *thread_name;
+};
+
+// This is needed to all extra_close_dmi to close this to prevent a
+// broken pipe when no DMIs are left.
+static vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+
+void *vtpm_manager_thread(void *arg_void) {
+ TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) );
+ struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *) arg_void;
+
+ *status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h,
+ arg->fw_tpm, arg->fw_tx_ipc_h, arg->fw_rx_ipc_h,
+ arg->is_priv, arg->thread_name);
+
+ return (status);
+}
+

void signal_handler(int reason) {
-#ifndef VTPM_MULTI_VM
-
if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %d.\n", reason);
} else {
@@ -60,71 +106,258 @@ void signal_handler(int reason) {
vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
pthread_exit(NULL);
}
+
+ VTPM_Stop_Manager();
+ exit(-1);
+}
+
+struct sigaction ctl_c_handler;
+
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+ int fh;
+ char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
+ char *tx_vtpm_name, *tx_tpm_name;
+ struct stat file_info;
+
+ if (dmi_res->dmi_id == VTPM_CTL_DM) {
+ dmi_res->tx_tpm_ipc_h = NULL;
+ dmi_res->rx_tpm_ipc_h = NULL;
+ dmi_res->tx_vtpm_ipc_h = NULL;
+ dmi_res->rx_vtpm_ipc_h = NULL;
+ } else {
+ // Create a pair of fifo pipes
+ dmi_res->rx_tpm_ipc_h = NULL;
+ dmi_res->rx_vtpm_ipc_h = NULL;
+
+ if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) ||
+ ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) ||
+ ((tx_tpm_name = (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) == NULL ) ||
+ ((tx_vtpm_name =(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) {
+ status =TPM_RESOURCES;
+ goto abort_egress;
+ }
+
+ sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id);
+ sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id);
+
+ if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE) != 0) ||
+ (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) != 0) ) { //FIXME: O_NONBLOCK?
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+
+ // Measure DMI
+ // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
+ // Also, this mechanism is specific to 1 VM.
+ /*
+ fh = open(TPM_EMULATOR_PATH, O_RDONLY);
+ stat_ret = fstat(fh, &file_stat);
+ if (stat_ret == 0)
+ dmi_size = file_stat.st_size;
+ else {
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+ dmi_buffer
+ */
+ memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
+
+
+ // Launch DMI
+ sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id);
+#ifdef MANUAL_DM_LAUNCH
+ vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s now.\n", dmi_id_str);
+ dmi_res->dmi_pid = 0;
+#else
+ pid_t pid = fork();
+
+ if (pid == -1) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
+ status = TPM_RESOURCES;
+ goto abort_egress;
+ } else if (pid == 0) {
+ if ( stat(dmi_res->NVMLocation, &file_info) == -1)
+ execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
+ else
+ execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
+
+ // Returning from these at all is an error.
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
+ } else {
+ dmi_res->dmi_pid = pid;
+ vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
+ }
+#endif // MANUAL_DM_LAUNCH
+
+ } // If DMI = VTPM_CTL_DM
+ status = TPM_SUCCESS;
+
+abort_egress:
+ return (status);
+}
+
+TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+ TPM_RESULT status = TPM_SUCCESS;
+
+ if (vtpm_globals->connected_dmis == 0) {
+ // No more DMI's connected. Close fifo to prevent a broken pipe.
+ // This is hackish. Need to think of another way.
+ vtpm_ipc_close(g_rx_tpm_ipc_h);
+ }
+
+
+ if (dmi_res->dmi_id != VTPM_CTL_DM) {
+ vtpm_ipc_close(dmi_res->tx_tpm_ipc_h);
+ vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h);
+
+ free(dmi_res->tx_tpm_ipc_h->name);
+ free(dmi_res->tx_vtpm_ipc_h->name);
+
+#ifndef MANUAL_DM_LAUNCH
+ if (dmi_res->dmi_id != VTPM_CTL_DM) {
+ if (dmi_res->dmi_pid != 0) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
+ if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
+ vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid);
+ } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) {
+ vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid);
+ status = TPM_FAIL;
+ }
+ } else {
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n");
+ status = TPM_FAIL;
+ }
+ }
#endif
- VTPM_Stop_Service();
- exit(-1);
-}
-
-struct sigaction ctl_c_handler;
+
+ } //endif ! dom0
+ return status;
+}
+

int main(int argc, char **argv) {
+ vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h, rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h;
+ struct vtpm_thread_params_s be_thread_params, dmi_thread_params, hp_thread_params;
+ pthread_t be_thread, dmi_thread, hp_thread;
+
+#ifdef DUMMY_BACKEND
+ vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h;
+#else
+ vtpm_ipc_handle_t real_be_ipc_h;
+#endif

vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
-
- if (VTPM_Init_Service() != TPM_SUCCESS) {
+
+ // -------------------- Initialize Manager -----------------
+ if (VTPM_Init_Manager() != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n");
return -1;
}

+ // -------------------- Setup Ctrl+C Handlers --------------
ctl_c_handler.sa_handler = signal_handler;
sigemptyset(&ctl_c_handler.sa_mask);
ctl_c_handler.sa_flags = 0;

if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1)
- vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop service gently.\n");
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n");

// For easier debuggin with gdb
if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1)
- vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop service gently.\n");
-
-#ifdef VTPM_MULTI_VM
- TPM_RESULT status = VTPM_Service_Handler();
-
- if (status != TPM_SUCCESS)
- vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager exited with status %s. It never should exit.\n", tpm_get_error_name(status));
-
- return -1;
-#else
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n");
+
sigset_t sig_mask;
-
sigemptyset(&sig_mask);
sigaddset(&sig_mask, SIGPIPE);
sigprocmask(SIG_BLOCK, &sig_mask, NULL);
- //pthread_mutex_init(&vtpm_globals->dmi_mutex, NULL);
- pthread_t be_thread, dmi_thread;
- int betype_be, dmitype_dmi;
-
+
+ // ------------------- Set up file ipc structures ----------
+#ifdef DUMMY_BACKEND
+ if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) != 0) ||
+ (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) != 0) ) {
+
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n");
+ exit(-1);
+ }
+
+ tx_be_ipc_h = &tx_dummy_ipc_h;
+ rx_be_ipc_h = &rx_dummy_ipc_h;
+#else
+ vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE);
+
+ tx_be_ipc_h = &real_be_ipc_h;
+ rx_be_ipc_h = &real_be_ipc_h;
+#endif
+
+ if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) != 0) ||
+ (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) != 0) || //FIXME: O_RDONLY?
+ (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) ||
+ (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n");
+ exit(-1);
+ }
+
+ g_rx_tpm_ipc_h = &rx_tpm_ipc_h;
+
+ // -------------------- Set up thread params -------------
+
+ be_thread_params.tx_ipc_h = tx_be_ipc_h;
+ be_thread_params.rx_ipc_h = rx_be_ipc_h;
+ be_thread_params.fw_tpm = TRUE;
+ be_thread_params.fw_tx_ipc_h = NULL;
+ be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
+ be_thread_params.is_priv = TRUE; //FIXME: Change when HP is up
+ be_thread_params.thread_name = "Backend Listener";
+
+ dmi_thread_params.tx_ipc_h = NULL;
+ dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h;
+ dmi_thread_params.fw_tpm = FALSE;
+ dmi_thread_params.fw_tx_ipc_h = NULL;
+ dmi_thread_params.fw_rx_ipc_h = NULL;
+ dmi_thread_params.is_priv = FALSE;
+ dmi_thread_params.thread_name = "VTPM Listeners";
+
+ hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
+ hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
+ hp_thread_params.fw_tpm = FALSE;
+ hp_thread_params.fw_tx_ipc_h = NULL;
+ hp_thread_params.fw_rx_ipc_h = NULL;
+ hp_thread_params.is_priv = TRUE;
+ hp_thread_params.thread_name = "Hotplug Listener";
+
+ // --------------------- Launch Threads -----------------
+
+ vtpm_lock_init();
+
vtpm_globals->master_pid = pthread_self();

- betype_be = BE_LISTENER_THREAD;
- if (pthread_create(&be_thread, NULL, VTPM_Service_Handler, &betype_be) != 0) {
+ if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
exit(-1);
}

- dmitype_dmi = DMI_LISTENER_THREAD;
- if (pthread_create(&dmi_thread, NULL, VTPM_Service_Handler, &dmitype_dmi) != 0) {
+ if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
exit(-1);
}
-
+
+
+// if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) {
+// vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
+// exit(-1);
+// }
+
//Join the other threads until exit time.
pthread_join(be_thread, NULL);
pthread_join(dmi_thread, NULL);
-#endif
+ pthread_join(hp_thread, NULL);

vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n");

- VTPM_Stop_Service();
+ VTPM_Stop_Manager();
+ vtpm_lock_destroy();
return 0;
}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmpriv.h Mon May 22 14:13:38 2006 -0600
@@ -44,42 +44,24 @@
#include "tcs.h"
#include "buffer.h"
#include "crypto.h"
+#include "vtpm_ipc.h"

#define STATE_FILE "/var/vtpm/VTPM"
#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data"
-#define VTPM_BE_DEV "/dev/vtpm"
#define VTPM_CTL_DM 0
-
-#ifndef VTPM_MUTLI_VM
- #include <sys/types.h>
- #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
- #define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
-
- #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo"
- #define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo"
-
- #define BE_LISTENER_THREAD 1
- #define DMI_LISTENER_THREAD 2
-
- // Seconds until DMI timeout. Timeouts result in DMI being out
- // of sync, which may require a reboot of DMI and guest to recover
- // from. Don't set this to low. Also note that DMI may issue a TPM
- // call so we should expect time to process at DMI + TPM processing.
- #define DMI_TIMEOUT 90
-#endif
-

// ------------------------ Private Structures -----------------------
typedef struct VTPM_DMI_RESOURCE_T {
- // I/O info for Manager to talk to DMI's over FIFOs
-#ifndef VTPM_MUTLI_VM
- int guest_tx_fh; // open GUEST_TX_FIFO
- int vtpm_tx_fh; // open VTPM_TX_FIFO
- char *guest_tx_fname; // open GUEST_TX_FIFO
- char *vtpm_tx_fname; // open VTPM_TX_FIFO
-
+ // I/O info for Manager to talk to DMI's and controllers
+ vtpm_ipc_handle_t *tx_vtpm_ipc_h; // TX VTPM Results to DMI
+ vtpm_ipc_handle_t *rx_vtpm_ipc_h; // RX VTPM Commands from DMI
+ vtpm_ipc_handle_t *tx_tpm_ipc_h; // TX TPM Commands to DMI
+ vtpm_ipc_handle_t *rx_tpm_ipc_h; // RX TPM Results from DMI
+
+#ifndef VTPM_MULTI_VM
pid_t dmi_pid;
#endif
+
// Non-persistent Information
bool connected;
UINT32 dmi_domain_id;
@@ -94,26 +76,19 @@ typedef struct VTPM_DMI_RESOURCE_T {

typedef struct tdVTPM_GLOBALS {
// Non-persistent data
- int be_fh; // File handle to ipc used to communicate with backend
#ifndef VTPM_MULTI_VM
- int vtpm_rx_fh;
- int guest_rx_fh;
- int connected_dmis; // Used to close guest_rx when no dmis are connected
-
pid_t master_pid;
#endif
+
+ int connected_dmis; // To close guest_rx when no dmis are connected
+
struct hashtable *dmi_map; // Table of all DMI's known indexed by persistent instance #
-#ifndef VTPM_MULTI_VM
- pthread_mutex_t dmi_map_mutex; //
-#endif
+
TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager
TPM_HANDLE storageKeyHandle; // Key used by persistent store
CRYPTO_INFO storageKey; // For software encryption
CRYPTO_INFO bootKey; // For saving table
TCS_AUTH keyAuth; // OIAP session for storageKey
- BOOL DMI_table_dirty; // Indicates that a command
- // has updated the DMI table
-

// Persistent Data
TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM
@@ -130,6 +105,18 @@ extern const TPM_AUTHDATA SRK_AUTH; //
extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value

// ********************** Command Handler Prototypes ***********************
+
+// ********************** VTPM Functions *************************
+TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service
+void VTPM_Stop_Manager(); // Stop VTPM Service
+TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_ipc_h,
+ vtpm_ipc_handle_t *rx_ipc_h,
+ BOOL fw_tpm, // Should forward TPM cmds
+ vtpm_ipc_handle_t *fw_tx_ipc_h,
+ vtpm_ipc_handle_t *fw_rx_ipc_h,
+ BOOL is_priv,
+ char *client_name);
+
TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf);
@@ -148,8 +135,12 @@ TPM_RESULT VTPM_Handle_Close_DMI(const b

TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);

-TPM_RESULT VTPM_SaveService(void);
-TPM_RESULT VTPM_LoadService(void);
+TPM_RESULT VTPM_SaveManagerData(void);
+TPM_RESULT VTPM_LoadManagerData(void);

-TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res);
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
+
+TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
+
+TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
#endif // __VTPMPRIV_H__
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenmon/xenbaked.c
--- a/tools/xenmon/xenbaked.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenmon/xenbaked.c Mon May 22 14:13:38 2006 -0600
@@ -35,6 +35,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@@ -46,7 +47,14 @@
#include <sys/select.h>
#include <xen/linux/evtchn.h>

-#include "xc_private.h"
+#define PERROR(_m, _a...) \
+do { \
+ int __saved_errno = errno; \
+ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
+ __saved_errno, strerror(__saved_errno)); \
+ errno = __saved_errno; \
+} while (0)
+
typedef struct { int counter; } atomic_t;
#define _atomic_read(v) ((v).counter)

@@ -326,77 +334,32 @@ void wait_for_event(void)
}
}

-void enable_tracing_or_die(int xc_handle)
-{
- int enable = 1;
- int tbsize = DEFAULT_TBUF_SIZE;
-
- if (xc_tbuf_enable(xc_handle, enable) != 0) {
- if (xc_tbuf_set_size(xc_handle, tbsize) != 0) {
- perror("set_size Hypercall failure");
- exit(1);
- }
- printf("Set default trace buffer allocation (%d pages)\n", tbsize);
- if (xc_tbuf_enable(xc_handle, enable) != 0) {
- perror("Could not enable trace buffers\n");
- exit(1);
- }
- }
- else
- printf("Tracing enabled\n");
-}
-
-void disable_tracing(void)
-{
- int enable = 0;
- int xc_handle = xc_interface_open();
-
- xc_tbuf_enable(xc_handle, enable);
- xc_interface_close(xc_handle);
-}
-
-
-/**
- * get_tbufs - get pointer to and size of the trace buffers
- * @mfn: location to store mfn of the trace buffers to
- * @size: location to store the size of a trace buffer to
- *
- * Gets the machine address of the trace pointer area and the size of the
- * per CPU buffers.
- */
-void get_tbufs(unsigned long *mfn, unsigned long *size)
-{
+static void get_tbufs(unsigned long *mfn, unsigned long *size)
+{
+ int xc_handle = xc_interface_open();
int ret;
- dom0_op_t op; /* dom0 op we'll build */
- int xc_handle = xc_interface_open(); /* for accessing control interface */
- unsigned int tbsize;
-
- enable_tracing_or_die(xc_handle);
-
- if (xc_tbuf_get_size(xc_handle, &tbsize) != 0) {
- perror("Failure to get tbuf info from Xen. Guess size is 0?");
- exit(1);
- }
- else
- printf("Current tbuf size: 0x%x\n", tbsize);
-
-
- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO;
-
- ret = do_dom0_op(xc_handle, &op);
-
- xc_interface_close(xc_handle);
+
+ if ( xc_handle < 0 )
+ {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = xc_tbuf_enable(xc_handle, DEFAULT_TBUF_SIZE, mfn, size);

if ( ret != 0 )
{
- PERROR("Failure to get trace buffer pointer from Xen");
- exit(EXIT_FAILURE);
- }
-
- *mfn = op.u.tbufcontrol.buffer_mfn;
- *size = op.u.tbufcontrol.size;
+ perror("Couldn't enable trace buffers");
+ exit(1);
+ }
+
+ xc_interface_close(xc_handle);
+}
+
+void disable_tracing(void)
+{
+ int xc_handle = xc_interface_open();
+ xc_tbuf_disable(xc_handle);
+ xc_interface_close(xc_handle);
}

/**
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenstore/xenstored_core.c Mon May 22 14:13:38 2006 -0600
@@ -461,7 +461,7 @@ static bool write_node(struct connection
+ node->num_perms*sizeof(node->perms[0])
+ node->datalen + node->childlen;

- if (data.dsize >= quota_max_entry_size)
+ if (domain_is_unprivileged(conn) && data.dsize >= quota_max_entry_size)
goto error;

data.dptr = talloc_size(node, data.dsize);
@@ -1811,6 +1811,21 @@ int main(int argc, char *argv[])

reopen_log();

+ /* make sure xenstored directory exists */
+ if (mkdir(xs_daemon_rundir(), 0755)) {
+ if (errno != EEXIST) {
+ perror("error: mkdir daemon rundir");
+ exit(-1);
+ }
+ }
+
+ if (mkdir(xs_daemon_rootdir(), 0755)) {
+ if (errno != EEXIST) {
+ perror("error: mkdir daemon rootdir");
+ exit(-1);
+ }
+ }
+
if (dofork) {
openlog("xenstored", 0, LOG_DAEMON);
daemonize();
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenstore/xenstored_domain.c Mon May 22 14:13:38 2006 -0600
@@ -248,6 +248,11 @@ bool domain_can_read(struct connection *
{
struct xenstore_domain_interface *intf = conn->domain->interface;
return (intf->req_cons != intf->req_prod);
+}
+
+bool domain_is_unprivileged(struct connection *conn)
+{
+ return (conn && conn->domain && conn->domain->domid != 0);
}

bool domain_can_write(struct connection *conn)
@@ -587,7 +592,7 @@ void domain_entry_dec(struct connection

int domain_entry(struct connection *conn)
{
- return (conn && conn->domain && conn->domain->domid)
+ return (domain_is_unprivileged(conn))
? conn->domain->nbentry
: 0;
}
@@ -609,7 +614,7 @@ void domain_watch_dec(struct connection

int domain_watch(struct connection *conn)
{
- return (conn && conn->domain && conn->domain->domid)
+ return (domain_is_unprivileged(conn))
? conn->domain->nbwatch
: 0;
}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenstore/xenstored_domain.h Mon May 22 14:13:38 2006 -0600
@@ -47,6 +47,8 @@ bool domain_can_read(struct connection *
bool domain_can_read(struct connection *conn);
bool domain_can_write(struct connection *conn);

+bool domain_is_unprivileged(struct connection *conn);
+
/* Quota manipulation */
void domain_entry_inc(struct connection *conn);
void domain_entry_dec(struct connection *conn);
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenstore/xs_lib.c
--- a/tools/xenstore/xs_lib.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenstore/xs_lib.c Mon May 22 14:13:38 2006 -0600
@@ -26,13 +26,13 @@

/* Common routines for the Xen store daemon and client library. */

-static const char *xs_daemon_rootdir(void)
+const char *xs_daemon_rootdir(void)
{
char *s = getenv("XENSTORED_ROOTDIR");
return (s ? s : "/var/lib/xenstored");
}

-static const char *xs_daemon_rundir(void)
+const char *xs_daemon_rundir(void)
{
char *s = getenv("XENSTORED_RUNDIR");
return (s ? s : "/var/run/xenstored");
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xenstore/xs_lib.h
--- a/tools/xenstore/xs_lib.h Mon May 22 08:53:26 2006 -0600
+++ b/tools/xenstore/xs_lib.h Mon May 22 14:13:38 2006 -0600
@@ -46,6 +46,8 @@ struct xs_permissions
#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2)

/* Path for various daemon things: env vars can override. */
+const char *xs_daemon_rootdir(void);
+const char *xs_daemon_rundir(void);
const char *xs_daemon_socket(void);
const char *xs_daemon_socket_ro(void);
const char *xs_domain_dev(void);
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile Mon May 22 08:53:26 2006 -0600
+++ b/tools/xentrace/Makefile Mon May 22 14:13:38 2006 -0600
@@ -14,7 +14,7 @@ HDRS = $(wildcard *.h)
HDRS = $(wildcard *.h)
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))

-BIN = xentrace tbctl setsize
+BIN = xentrace setsize
LIBBIN =
SCRIPTS = xentrace_format
MAN1 = $(wildcard *.1)
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/setsize.c
--- a/tools/xentrace/setsize.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xentrace/setsize.c Mon May 22 14:13:38 2006 -0600
@@ -5,33 +5,37 @@

int main(int argc, char * argv[])
{
- unsigned int size;
- int xc_handle = xc_interface_open();
+ unsigned long size;
+ int xc_handle = xc_interface_open();

- if (xc_tbuf_get_size(xc_handle, &size) != 0) {
- perror("Failure to get tbuf info from Xen. Guess size is 0");
- printf("This may mean that tracing is not enabled in xen.\n");
- // exit(1);
- }
- else
- printf("Current tbuf size: 0x%x\n", size);
+ if ( xc_tbuf_get_size(xc_handle, &size) != 0 )
+ {
+ perror("Failure to get tbuf info from Xen. Guess size is 0");
+ printf("This may mean that tracing is not enabled in xen.\n");
+ }
+ else
+ {
+ printf("Current tbuf size: 0x%lx\n", size);
+ }
+
+ if (argc < 2)
+ exit(0);
+
+ size = atol(argv[1]);
+
+ if ( xc_tbuf_set_size(xc_handle, size) != 0 )
+ {
+ perror("set_size Hypercall failure");
+ exit(1);
+ }
+ printf("set_size succeeded.\n");

- if (argc < 2)
- exit(0);
-
- size = atoi(argv[1]);
-
- if (xc_tbuf_set_size(xc_handle, size) != 0) {
- perror("set_size Hypercall failure");
- exit(1);
- }
- printf("set_size succeeded.\n");
+ if (xc_tbuf_get_size(xc_handle, &size) != 0)
+ perror("Failure to get tbuf info from Xen."
+ " Tracing must be enabled first");
+ else
+ printf("New tbuf size: 0x%lx\n", size);

- if (xc_tbuf_get_size(xc_handle, &size) != 0)
- perror("Failure to get tbuf info from Xen. Tracing must be enabled first");
- else
- printf("New tbuf size: 0x%x\n", size);
-
- xc_interface_close(xc_handle);
- return 0;
+ xc_interface_close(xc_handle);
+ return 0;
}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/xentrace.8
--- a/tools/xentrace/xentrace.8 Mon May 22 08:53:26 2006 -0600
+++ b/tools/xentrace/xentrace.8 Mon May 22 14:13:38 2006 -0600
@@ -35,6 +35,81 @@ all new records to the output
.B -s, --poll-sleep=p
set the time, p, (in milliseconds) to sleep between polling the buffers
for new data.
+.TP
+.B -c, --cpu-mask=c
+set cpu-mask
+.TP
+.B -e, --evt-mask=e
+set evt-mask
+.TP
+.B -?, --help
+Give this help list
+.TP
+.B --usage
+Give a short usage message
+.TP
+.B -V, --version
+Print program version
+
+.SS Event Classes (Masks)
+The following event classes (masks) can be used to filter the events being
+gathered by xentrace:
+.PP
+ \fIID\fP \fIDescription\fP
+.PP
+ 0x0001f000 TRC_GEN
+ 0x0002f000 TRC_SCHED
+ 0x0004f000 TRC_DOM0OP
+ 0x0008f000 TRC_VMX
+ 0x000af000 TRC_MEM
+ 0xfffff000 TRC_ALL
+
+
+.SS Event Subclasses (More Masks)
+The following event subclasses (masks) can also be used to filter the events being
+gathered by xentrace:
+.PP
+ \fIID\fP \fIDescription\fP
+.PP
+ 0x00081000 TRC_VMXEXIT
+ 0x00082000 TRC_VMXTIMER
+ 0x00084000 TRC_VMXINT
+ 0x00088000 TRC_VMXIO
+
+
+.SS Events
+.B xentrace
+collects the following events from the trace buffer:
+.PP
+ \fIID\fP \fIDescription\fP
+.PP
+ 0x0002f001 TRC_SCHED_DOM_ADD
+ 0x0002f002 TRC_SCHED_DOM_REM
+ 0x0002f003 TRC_SCHED_SLEEP
+ 0x0002f004 TRC_SCHED_WAKE
+ 0x0002f005 TRC_SCHED_YIELD
+ 0x0002f006 TRC_SCHED_BLOCK
+ 0x0002f007 TRC_SCHED_SHUTDOWN
+ 0x0002f008 TRC_SCHED_CTL
+ 0x0002f009 TRC_SCHED_ADJDOM
+ 0x0002f010 TRC_SCHED_SWITCH
+ 0x0002f011 TRC_SCHED_S_TIMER_FN
+ 0x0002f012 TRC_SCHED_T_TIMER_FN
+ 0x0002f013 TRC_SCHED_DOM_TIMER_FN
+ 0x0002f014 TRC_SCHED_SWITCH_INFPREV
+ 0x0002f015 TRC_SCHED_SWITCH_INFNEXT
+
+ 0x000af001 TRC_MEM_PAGE_GRANT_MAP
+ 0x000af002 TRC_MEM_PAGE_GRANT_UNMAP
+ 0x000af003 TRC_MEM_PAGE_GRANT_TRANSFER
+
+ 0x00081001 TRC_VMX_VMEXIT
+ 0x00081002 TRC_VMX_VMENTRY
+
+ 0x00082001 TRC_VMX_TIMER_INTR
+
+ 0x00084001 TRC_VMX_INT
+.PP

.SH AUTHOR
Mark A. Williamson <mark.a.williamson@intel.com>
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon May 22 08:53:26 2006 -0600
+++ b/tools/xentrace/xentrace.c Mon May 22 14:13:38 2006 -0600
@@ -46,7 +46,7 @@ extern FILE *stderr;
/* sleep for this long (milliseconds) between checking the trace buffers */
#define POLL_SLEEP_MILLIS 100

-
+#define DEFAULT_TBUF_SIZE 20
/***** The code **************************************************************/

typedef struct settings_st {
@@ -101,32 +101,25 @@ void write_rec(unsigned int cpu, struct
}
}

-/**
- * get_tbufs - get pointer to and size of the trace buffers
- * @mfn: location to store mfn of the trace buffers to
- * @size: location to store the size of a trace buffer to
- *
- * Gets the machine address of the trace pointer area and the size of the
- * per CPU buffers.
- */
-void get_tbufs(unsigned long *mfn, unsigned long *size)
-{
- uint32_t size32;
- int xc_handle = xc_interface_open(); /* for accessing control interface */
-
- if (xc_tbuf_get_size(xc_handle, &size32) != 0)
- goto fail;
- *size = size32;
-
- if (xc_tbuf_get_mfn(xc_handle, mfn) != 0)
- goto fail;
+static void get_tbufs(unsigned long *mfn, unsigned long *size)
+{
+ int xc_handle = xc_interface_open();
+ int ret;
+
+ if ( xc_handle < 0 )
+ {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = xc_tbuf_enable(xc_handle, DEFAULT_TBUF_SIZE, mfn, size);
+
+ if ( ret != 0 )
+ {
+ perror("Couldn't enable trace buffers");
+ exit(1);
+ }

xc_interface_close(xc_handle);
- return;
-
-fail:
- PERROR("Failure to get trace buffer pointer from Xen");
- exit(EXIT_FAILURE);
}

/**
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/xentrace_format
--- a/tools/xentrace/xentrace_format Mon May 22 08:53:26 2006 -0600
+++ b/tools/xentrace/xentrace_format Mon May 22 14:13:38 2006 -0600
@@ -89,7 +89,7 @@ CPUREC = "I"
CPUREC = "I"
TRCREC = "QLLLLLL"

-last_tsc = [0,0,0,0,0,0,0,0]
+last_tsc = [0]

i=0

@@ -111,7 +111,9 @@ while not interrupted:

#print i, tsc

- if tsc < last_tsc[cpu]:
+ if cpu >= len(last_tsc):
+ last_tsc += [0] * (cpu - len(last_tsc) + 1)
+ elif tsc < last_tsc[cpu]:
print "TSC stepped backward cpu %d ! %d %d" % (cpu,tsc,last_tsc[cpu])

last_tsc[cpu] = tsc
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/configure.ac Mon May 22 14:13:38 2006 -0600
@@ -99,6 +99,7 @@ AC_CONFIG_FILES([.
tests/block-list/Makefile
tests/block-create/Makefile
tests/block-destroy/Makefile
+ tests/block-integrity/Makefile
tests/console/Makefile
tests/create/Makefile
tests/destroy/Makefile
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/ramdisk/bin/create_disk_image
--- a/tools/xm-test/ramdisk/bin/create_disk_image Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/ramdisk/bin/create_disk_image Mon May 22 14:13:38 2006 -0600
@@ -207,6 +207,13 @@ function dd_rootfs_to_image()
dd if="$ROOTFS" of="$LOOPP" > /dev/null 2>&1
if [ $? -ne 0 ]; then
die "Failed to dd $ROOTFS to $LOOPP."
+ fi
+
+ # Resize fs to use full partition
+ e2fsck -f $LOOPP
+ resize2fs $LOOPP
+ if [ $? -ne 0 ]; then
+ die "Failed to resize rootfs on $LOOPP."
fi
}

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/Makefile.am
--- a/tools/xm-test/tests/Makefile.am Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/Makefile.am Mon May 22 14:13:38 2006 -0600
@@ -1,14 +1,15 @@ SUBDIRS = \
SUBDIRS = \
block-create \
- block-list \
- block-destroy \
+ block-list \
+ block-destroy \
+ block-integrity \
console \
create \
destroy \
dmesg \
domid \
domname \
- help \
+ help \
info \
list \
memmax \
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py
--- a/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py Mon May 22 14:13:38 2006 -0600
@@ -4,20 +4,23 @@
# Authors: Dan Smith <danms@us.ibm.com>
# Ryan Harper <ryanh@us.ibm.com>

-# 1) Make sure we have a multi cpu system
+# 1) Make sure we have a multi cpu system and dom0 has at
+# least 2 vcpus online.
# 2) clone standard config (/etc/xen/xend-config.sxp)
# 3) modify clone with enforce_dom0_cpus=X
# 4) restart xend with modified config
# 5) check /proc/cpuinfo for cpu count
-# 6) check xm list -v to see that only 1 cpu is online for dom0
-# 7) Restart xend with default config
+# 6) check xm info 'VCPUs' field to see that only 'enforce_dom0_cpus'
+# number of cpus are online in dom0
+# 7) Restore initial dom0 vcpu state
+# 8) Restart xend with default config

import sys
import re
import time
import os

-# what value should dom0_cpus be enforced?
+# what value should dom0_cpus enforce?
enforce_dom0_cpus=1

from XmTestLib import *
@@ -25,12 +28,19 @@ check_status = 1
check_status = 1
max_tries = 10

-# 1) Make sure we have a multi cpu system
+# 1) Make sure we have a multi cpu system and dom0 has at least 2 vcpus online.

if smpConcurrencyLevel() <= 1:
print "*** NOTE: This machine does not have more than one physical"
print " or logical cpu. The vcpu-disable test cannot be run!"
SKIP("Host not capable of running test")
+
+# count number of online vcpus in dom0
+dom0_online_vcpus = int(getDomInfo("Domain-0", "VCPUs"))
+if dom0_online_vcpus <= 1:
+ print "*** NOTE: DOM0 needs at least 2 VCPUs online to run this test"
+ print " Please enable additional vcpus if possible via xm vcpu-set"
+ SKIP("Host state not capable of running test")

# 2) clone standard config (/etc/xen/xend-config.sxp)
# 3) modify clone with enforce_dom0_cpus=1
@@ -55,36 +65,61 @@ if check_status and status != 0:
FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))

# 5) check /proc/cpuinfo for cpu count
-cmd = "grep \"^processor\" /proc/cpuinfo | wc -l"
-status, output = traceCommand(cmd)
+
+# It takes some time for the CPU count to change, on multi-proc systems, so check the number of procs in a loop for 20 seconds.
+#Sleep inside the loop for a second each time.
+timeout = 20
+starttime = time.time()
+while timeout + starttime > time.time():
+# Check /proc/cpuinfo
+ cmd = "grep \"^processor\" /proc/cpuinfo | wc -l"
+ status, output = traceCommand(cmd)
+ if check_status and status != 0:
+ os.unsetenv("XEND_CONFIG")
+ restartXend()
+ FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
+# Has it succeeded? If so, we can leave the loop
+ if output == str(enforce_dom0_cpus):
+ break
+# Sleep for 1 second before trying again
+ time.sleep(1)
+if output != str(enforce_dom0_cpus):
+ os.unsetenv("XEND_CONFIG")
+ restartXend()
+ FAIL("/proc/cpuinfo says xend didn't enforce dom0_cpus (%s != %s)"%(output,
+ enforce_dom0_cpus))
+
+# 6) count number of online cpus and see that it matches enforce value
+num_online = int(getDomInfo("Domain-0", "VCPUs"))
+if num_online != enforce_dom0_cpus:
+ os.unsetenv("XEND_CONFIG")
+ restartXend()
+ FAIL("xm says xend didn't enforce dom0_cpus (%s != %s)" %(num_online,
+ enforce_dom0_cpus))
+
+# 7) restore dead processors
+status, output = traceCommand("xm vcpu-set 0 %s"%(dom0_online_vcpus))
if check_status and status != 0:
os.unsetenv("XEND_CONFIG")
restartXend()
FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))

-if output != str(enforce_dom0_cpus):
+# check restore worked
+# Since this also takes time, we will do it in a loop with a 20 second timeout.
+timeout=20
+starttime=time.time()
+while timeout + starttime > time.time():
+ num_online = int(getDomInfo("Domain-0", "VCPUs"))
+ if num_online == dom0_online_vcpus:
+ break
+ time.sleep(1)
+if num_online != dom0_online_vcpus:
os.unsetenv("XEND_CONFIG")
restartXend()
- FAIL("/proc/cpuinfo says xend didn't enforce dom0_cpus (%s != %s)" %(output, enforce_dom0_cpus))
+ FAIL("failed to restore dom0's VCPUs")

-# 7) count number of online cpus and see that it matches enforce value
-dom0vcpus = getVcpuInfo("Domain-0")
-num_online = len(filter(lambda x: x >= 0, dom0vcpus.values()))
-if num_online != enforce_dom0_cpus:
- os.unsetenv("XEND_CONFIG")
- restartXend()
- FAIL("xm says xend didn't enforce dom0_cpus (%s != %s)" %(num_online, enforce_dom0_cpus))

-# restore dead processors
-for (k,v) in zip(dom0vcpus.keys(),dom0vcpus.values()):
- if v == -1:
- status, output = traceCommand("xm vcpu-enable 0 %s"%(k))
- if check_status and status != 0:
- os.unsetenv("XEND_CONFIG")
- restartXend()
- FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
-
-# Restart xend with default config
+# 8) Restart xend with default config
os.unsetenv("XEND_CONFIG")
restartXend()

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/03_network_local_tcp_pos.py
--- a/tools/xm-test/tests/network/03_network_local_tcp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/03_network_local_tcp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -44,7 +44,7 @@ try:
lofails=""
for size in trysizes:
out = console.runCmd("hping2 127.0.0.1 -E /dev/urandom -q -c 20 "
- + "--fast -d " + str(size))
+ + "--fast -d " + str(size) + " -N " + str(size))
if out["return"]:
lofails += " " + str(size)

@@ -54,7 +54,7 @@ try:
ip = netdev.getNetDevIP()
for size in trysizes:
out = console.runCmd("hping2 " + ip + " -E /dev/urandom -q -c 20 "
- + "--fast -d "+ str(size))
+ + "--fast -d "+ str(size) + " -N " + str(size))
if out["return"]:
eth0fails += " " + str(size)
except ConsoleError, e:
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/04_network_local_udp_pos.py
--- a/tools/xm-test/tests/network/04_network_local_udp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/04_network_local_udp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -43,7 +43,7 @@ try:
lofails=""
for size in trysizes:
out = console.runCmd("hping2 127.0.0.1 -E /dev/urandom -2 -q -c 20 "
- + "--fast -d " + str(size))
+ + "--fast -d " + str(size) + " -N " + str(size))
if out["return"]:
lofails += " " + str(size)
print out["output"]
@@ -54,7 +54,7 @@ try:
ip = netdev.getNetDevIP()
for size in trysizes:
out = console.runCmd("hping2 " + ip + " -E /dev/urandom -2 -q -c 20 "
- + "--fast -d " + str(size))
+ + "--fast -d " + str(size) + " -N " + str(size))
if out["return"]:
eth0fails += " " + str(size)
print out["output"]
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/06_network_dom0_tcp_pos.py
--- a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -44,7 +44,7 @@ try:
dom0ip = netdev.getDom0AliasIP()
for size in trysizes:
out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -q -c 20 "
- + "--fast -d " + str(size))
+ + "--fast -d " + str(size) + " -N " + str(size))
if out["return"]:
fails += " " + str(size)
print out["output"]
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/07_network_dom0_udp_pos.py
--- a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -43,7 +43,7 @@ try:
dom0ip = netdev.getDom0AliasIP()
for size in trysizes:
out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -2 -q -c 20"
- + " --fast -d " + str(size))
+ + " --fast -d " + str(size) + " -N " + str(size))
if out["return"]:
fails += " " + str(size)
print out["output"]
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/12_network_domU_tcp_pos.py
--- a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -50,7 +50,7 @@ try:
ip2 = dst_netdev.getNetDevIP()
for size in pingsizes:
out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -q -c 20 "
- + "--fast -d " + str(size))
+ + "--fast -d " + str(size) + " -N " + str(size))
if out["return"]:
fails += " " + str(size)
print out["output"]
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/network/13_network_domU_udp_pos.py
--- a/tools/xm-test/tests/network/13_network_domU_udp_pos.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/network/13_network_domU_udp_pos.py Mon May 22 14:13:38 2006 -0600
@@ -50,7 +50,7 @@ try:
ip2 = dst_netdev.getNetDevIP()
for size in pingsizes:
out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -2 -q "
- + "-c 20 --fast -d " + str(size))
+ + "-c 20 --fast -d " + str(size) + " -N " + str(size))
if out["return"]:
fails += " " + str(size)
print out["output"]
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py Mon May 22 14:13:38 2006 -0600
@@ -6,6 +6,7 @@
# Positive Test: create domain with virtual TPM attached at build time,
# check list of pcrs; locally migrate the domain and
# check list of pcrs again
+# This test does local live migration.

from XmTestLib import *
from vtpm_utils import *
@@ -50,40 +51,44 @@ domain.closeConsole()

old_domid = domid(domName)

-try:
- status, ouptut = traceCommand("xm migrate -l %s localhost" %
- domName,
- timeout=90)
-except TimeoutError, e:
- saveLog(consoleHistory)
- vtpm_cleanup(domName)
- FAIL(str(e))
+loop = 0
+while loop < 3:
+ try:
+ status, ouptut = traceCommand("xm migrate -l %s localhost" %
+ domName,
+ timeout=90)
+ except TimeoutError, e:
+ saveLog(consoleHistory)
+ vtpm_cleanup(domName)
+ FAIL(str(e))

-if status != 0:
- saveLog(consoleHistory)
- vtpm_cleanup(domName)
- FAIL("xm migrate did not succeed. External device migration activated?")
+ if status != 0:
+ saveLog(consoleHistory)
+ vtpm_cleanup(domName)
+ FAIL("xm migrate did not succeed. External device migration activated?")


-domName = domain.getName()
-new_domid = domid(domName)
+ domName = domain.getName()
+ new_domid = domid(domName)

-if (old_domid == new_domid):
- vtpm_cleanup(domName)
- FAIL("xm migrate failed, domain id is still %s" % old_domid)
+ if (old_domid == new_domid):
+ vtpm_cleanup(domName)
+ FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+ (old_domid,loop))

-try:
- console = domain.getConsole()
-except ConsoleError, e:
- vtpm_cleanup(domName)
- FAIL(str(e))
+ try:
+ console = domain.getConsole()
+ except ConsoleError, e:
+ vtpm_cleanup(domName)
+ FAIL(str(e))

-try:
- run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
-except ConsoleError, e:
- saveLog(console.getHistory())
- vtpm_cleanup(domName)
- FAIL(str(e))
+ try:
+ run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+ except ConsoleError, e:
+ saveLog(console.getHistory())
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+ loop += 1

domain.closeConsole()

diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/vtpm/Makefile.am
--- a/tools/xm-test/tests/vtpm/Makefile.am Mon May 22 08:53:26 2006 -0600
+++ b/tools/xm-test/tests/vtpm/Makefile.am Mon May 22 14:13:38 2006 -0600
@@ -3,7 +3,8 @@ TESTS = 01_vtpm-list_pos.test \
TESTS = 01_vtpm-list_pos.test \
02_vtpm-cat_pcrs.test \
03_vtpm-susp_res.test \
- 04_vtpm-loc_migr.test
+ 04_vtpm-loc_migr.test \
+ 05_vtpm-loc_migr.test

XFAIL_TESTS =

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/dom0_ops.c Mon May 22 14:13:38 2006 -0600
@@ -404,27 +404,6 @@ long arch_do_dom0_op(struct dom0_op *op,
}
break;

- case DOM0_PHYSICAL_MEMORY_MAP:
- {
- struct dom0_memory_map_entry entry;
- int i;
-
- for ( i = 0; i < e820.nr_map; i++ )
- {
- if ( i >= op->u.physical_memory_map.max_map_entries )
- break;
- entry.start = e820.map[i].addr;
- entry.end = e820.map[i].addr + e820.map[i].size;
- entry.is_ram = (e820.map[i].type == E820_RAM);
- (void)copy_to_guest_offset(
- op->u.physical_memory_map.memory_map, i, &entry, 1);
- }
-
- op->u.physical_memory_map.nr_map_entries = i;
- (void)copy_to_guest(u_dom0_op, op, 1);
- }
- break;
-
case DOM0_HYPERCALL_INIT:
{
struct domain *d;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/domain.c Mon May 22 14:13:38 2006 -0600
@@ -286,6 +286,11 @@ int arch_set_info_guest(
v->arch.flags |= TF_kernel_mode;

memcpy(&v->arch.guest_context, c, sizeof(*c));
+
+ /* Only CR0.TS is modifiable by guest or admin. */
+ v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
+ v->arch.guest_context.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS;
+
init_int80_direct_trap(v);

if ( !(c->flags & VGCF_HVM_GUEST) )
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/hvm.c Mon May 22 14:13:38 2006 -0600
@@ -189,7 +189,11 @@ void hvm_setup_platform(struct domain* d
if ( !hvm_guest(current) || (current->vcpu_id != 0) )
return;

- shadow_direct_map_init(d);
+ if ( shadow_direct_map_init(d) == 0 )
+ {
+ printk("Can not allocate shadow direct map for HVM domain.\n");
+ domain_crash_synchronous();
+ }

hvm_map_io_shared_page(d);
hvm_get_info(d);
@@ -240,15 +244,18 @@ int cpu_get_interrupt(struct vcpu *v, in
{
int intno;
struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic;
+ unsigned long flags;

if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) {
/* set irq request if a PIC irq is still pending */
/* XXX: improve that */
+ spin_lock_irqsave(&s->lock, flags);
pic_update_irq(s);
+ spin_unlock_irqrestore(&s->lock, flags);
return intno;
}
/* read the irq from the PIC */
- if ( (intno = cpu_get_pic_interrupt(v, type)) != -1 )
+ if ( v->vcpu_id == 0 && (intno = cpu_get_pic_interrupt(v, type)) != -1 )
return intno;

return -1;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/i8259.c Mon May 22 14:13:38 2006 -0600
@@ -35,9 +35,13 @@
#include <asm/current.h>

/* set irq level. If an edge is detected, then the IRR is set to 1 */
+/* Caller must hold vpic lock */
static inline void pic_set_irq1(PicState *s, int irq, int level)
{
int mask;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));
+
mask = 1 << irq;
if (s->elcr & mask) {
/* level triggered */
@@ -63,9 +67,13 @@ static inline void pic_set_irq1(PicState

/* return the highest priority found in mask (highest = smallest
number). Return 8 if no irq */
+/* Caller must hold vpic lock */
static inline int get_priority(PicState *s, int mask)
{
int priority;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));
+
if (mask == 0)
return 8;
priority = 0;
@@ -75,9 +83,12 @@ static inline int get_priority(PicState
}

/* return the pic wanted interrupt. return -1 if none */
+/* Caller must hold vpic lock */
static int pic_get_irq(PicState *s)
{
int mask, cur_priority, priority;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));

mask = s->irr & ~s->imr;
priority = get_priority(s, mask);
@@ -101,9 +112,12 @@ static int pic_get_irq(PicState *s)
/* raise irq to CPU if necessary. must be called every time the active
irq may change */
/* XXX: should not export it, but it is needed for an APIC kludge */
+/* Caller must hold vpic lock */
void pic_update_irq(struct hvm_virpic *s)
{
int irq2, irq;
+
+ BUG_ON(!spin_is_locked(&s->lock));

/* first look at slave pic */
irq2 = pic_get_irq(&s->pics[1]);
@@ -122,29 +136,40 @@ void pic_set_irq_new(void *opaque, int i
void pic_set_irq_new(void *opaque, int irq, int level)
{
struct hvm_virpic *s = opaque;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
hvm_vioapic_set_irq(current->domain, irq, level);
pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
/* used for IOAPIC irqs */
if (s->alt_irq_func)
s->alt_irq_func(s->alt_irq_opaque, irq, level);
pic_update_irq(s);
+ spin_unlock_irqrestore(&s->lock, flags);
}

void do_pic_irqs (struct hvm_virpic *s, uint16_t irqs)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
s->pics[1].irr |= (uint8_t)(irqs >> 8);
s->pics[0].irr |= (uint8_t) irqs;
hvm_vioapic_do_irqs(current->domain, irqs);
pic_update_irq(s);
+ spin_unlock_irqrestore(&s->lock, flags);
}

void do_pic_irqs_clear (struct hvm_virpic *s, uint16_t irqs)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
s->pics[0].irr &= ~(uint8_t) irqs;
hvm_vioapic_do_irqs_clear(current->domain, irqs);
pic_update_irq(s);
+ spin_unlock_irqrestore(&s->lock, flags);
}

/* obsolete function */
@@ -154,8 +179,11 @@ void pic_set_irq(struct hvm_virpic *isa_
}

/* acknowledge interrupt 'irq' */
+/* Caller must hold vpic lock */
static inline void pic_intack(PicState *s, int irq)
{
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));
+
if (s->auto_eoi) {
if (s->rotate_on_auto_eoi)
s->priority_add = (irq + 1) & 7;
@@ -170,7 +198,9 @@ int pic_read_irq(struct hvm_virpic *s)
int pic_read_irq(struct hvm_virpic *s)
{
int irq, irq2, intno;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
irq = pic_get_irq(&s->pics[0]);
if (irq >= 0) {
pic_intack(&s->pics[0], irq);
@@ -194,13 +224,17 @@ int pic_read_irq(struct hvm_virpic *s)
intno = s->pics[0].irq_base + irq;
}
pic_update_irq(s);
+ spin_unlock_irqrestore(&s->lock, flags);

return intno;
}

+/* Caller must hold vpic lock */
static void update_shared_irr(struct hvm_virpic *s, PicState *c)
{
uint8_t *pl, *pe;
+
+ BUG_ON(!spin_is_locked(&s->lock));

get_sp(current->domain)->sp_global.pic_elcr =
s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
@@ -216,9 +250,12 @@ static void update_shared_irr(struct hvm
}
}

+/* Caller must hold vpic lock */
static void pic_reset(void *opaque)
{
PicState *s = opaque;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));

s->last_irr = 0;
s->irr = 0;
@@ -237,10 +274,13 @@ static void pic_reset(void *opaque)
s->elcr = 0;
}

+/* Caller must hold vpic lock */
static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
PicState *s = opaque;
int priority, cmd, irq;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));

addr &= 1;
if (addr == 0) {
@@ -328,9 +368,12 @@ static void pic_ioport_write(void *opaqu
}
}

+/* Caller must hold vpic lock */
static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
{
int ret;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));

ret = pic_get_irq(s);
if (ret >= 0) {
@@ -350,11 +393,14 @@ static uint32_t pic_poll_read (PicState
return ret;
}

+/* Caller must hold vpic lock */
static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
{
PicState *s = opaque;
unsigned int addr;
int ret;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));

addr = addr1;
addr &= 1;
@@ -375,23 +421,30 @@ static uint32_t pic_ioport_read(void *op
}

/* memory mapped interrupt status */
-/* XXX: may be the same than pic_read_irq() */
+/* XXX: may be the same than pic_read_rq() */
uint32_t pic_intack_read(struct hvm_virpic *s)
{
int ret;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
ret = pic_poll_read(&s->pics[0], 0x00);
if (ret == 2)
ret = pic_poll_read(&s->pics[1], 0x80) + 8;
/* Prepare for ISR read */
s->pics[0].read_reg_select = 1;
+ spin_unlock_irqrestore(&s->lock, flags);

return ret;
}

static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+/* Caller must hold vpic lock */
{
PicState *s = opaque;
+
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));
+
s->elcr = val & s->elcr_mask;
}

@@ -402,23 +455,31 @@ static uint32_t elcr_ioport_read(void *o
}

/* XXX: add generic master/slave system */
+/* Caller must hold vpic lock */
static void pic_init1(int io_addr, int elcr_addr, PicState *s)
{
+ BUG_ON(!spin_is_locked(&s->pics_state->lock));
+
pic_reset(s);
}

void pic_init(struct hvm_virpic *s, void (*irq_request)(void *, int),
void *irq_request_opaque)
{
+ unsigned long flags;
+
memset(s, 0, sizeof(*s));
+ spin_lock_init(&s->lock);
+ s->pics[0].pics_state = s;
+ s->pics[1].pics_state = s;
+ spin_lock_irqsave(&s->lock, flags);
pic_init1(0x20, 0x4d0, &s->pics[0]);
pic_init1(0xa0, 0x4d1, &s->pics[1]);
+ spin_unlock_irqrestore(&s->lock, flags);
s->pics[0].elcr_mask = 0xf8;
s->pics[1].elcr_mask = 0xde;
s->irq_request = irq_request;
s->irq_request_opaque = irq_request_opaque;
- s->pics[0].pics_state = s;
- s->pics[1].pics_state = s;
return;
}

@@ -426,8 +487,12 @@ void pic_set_alt_irq_func(struct hvm_vir
void (*alt_irq_func)(void *, int, int),
void *alt_irq_opaque)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
s->alt_irq_func = alt_irq_func;
s->alt_irq_opaque = alt_irq_opaque;
+ spin_unlock_irqrestore(&s->lock, flags);
}

static int intercept_pic_io(ioreq_t *p)
@@ -435,6 +500,7 @@ static int intercept_pic_io(ioreq_t *p)
struct hvm_virpic *pic;
struct vcpu *v = current;
uint32_t data;
+ unsigned long flags;

if ( p->size != 1 || p->count != 1) {
printk("PIC_IO wrong access size %d!\n", (int)p->size);
@@ -446,12 +512,16 @@ static int intercept_pic_io(ioreq_t *p)
hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
else
data = p->u.data;
+ spin_lock_irqsave(&pic->lock, flags);
pic_ioport_write((void*)&pic->pics[p->addr>>7],
(uint32_t) p->addr, (uint32_t) (data & 0xff));
+ spin_unlock_irqrestore(&pic->lock, flags);
}
else {
+ spin_lock_irqsave(&pic->lock, flags);
data = pic_ioport_read(
(void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
+ spin_unlock_irqrestore(&pic->lock, flags);
if(p->pdata_valid)
hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
else
@@ -465,6 +535,7 @@ static int intercept_elcr_io(ioreq_t *p)
struct hvm_virpic *s;
struct vcpu *v = current;
uint32_t data;
+ unsigned long flags;

if ( p->size != 1 || p->count != 1 ) {
printk("PIC_IO wrong access size %d!\n", (int)p->size);
@@ -477,10 +548,12 @@ static int intercept_elcr_io(ioreq_t *p)
hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
else
data = p->u.data;
+ spin_lock_irqsave(&s->lock, flags);
elcr_ioport_write((void*)&s->pics[p->addr&1],
(uint32_t) p->addr, (uint32_t)( data & 0xff));
get_sp(current->domain)->sp_global.pic_elcr =
s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
+ spin_unlock_irqrestore(&s->lock, flags);
}
else {
data = (u64) elcr_ioport_read(
@@ -512,10 +585,9 @@ int cpu_get_pic_interrupt(struct vcpu *v
if ( !vlapic_accept_pic_intr(v) )
return -1;

- if ( !plat->interrupt_request )
+ if (cmpxchg(&plat->interrupt_request, 1, 0) != 1)
return -1;

- plat->interrupt_request = 0;
/* read the irq from the PIC */
intno = pic_read_irq(s);
*type = VLAPIC_DELIV_MODE_EXT;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/platform.c Mon May 22 14:13:38 2006 -0600
@@ -865,7 +865,7 @@ void handle_mmio(unsigned long va, unsig
* copy ourself. After this copy succeeds, "rep movs" is executed
* again.
*/
- if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
+ if ((addr & PAGE_MASK) != ((addr + sign * (size - 1)) & PAGE_MASK)) {
unsigned long value = 0;

mmio_opp->flags |= OVERLAP;
@@ -876,7 +876,7 @@ void handle_mmio(unsigned long va, unsig
hvm_copy(&value, addr, size, HVM_COPY_IN);
send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
} else {
- if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
+ if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & PAGE_MASK)) {
regs->eip -= inst_len; /* do not advance %eip */

if (sign > 0)
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c Mon May 22 14:13:38 2006 -0600
@@ -132,17 +132,13 @@ asmlinkage void svm_intr_assist(void)
ASSERT(vmcb);

/* Check if an Injection is active */
- if (v->arch.hvm_svm.injecting_event) {
/* Previous Interrupt delivery caused this Intercept? */
if (vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0)) {
v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
// printk("Injecting PF#: saving IRQ from ExitInfo\n");
vmcb->exitintinfo.bytes = 0;
-
- /* bail out, we won't be injecting an interrupt this time */
- return;
+ re_injecting = 1;
}
- }

/* Guest's interrputs masked? */
rflags = vmcb->rflags;
@@ -151,16 +147,9 @@ asmlinkage void svm_intr_assist(void)
/* bail out, we won't be injecting an interrupt this time */
return;
}
-
- /* Interrupt delivery caused an Intercept? */
- if (vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0)) {
-// printk("Re-injecting IRQ from ExitInfo\n");
- intr_vector = vmcb->exitintinfo.fields.vector;
- vmcb->exitintinfo.bytes = 0;
- re_injecting = 1;
- }
+
/* Previous interrupt still pending? */
- else if (vmcb->vintr.fields.irq) {
+ if (vmcb->vintr.fields.irq) {
// printk("Re-injecting IRQ from Vintr\n");
intr_vector = vmcb->vintr.fields.vector;
vmcb->vintr.bytes = 0;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Mon May 22 14:13:38 2006 -0600
@@ -82,9 +82,11 @@ void svm_dump_regs(const char *from, str

static void svm_relinquish_guest_resources(struct domain *d);

-/* Host save area */
-struct host_save_area *host_save_area[ NR_CPUS ] = {0};
-static struct asid_pool ASIDpool[NR_CPUS];
+
+extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm );
+
+/* Host save area and ASID glogal data */
+struct svm_percore_globals svm_globals[NR_CPUS];

/*
* Initializes the POOL of ASID used by the guests per core.
@@ -92,15 +94,15 @@ void asidpool_init( int core )
void asidpool_init( int core )
{
int i;
- ASIDpool[core].asid_lock = SPIN_LOCK_UNLOCKED;
- spin_lock(&ASIDpool[core].asid_lock);
+ svm_globals[core].ASIDpool.asid_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock(&svm_globals[core].ASIDpool.asid_lock);
/* Host ASID is always in use */
- ASIDpool[core].asid[INITIAL_ASID] = ASID_INUSE;
+ svm_globals[core].ASIDpool.asid[INITIAL_ASID] = ASID_INUSE;
for( i=1; i<ASID_MAX; i++ )
{
- ASIDpool[core].asid[i] = ASID_AVAILABLE;
- }
- spin_unlock(&ASIDpool[core].asid_lock);
+ svm_globals[core].ASIDpool.asid[i] = ASID_AVAILABLE;
+ }
+ spin_unlock(&svm_globals[core].ASIDpool.asid_lock);
}


@@ -110,10 +112,10 @@ static int asidpool_fetch_next( struct v
int i;
for( i = 1; i < ASID_MAX; i++ )
{
- if( ASIDpool[core].asid[i] == ASID_AVAILABLE )
+ if( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE )
{
vmcb->guest_asid = i;
- ASIDpool[core].asid[i] = ASID_INUSE;
+ svm_globals[core].ASIDpool.asid[i] = ASID_INUSE;
return i;
}
}
@@ -138,42 +140,42 @@ int asidpool_assign_next( struct vmcb_st
int res = 1;
static unsigned long cnt=0;

- spin_lock(&ASIDpool[oldcore].asid_lock);
+ spin_lock(&svm_globals[oldcore].ASIDpool.asid_lock);
if( retire_current && vmcb->guest_asid ) {
- ASIDpool[oldcore].asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
- }
- spin_unlock(&ASIDpool[oldcore].asid_lock);
- spin_lock(&ASIDpool[newcore].asid_lock);
+ svm_globals[oldcore].ASIDpool.asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
+ }
+ spin_unlock(&svm_globals[oldcore].ASIDpool.asid_lock);
+ spin_lock(&svm_globals[newcore].ASIDpool.asid_lock);
if( asidpool_fetch_next( vmcb, newcore ) < 0 ) {
if (svm_dbg_on)
printk( "SVM: tlb(%ld)\n", cnt++ );
/* FLUSH the TLB and all retired slots are made available */
vmcb->tlb_control = 1;
for( i = 1; i < ASID_MAX; i++ ) {
- if( ASIDpool[newcore].asid[i] == ASID_RETIRED ) {
- ASIDpool[newcore].asid[i] = ASID_AVAILABLE;
+ if( svm_globals[newcore].ASIDpool.asid[i] == ASID_RETIRED ) {
+ svm_globals[newcore].ASIDpool.asid[i] = ASID_AVAILABLE;
}
}
/* Get the First slot available */
res = asidpool_fetch_next( vmcb, newcore ) > 0;
}
- spin_unlock(&ASIDpool[newcore].asid_lock);
+ spin_unlock(&svm_globals[newcore].ASIDpool.asid_lock);
return res;
}

void asidpool_retire( struct vmcb_struct *vmcb, int core )
{
- spin_lock(&ASIDpool[core].asid_lock);
+ spin_lock(&svm_globals[core].ASIDpool.asid_lock);
if( vmcb->guest_asid ) {
- ASIDpool[core].asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
+ svm_globals[core].ASIDpool.asid[ vmcb->guest_asid & (ASID_MAX-1) ] = ASID_RETIRED;
}
- spin_unlock(&ASIDpool[core].asid_lock);
-}
-
-static inline void svm_inject_exception(struct vmcb_struct *vmcb,
- int trap, int ev, int error_code)
+ spin_unlock(&svm_globals[core].ASIDpool.asid_lock);
+}
+
+static inline void svm_inject_exception(struct vcpu *v, int trap, int ev, int error_code)
{
eventinj_t event;
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;

event.bytes = 0;
event.fields.v = 1;
@@ -198,8 +200,13 @@ void stop_svm(void)
wrmsr(MSR_EFER, eax, edx);

/* release the HSA */
- free_host_save_area( host_save_area[ cpu ] );
- host_save_area[ cpu ] = NULL;
+ free_host_save_area( svm_globals[cpu].hsa );
+ free_host_save_area( svm_globals[cpu].scratch_hsa );
+ svm_globals[cpu].hsa = NULL;
+ svm_globals[cpu].hsa_pa = 0;
+ svm_globals[cpu].scratch_hsa = NULL;
+ svm_globals[cpu].scratch_hsa_pa = 0;
+ wrmsr(MSR_K8_VM_HSAVE_PA, 0, 0 );

printk("AMD SVM Extension is disabled.\n");
}
@@ -329,7 +336,7 @@ static inline int long_mode_do_msr_write
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
printk("trying to set reserved bit in EFER\n");
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
return 0;
}

@@ -343,7 +350,7 @@ static inline int long_mode_do_msr_write
{
printk("trying to set LME bit when "
"in paging mode or PAE bit is not set\n");
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
return 0;
}
set_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state);
@@ -367,7 +374,7 @@ static inline int long_mode_do_msr_write
if (!IS_CANO_ADDRESS(msr_content))
{
HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
}

if (regs->ecx == MSR_FS_BASE)
@@ -451,20 +458,26 @@ int start_svm(void)

if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
return 0;
+ svm_globals[cpu].hsa = alloc_host_save_area();
+ if (! svm_globals[cpu].hsa)
+ return 0;

rdmsr(MSR_EFER, eax, edx);
eax |= EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
- asidpool_init(smp_processor_id());
+ asidpool_init( cpu );
printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );

/* Initialize the HSA for this core */
- host_save_area[ cpu ] = alloc_host_save_area();
- phys_hsa = (u64) virt_to_maddr( host_save_area[ cpu ] );
+ phys_hsa = (u64) virt_to_maddr( svm_globals[cpu].hsa );
phys_hsa_lo = (u32) phys_hsa;
phys_hsa_hi = (u32) (phys_hsa >> 32);
wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
-
+ svm_globals[cpu].hsa_pa = phys_hsa;
+
+ svm_globals[cpu].scratch_hsa = alloc_host_save_area();
+ svm_globals[cpu].scratch_hsa_pa = (u64)virt_to_maddr( svm_globals[cpu].scratch_hsa );
+
/* Setup HVM interfaces */
hvm_funcs.disable = stop_svm;

@@ -546,7 +559,6 @@ static inline int svm_do_debugout(unsign
return 1;
}

-
void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -577,8 +589,6 @@ void svm_store_cpu_user_regs(struct cpu_
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
- regs->fs = vmcb->fs.sel;
- regs->gs = vmcb->gs.sel;
}

/* XXX Use svm_load_cpu_guest_regs instead */
@@ -594,12 +604,6 @@ void svm_load_cpu_user_regs(struct vcpu
vmcb->rflags = regs->eflags;
vmcb->cs.sel = regs->cs;
vmcb->rip = regs->eip;
-
- vmcb->ds.sel = regs->ds;
- vmcb->es.sel = regs->es;
- vmcb->fs.sel = regs->fs;
- vmcb->gs.sel = regs->gs;
-
if (regs->eflags & EF_TF)
*intercepts |= EXCEPTION_BITMAP_DB;
else
@@ -897,10 +901,9 @@ static void svm_do_general_protection_fa
(unsigned long)regs->eax, (unsigned long)regs->ebx,
(unsigned long)regs->ecx, (unsigned long)regs->edx,
(unsigned long)regs->esi, (unsigned long)regs->edi);
-
-
+
/* Reflect it back into the guest */
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, error_code);
+ svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
}

/* Reserved bits: [31:14], [12:1] */
@@ -1118,19 +1121,17 @@ static void svm_dr_access (struct vcpu *
}


-static unsigned int check_for_null_selector(struct vmcb_struct *vmcb,
- unsigned int dir, unsigned long *base, unsigned int real)
-
+static void svm_get_prefix_info(struct vmcb_struct *vmcb,
+ unsigned int dir, segment_selector_t **seg, unsigned int *asize)
{
unsigned char inst[MAX_INST_LEN];
- segment_selector_t seg;
int i;

memset(inst, 0, MAX_INST_LEN);
if (inst_copy_from_guest(inst, svm_rip2pointer(vmcb), sizeof(inst))
!= MAX_INST_LEN)
{
- printk("check_for_null_selector: get guest instruction failed\n");
+ printk("%s: get guest instruction failed\n", __func__);
domain_crash_synchronous();
}

@@ -1142,7 +1143,6 @@ static unsigned int check_for_null_selec
case 0xf2: /* REPNZ */
case 0xf0: /* LOCK */
case 0x66: /* data32 */
- case 0x67: /* addr32 */
#if __x86_64__
/* REX prefixes */
case 0x40:
@@ -1164,89 +1164,134 @@ static unsigned int check_for_null_selec
case 0x4f:
#endif
continue;
+ case 0x67: /* addr32 */
+ *asize ^= 48; /* Switch 16/32 bits */
+ continue;
case 0x2e: /* CS */
- seg = vmcb->cs;
+ *seg = &vmcb->cs;
+ continue;
+ case 0x36: /* SS */
+ *seg = &vmcb->ss;
+ continue;
+ case 0x26: /* ES */
+ *seg = &vmcb->es;
+ continue;
+ case 0x64: /* FS */
+ *seg = &vmcb->fs;
+ continue;
+ case 0x65: /* GS */
+ *seg = &vmcb->gs;
+ continue;
+ case 0x3e: /* DS */
+ *seg = &vmcb->ds;
+ continue;
+ default:
break;
- case 0x36: /* SS */
- seg = vmcb->ss;
- break;
- case 0x26: /* ES */
- seg = vmcb->es;
- break;
- case 0x64: /* FS */
- seg = vmcb->fs;
- break;
- case 0x65: /* GS */
- seg = vmcb->gs;
- break;
- case 0x3e: /* DS */
- /* FALLTHROUGH */
- seg = vmcb->ds;
- break;
- default:
- if (dir == IOREQ_READ) /* IN/INS instruction? */
- seg = vmcb->es;
- else
- seg = vmcb->ds;
- }
-
- if (base)
- *base = seg.base;
-
- return seg.attributes.fields.p;
- }
-
- ASSERT(0);
- return 0;
+ }
+ return;
+ }
}


/* Get the address of INS/OUTS instruction */
-static inline unsigned long svm_get_io_address(struct vmcb_struct *vmcb,
- struct cpu_user_regs *regs, unsigned int dir, unsigned int real)
-{
- unsigned long addr = 0;
- unsigned long base = 0;
-
- check_for_null_selector(vmcb, dir, &base, real);
+static inline int svm_get_io_address(struct vcpu *v,
+ struct cpu_user_regs *regs, unsigned int dir,
+ unsigned long *count, unsigned long *addr)
+{
+ unsigned long reg;
+ unsigned int asize = 0;
+ unsigned int isize;
+ int long_mode;
+ ioio_info_t info;
+ segment_selector_t *seg = NULL;
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+ info.bytes = vmcb->exitinfo1;
+
+ /* If we're in long mode, we shouldn't check the segment presence and limit */
+ long_mode = vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA;
+
+ /* d field of cs.attributes is 1 for 32-bit, 0 for 16 or 64 bit.
+ * l field combined with EFER_LMA -> longmode says whether it's 16 or 64 bit.
+ */
+ asize = (long_mode)?64:((vmcb->cs.attributes.fields.db)?32:16);
+
+
+ /* The ins/outs instructions are single byte, so if we have got more
+ * than one byte (+ maybe rep-prefix), we have some prefix so we need
+ * to figure out what it is...
+ */
+ isize = vmcb->exitinfo2 - vmcb->rip;
+
+ if (info.fields.rep)
+ isize --;
+
+ if (isize > 1)
+ {
+ svm_get_prefix_info(vmcb, dir, &seg, &asize);
+ }
+
+ ASSERT(dir == IOREQ_READ || dir == IOREQ_WRITE);

if (dir == IOREQ_WRITE)
{
- if (real)
- addr = (regs->esi & 0xFFFF) + base;
- else
- addr = regs->esi + base;
+ reg = regs->esi;
+ if (!seg) /* If no prefix, used DS. */
+ seg = &vmcb->ds;
}
else
{
- if (real)
- addr = (regs->edi & 0xFFFF) + base;
- else
- addr = regs->edi + base;
- }
-
- return addr;
+ reg = regs->edi;
+ seg = &vmcb->es; /* Note: This is ALWAYS ES. */
+ }
+
+ /* If the segment isn't present, give GP fault! */
+ if (!long_mode && !seg->attributes.fields.p)
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, seg->sel);
+ return 0;
+ }
+
+ if (asize == 16)
+ {
+ *addr = (reg & 0xFFFF);
+ *count = regs->ecx & 0xffff;
+ }
+ else
+ {
+ *addr = reg;
+ *count = regs->ecx;
+ }
+
+ if (!long_mode) {
+ if (*addr > seg->limit)
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, seg->sel);
+ return 0;
+ }
+ else
+ {
+ *addr += seg->base;
+ }
+ }
+
+
+ return 1;
}


static void svm_io_instruction(struct vcpu *v, struct cpu_user_regs *regs)
{
struct mmio_op *mmio_opp;
- unsigned long eip, cs, eflags, cr0;
- unsigned long port;
- unsigned int real, size, dir;
+ unsigned int port;
+ unsigned int size, dir;
ioio_info_t info;
-
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;

ASSERT(vmcb);
mmio_opp = &current->arch.hvm_vcpu.mmio_op;
mmio_opp->instr = INSTR_PIO;
mmio_opp->flags = 0;
-
- eip = vmcb->rip;
- cs = vmcb->cs.sel;
- eflags = vmcb->rflags;

info.bytes = vmcb->exitinfo1;

@@ -1259,27 +1304,34 @@ static void svm_io_instruction(struct vc
else
size = 1;

- cr0 = vmcb->cr0;
- real = (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
-
HVM_DBG_LOG(DBG_LEVEL_IO,
- "svm_io_instruction: port 0x%lx real %d, eip=%lx:%lx, "
- "exit_qualification = %lx",
- (unsigned long) port, real, cs, eip, (unsigned long)info.bytes);
+ "svm_io_instruction: port 0x%x eip=%x:%"PRIx64", "
+ "exit_qualification = %"PRIx64,
+ port, vmcb->cs.sel, vmcb->rip, info.bytes);
+
/* string instruction */
if (info.fields.str)
{
- unsigned long addr, count = 1;
+ unsigned long addr, count;
int sign = regs->eflags & EF_DF ? -1 : 1;

- /* Need the original rip, here. */
- addr = svm_get_io_address(vmcb, regs, dir, real);
+ if (!svm_get_io_address(v, regs, dir, &count, &addr))
+ {
+ /* We failed to get a valid address, so don't do the IO operation -
+ * it would just get worse if we do! Hopefully the guest is handing
+ * gp-faults...
+ */
+ return;
+ }

/* "rep" prefix */
if (info.fields.rep)
{
mmio_opp->flags |= REPZ;
- count = real ? regs->ecx & 0xFFFF : regs->ecx;
+ }
+ else
+ {
+ count = 1;
}

/*
@@ -1368,7 +1420,7 @@ static int svm_set_cr0(unsigned long val
&v->arch.hvm_svm.cpu_state))
{
HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
}

if (test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
@@ -1442,7 +1494,7 @@ static int svm_set_cr0(unsigned long val
*/
if ((value & X86_CR0_PE) == 0) {
if (value & X86_CR0_PG) {
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}

@@ -1689,7 +1741,7 @@ static int mov_to_cr(int gpreg, int cr,
} else {
if (test_bit(SVM_CPU_STATE_LMA_ENABLED,
&v->arch.hvm_svm.cpu_state)) {
- svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
}
clear_bit(SVM_CPU_STATE_PAE_ENABLED, &v->arch.hvm_svm.cpu_state);
}
@@ -1805,7 +1857,8 @@ static int svm_cr_access(struct vcpu *v,
break;

case INSTR_SMSW:
- svm_dump_inst(svm_rip2pointer(vmcb));
+ if (svm_dbg_on)
+ svm_dump_inst(svm_rip2pointer(vmcb));
value = v->arch.hvm_svm.cpu_shadow_cr0;
gpreg = decode_src_reg(prefix, buffer[index+2]);
set_reg(gpreg, value, regs, vmcb);
@@ -1942,9 +1995,25 @@ static inline void svm_vmexit_do_hlt(str
}


-static inline void svm_vmexit_do_mwait(void)
-{
-}
+static void svm_vmexit_do_invd(struct vmcb_struct *vmcb)
+{
+ int inst_len;
+
+ /* Invalidate the cache - we can't really do that safely - maybe we should
+ * WBINVD, but I think it's just fine to completely ignore it - we should
+ * have cache-snooping that solves it anyways. -- Mats P.
+ */
+
+ /* Tell the user that we did this - just in case someone runs some really weird
+ * operating system and wants to know why it's not working as it should...
+ */
+ printk("INVD instruction intercepted - ignored\n");
+
+ inst_len = __get_instruction_length(vmcb, INSTR_INVD, NULL);
+ __update_guest_eip(vmcb, inst_len);
+}
+
+


#ifdef XEN_DEBUGGER
@@ -2006,7 +2075,7 @@ void svm_handle_invlpg(const short invlp
__update_guest_eip(vmcb, inst_len);

/*
- * The address is implicit on this instruction At the moment, we don't
+ * The address is implicit on this instruction. At the moment, we don't
* use ecx (ASID) to identify individual guests pages
*/
g_vaddr = regs->eax;
@@ -2440,7 +2509,6 @@ asmlinkage void svm_vmexit_handler(struc

exit_reason = vmcb->exitcode;
save_svm_cpu_user_regs(v, &regs);
- v->arch.hvm_svm.injecting_event = 0;

vmcb->tlb_control = 1;

@@ -2604,7 +2672,7 @@ asmlinkage void svm_vmexit_handler(struc
if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
domain_pause_for_debugger();
else
- svm_inject_exception(vmcb, TRAP_int3, 0, 0);
+ svm_inject_exception(v, TRAP_int3, 0, 0);
#endif
break;

@@ -2615,7 +2683,6 @@ asmlinkage void svm_vmexit_handler(struc
case VMEXIT_EXCEPTION_GP:
/* This should probably not be trapped in the future */
regs.error_code = vmcb->exitinfo1;
- v->arch.hvm_svm.injecting_event = 1;
svm_do_general_protection_fault(v, &regs);
break;

@@ -2635,9 +2702,8 @@ asmlinkage void svm_vmexit_handler(struc
//printk("PF1\n");
if (!(error = svm_do_page_fault(va, &regs)))
{
- v->arch.hvm_svm.injecting_event = 1;
/* Inject #PG using Interruption-Information Fields */
- svm_inject_exception(vmcb, TRAP_page_fault, 1, regs.error_code);
+ svm_inject_exception(v, TRAP_page_fault, 1, regs.error_code);

v->arch.hvm_svm.cpu_cr2 = va;
vmcb->cr2 = va;
@@ -2654,6 +2720,11 @@ asmlinkage void svm_vmexit_handler(struc

case VMEXIT_INTR:
raise_softirq(SCHEDULE_SOFTIRQ);
+ break;
+
+
+ case VMEXIT_INVD:
+ svm_vmexit_do_invd(vmcb);
break;

case VMEXIT_GDTR_WRITE:
@@ -2845,6 +2916,9 @@ asmlinkage void svm_asid(void)
v->arch.hvm_svm.asid_core = v->arch.hvm_svm.launch_core;
clear_bit( ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags );
}
+
+ /* make sure the HSA is set for the current core */
+ set_hsa_to_guest( &v->arch.hvm_svm );
}

/*
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/svm/vmcb.c Mon May 22 14:13:38 2006 -0600
@@ -36,7 +36,7 @@
#include <xen/kernel.h>
#include <xen/domain_page.h>

-extern struct host_save_area *host_save_area[];
+extern struct svm_percore_globals svm_globals[];
extern int svm_dbg_on;
extern int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current,
int oldcore, int newcore);
@@ -117,16 +117,12 @@ static int construct_vmcb_controls(struc

/* mask off all general 1 intercepts except those listed here */
vmcb->general1_intercepts =
- ~(GENERAL1_INTERCEPT_CR0_SEL_WRITE | GENERAL1_INTERCEPT_VINTR |
- GENERAL1_INTERCEPT_IDTR_READ | GENERAL1_INTERCEPT_IDTR_WRITE |
- GENERAL1_INTERCEPT_GDTR_READ | GENERAL1_INTERCEPT_GDTR_WRITE |
- GENERAL1_INTERCEPT_LDTR_READ | GENERAL1_INTERCEPT_LDTR_WRITE |
- GENERAL1_INTERCEPT_TR_READ | GENERAL1_INTERCEPT_TR_WRITE |
- GENERAL1_INTERCEPT_RDTSC | GENERAL1_INTERCEPT_PUSHF |
- GENERAL1_INTERCEPT_SWINT | GENERAL1_INTERCEPT_POPF |
- GENERAL1_INTERCEPT_IRET | GENERAL1_INTERCEPT_PAUSE |
- GENERAL1_INTERCEPT_TASK_SWITCH
- );
+ GENERAL1_INTERCEPT_INTR | GENERAL1_INTERCEPT_NMI |
+ GENERAL1_INTERCEPT_SMI | GENERAL1_INTERCEPT_INIT |
+ GENERAL1_INTERCEPT_CPUID | GENERAL1_INTERCEPT_INVD |
+ GENERAL1_INTERCEPT_HLT | GENERAL1_INTERCEPT_INVLPG |
+ GENERAL1_INTERCEPT_INVLPGA | GENERAL1_INTERCEPT_IOIO_PROT |
+ GENERAL1_INTERCEPT_MSR_PROT | GENERAL1_INTERCEPT_SHUTDOWN_EVT;

/* turn on the general 2 intercepts */
vmcb->general2_intercepts =
@@ -143,17 +139,20 @@ static int construct_vmcb_controls(struc

/* The following is for I/O and MSR permision map */
iopm = alloc_xenheap_pages(get_order_from_bytes(IOPM_SIZE));
-
- ASSERT(iopm);
- memset(iopm, 0xff, IOPM_SIZE);
- clear_bit(PC_DEBUG_PORT, iopm);
+ if (iopm)
+ {
+ memset(iopm, 0xff, IOPM_SIZE);
+ clear_bit(PC_DEBUG_PORT, iopm);
+ }
msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));
-
- ASSERT(msrpm);
- memset(msrpm, 0xff, MSRPM_SIZE);
+ if (msrpm)
+ memset(msrpm, 0xff, MSRPM_SIZE);

arch_svm->iopm = iopm;
arch_svm->msrpm = msrpm;
+
+ if (! iopm || ! msrpm)
+ return 1;

vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm);
vmcb->msrpm_base_pa = (u64) virt_to_maddr(msrpm);
@@ -421,7 +420,6 @@ void svm_do_launch(struct vcpu *v)

v->arch.schedule_tail = arch_svm_do_resume;

- v->arch.hvm_svm.injecting_event = 0;
v->arch.hvm_svm.saved_irq_vector = -1;

svm_set_guest_time(v, 0);
@@ -435,8 +433,7 @@ void svm_do_launch(struct vcpu *v)

void set_hsa_to_guest( struct arch_svm_struct *arch_svm )
{
- arch_svm->host_save_area = host_save_area[ smp_processor_id() ];
- arch_svm->host_save_pa = (u64)virt_to_maddr( arch_svm->host_save_area );
+ arch_svm->host_save_pa = svm_globals[ smp_processor_id() ].scratch_hsa_pa;
}

/*
@@ -450,9 +447,6 @@ void svm_do_resume(struct vcpu *v)

svm_stts(v);

- /* make sure the HSA is set for the current core */
- set_hsa_to_guest( &v->arch.hvm_svm );
-
/* pick up the elapsed PIT ticks and re-enable pit_timer */
if ( time_info->first_injected ) {
if ( v->domain->arch.hvm_domain.guest_time ) {
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Mon May 22 14:13:38 2006 -0600
@@ -35,6 +35,7 @@
#include <xen/event.h>
#include <xen/kernel.h>
#include <asm/shadow.h>
+#include <xen/keyhandler.h>
#if CONFIG_PAGING_LEVELS >= 3
#include <asm/shadow_64.h>
#endif
@@ -542,6 +543,101 @@ void arch_vmx_do_launch(struct vcpu *v)
reset_stack_and_jump(vmx_asm_do_launch);
}

+
+/* Dump a section of VMCS */
+static void print_section(char *header, uint32_t start,
+ uint32_t end, int incr)
+{
+ uint32_t addr, j;
+ unsigned long val;
+ int code;
+ char *fmt[4] = {"0x%04lx ", "0x%016lx ", "0x%08lx ", "0x%016lx "};
+ char *err[4] = {"------ ", "------------------ ",
+ "---------- ", "------------------ "};
+
+ /* Find width of the field (encoded in bits 14:13 of address) */
+ code = (start>>13)&3;
+
+ if (header)
+ printk("\t %s", header);
+
+ for (addr=start, j=0; addr<=end; addr+=incr, j++) {
+
+ if (!(j&3))
+ printk("\n\t\t0x%08x: ", addr);
+
+ if (!__vmread(addr, &val))
+ printk(fmt[code], val);
+ else
+ printk("%s", err[code]);
+ }
+
+ printk("\n");
+}
+
+/* Dump current VMCS */
+void vmcs_dump_vcpu(void)
+{
+ print_section("16-bit Guest-State Fields", 0x800, 0x80e, 2);
+ print_section("16-bit Host-State Fields", 0xc00, 0xc0c, 2);
+ print_section("64-bit Control Fields", 0x2000, 0x2013, 1);
+ print_section("64-bit Guest-State Fields", 0x2800, 0x2803, 1);
+ print_section("32-bit Control Fields", 0x4000, 0x401c, 2);
+ print_section("32-bit RO Data Fields", 0x4400, 0x440e, 2);
+ print_section("32-bit Guest-State Fields", 0x4800, 0x482a, 2);
+ print_section("32-bit Host-State Fields", 0x4c00, 0x4c00, 2);
+ print_section("Natural 64-bit Control Fields", 0x6000, 0x600e, 2);
+ print_section("64-bit RO Data Fields", 0x6400, 0x640A, 2);
+ print_section("Natural 64-bit Guest-State Fields", 0x6800, 0x6826, 2);
+ print_section("Natural 64-bit Host-State Fields", 0x6c00, 0x6c16, 2);
+}
+
+
+static void vmcs_dump(unsigned char ch)
+{
+ struct domain *d;
+ struct vcpu *v;
+
+ printk("*********** VMCS Areas **************\n");
+ for_each_domain(d) {
+ printk("\n>>> Domain %d <<<\n", d->domain_id);
+ for_each_vcpu(d, v) {
+
+ /*
+ * Presumably, if a domain is not an HVM guest,
+ * the very first CPU will not pass this test
+ */
+ if (!hvm_guest(v)) {
+ printk("\t\tNot HVM guest\n");
+ break;
+ }
+ printk("\tVCPU %d\n", v->vcpu_id);
+
+ if (v != current) {
+ vcpu_pause(v);
+ __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+ }
+
+ vmcs_dump_vcpu();
+
+ if (v != current) {
+ __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
+ vcpu_unpause(v);
+ }
+ }
+ }
+
+ printk("**************************************\n");
+}
+
+static int __init setup_vmcs_dump(void)
+{
+ register_keyhandler('v', vmcs_dump, "dump Intel's VMCS");
+ return 0;
+}
+
+__initcall(setup_vmcs_dump);
+
/*
* Local variables:
* mode: C
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon May 22 14:13:38 2006 -0600
@@ -2082,7 +2082,10 @@ asmlinkage void vmx_vmexit_handler(struc
HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);

if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
- printk("Failed vm entry\n");
+ printk("Failed vm entry (reason 0x%x)\n", exit_reason);
+ printk("*********** VMCS Area **************\n");
+ vmcs_dump_vcpu();
+ printk("**************************************\n");
domain_crash_synchronous();
return;
}
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/mm.c Mon May 22 14:13:38 2006 -0600
@@ -2811,6 +2811,8 @@ long do_update_descriptor(u64 pa, u64 de
return ret;
}

+typedef struct e820entry e820entry_t;
+DEFINE_XEN_GUEST_HANDLE(e820entry_t);

long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
{
@@ -2867,6 +2869,39 @@ long arch_memory_op(int op, XEN_GUEST_HA
put_domain(d);

break;
+ }
+
+ case XENMEM_memory_map:
+ {
+ return -ENOSYS;
+ }
+
+ case XENMEM_machine_memory_map:
+ {
+ struct xen_memory_map memmap;
+ XEN_GUEST_HANDLE(e820entry_t) buffer;
+ int count;
+
+ if ( !IS_PRIV(current->domain) )
+ return -EINVAL;
+
+ if ( copy_from_guest(&memmap, arg, 1) )
+ return -EFAULT;
+ if ( memmap.nr_entries < e820.nr_map + 1 )
+ return -EINVAL;
+
+ buffer = guest_handle_cast(memmap.buffer, e820entry_t);
+
+ count = min((unsigned int)e820.nr_map, memmap.nr_entries);
+ if ( copy_to_guest(buffer, &e820.map[0], count) < 0 )
+ return -EFAULT;
+
+ memmap.nr_entries = count;
+
+ if ( copy_to_guest(arg, &memmap, 1) )
+ return -EFAULT;
+
+ return 0;
}

default:
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/shadow.c Mon May 22 14:13:38 2006 -0600
@@ -347,6 +347,13 @@ alloc_shadow_page(struct domain *d,
d->arch.shadow_page_count++;
if ( PGT_l4_page_table == PGT_root_page_table )
pin = 1;
+#if CONFIG_PAGING_LEVELS == 3 & defined (GUEST_PGENTRY_32)
+ /*
+ * We use PGT_l4_shadow for 2-level paging guests on PAE
+ */
+ if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
+ pin = 1;
+#endif
break;

#if CONFIG_PAGING_LEVELS >= 4
@@ -423,7 +430,8 @@ no_shadow_page:
perfc_value(shadow_l2_pages),
perfc_value(hl2_table_pages),
perfc_value(snapshot_pages));
- BUG(); /* XXX FIXME: try a shadow flush to free up some memory. */
+ /* XXX FIXME: try a shadow flush to free up some memory. */
+ domain_crash_synchronous();

return 0;
}
@@ -2425,6 +2433,17 @@ static void shadow_update_pagetables(str
/*
* arch.shadow_table
*/
+#if CONFIG_PAGING_LEVELS == 3 & defined (GUEST_PGENTRY_32)
+ /*
+ * We use PGT_l4_shadow for 2-level paging guests on PAE
+ */
+ if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
+ {
+ if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_l4_shadow))) )
+ smfn = shadow_l3_table(v, gpfn, gmfn);
+ }
+ else
+#endif
if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) )
{
#if CONFIG_PAGING_LEVELS == 2
@@ -3046,7 +3065,8 @@ static inline unsigned long init_bl2(
if ( unlikely(!(smfn = alloc_shadow_page(d, gpfn, gmfn, PGT_l4_shadow))) )
{
printk("Couldn't alloc an L4 shadow for pfn=%lx mfn=%lx\n", gpfn, gmfn);
- BUG(); /* XXX Deal gracefully with failure. */
+ /* XXX Deal gracefully with failure. */
+ domain_crash_synchronous();
}

spl4e = (l4_pgentry_t *)map_domain_page(smfn);
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/shadow32.c Mon May 22 14:13:38 2006 -0600
@@ -246,7 +246,8 @@ alloc_shadow_page(struct domain *d,
perfc_value(shadow_l2_pages),
perfc_value(hl2_table_pages),
perfc_value(snapshot_pages));
- BUG(); /* XXX FIXME: try a shadow flush to free up some memory. */
+ /* XXX FIXME: try a shadow flush to free up some memory. */
+ domain_crash_synchronous();
}

smfn = page_to_mfn(page);
@@ -983,6 +984,11 @@ alloc_p2m_table(struct domain *d)
else
{
page = alloc_domheap_page(NULL);
+ if (!page)
+ {
+ printk("Alloc p2m table fail\n");
+ domain_crash(d);
+ }

l1tab = map_domain_page(page_to_mfn(page));
memset(l1tab, 0, PAGE_SIZE);
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/shadow_public.c Mon May 22 14:13:38 2006 -0600
@@ -324,6 +324,11 @@ static void alloc_monitor_pagetable(stru

mmfn_info = alloc_domheap_page(NULL);
ASSERT( mmfn_info );
+ if (!mmfn_info)
+ {
+ printk("Fail to allocate monitor pagetable\n");
+ domain_crash(v->domain);
+ }

mmfn = page_to_mfn(mmfn_info);
mpl4e = (l4_pgentry_t *) map_domain_page_global(mmfn);
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c Mon May 22 14:13:38 2006 -0600
@@ -6,7 +6,7 @@
* Copyright (c) 2005 Keir Fraser
*/

-#ifdef __TEST_HARNESS__
+#ifndef __XEN__
#include <stdio.h>
#include <stdint.h>
#include <public/xen.h>
@@ -1127,7 +1127,7 @@ x86_emulate_memop(
return -1;
}

-#ifndef __TEST_HARNESS__
+#ifdef __XEN__

#include <asm/mm.h>
#include <asm/uaccess.h>
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/common/acm_ops.c Mon May 22 14:13:38 2006 -0600
@@ -32,100 +32,94 @@

#ifndef ACM_SECURITY

-long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
+
+long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
return -ENOSYS;
}

+
#else

-enum acm_operation {
- POLICY, /* access to policy interface (early drop) */
- GETPOLICY, /* dump policy cache */
- SETPOLICY, /* set policy cache (controls security) */
- DUMPSTATS, /* dump policy statistics */
- GETSSID, /* retrieve ssidref for domain id (decide inside authorized domains) */
- GETDECISION /* retrieve ACM decision from authorized domains */
-};
-
-int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
+
+int acm_authorize_acm_ops(struct domain *d)
{
/* currently, policy management functions are restricted to privileged domains */
if (!IS_PRIV(d))
return -EPERM;
-
return 0;
}

-long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
-{
- long ret = 0;
- struct acm_op curop, *op = &curop;
-
- if (acm_authorize_acm_ops(current->domain, POLICY))
+
+long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+ long rc = -EFAULT;
+
+ if (acm_authorize_acm_ops(current->domain))
return -EPERM;

- if (copy_from_guest(op, u_acm_op, 1))
- return -EFAULT;
-
- if (op->interface_version != ACM_INTERFACE_VERSION)
- return -EACCES;
-
- switch (op->cmd)
+ switch ( cmd )
{
- case ACM_SETPOLICY:
- {
- ret = acm_authorize_acm_ops(current->domain, SETPOLICY);
- if (!ret)
- ret = acm_set_policy(op->u.setpolicy.pushcache,
- op->u.setpolicy.pushcache_size, 1);
- }
- break;
-
- case ACM_GETPOLICY:
- {
- ret = acm_authorize_acm_ops(current->domain, GETPOLICY);
- if (!ret)
- ret = acm_get_policy(op->u.getpolicy.pullcache,
- op->u.getpolicy.pullcache_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
- }
- break;
-
- case ACM_DUMPSTATS:
- {
- ret = acm_authorize_acm_ops(current->domain, DUMPSTATS);
- if (!ret)
- ret = acm_dump_statistics(op->u.dumpstats.pullcache,
- op->u.dumpstats.pullcache_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
- }
- break;
-
- case ACM_GETSSID:
- {
+
+ case ACMOP_setpolicy: {
+ struct acm_setpolicy setpolicy;
+ if (copy_from_guest(&setpolicy, arg, 1) != 0)
+ return -EFAULT;
+ if (setpolicy.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ rc = acm_set_policy(setpolicy.pushcache,
+ setpolicy.pushcache_size, 1);
+ break;
+ }
+
+ case ACMOP_getpolicy: {
+ struct acm_getpolicy getpolicy;
+ if (copy_from_guest(&getpolicy, arg, 1) != 0)
+ return -EFAULT;
+ if (getpolicy.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ rc = acm_get_policy(getpolicy.pullcache,
+ getpolicy.pullcache_size);
+ break;
+ }
+
+ case ACMOP_dumpstats: {
+ struct acm_dumpstats dumpstats;
+ if (copy_from_guest(&dumpstats, arg, 1) != 0)
+ return -EFAULT;
+ if (dumpstats.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ rc = acm_dump_statistics(dumpstats.pullcache,
+ dumpstats.pullcache_size);
+ break;
+ }
+
+ case ACMOP_getssid: {
+ struct acm_getssid getssid;
ssidref_t ssidref;

- ret = acm_authorize_acm_ops(current->domain, GETSSID);
- if (ret)
- break;
-
- if (op->u.getssid.get_ssid_by == SSIDREF)
- ssidref = op->u.getssid.id.ssidref;
- else if (op->u.getssid.get_ssid_by == DOMAINID)
- {
- struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
- if (!subj)
- {
- ret = -ESRCH; /* domain not found */
- break;
- }
- if (subj->ssid == NULL)
- {
- put_domain(subj);
- ret = -ESRCH;
+ if (copy_from_guest(&getssid, arg, 1) != 0)
+ return -EFAULT;
+ if (getssid.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ if (getssid.get_ssid_by == SSIDREF)
+ ssidref = getssid.id.ssidref;
+ else if (getssid.get_ssid_by == DOMAINID)
+ {
+ struct domain *subj = find_domain_by_id(getssid.id.domainid);
+ if (!subj)
+ {
+ rc = -ESRCH; /* domain not found */
+ break;
+ }
+ if (subj->ssid == NULL)
+ {
+ put_domain(subj);
+ rc = -ESRCH;
break;
}
ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -133,39 +127,36 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
- break;
- }
- ret = acm_get_ssid(ssidref,
- op->u.getssid.ssidbuf,
- op->u.getssid.ssidbuf_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
- }
- break;
-
- case ACM_GETDECISION:
- {
+ rc = -ESRCH;
+ break;
+ }
+ rc = acm_get_ssid(ssidref, getssid.ssidbuf, getssid.ssidbuf_size);
+ break;
+ }
+
+ case ACMOP_getdecision: {
+ struct acm_getdecision getdecision;
ssidref_t ssidref1, ssidref2;

- ret = acm_authorize_acm_ops(current->domain, GETDECISION);
- if (ret)
- break;
-
- if (op->u.getdecision.get_decision_by1 == SSIDREF)
- ssidref1 = op->u.getdecision.id1.ssidref;
- else if (op->u.getdecision.get_decision_by1 == DOMAINID)
- {
- struct domain *subj = find_domain_by_id(op->u.getdecision.id1.domainid);
- if (!subj)
- {
- ret = -ESRCH; /* domain not found */
- break;
- }
- if (subj->ssid == NULL)
- {
- put_domain(subj);
- ret = -ESRCH;
+ if (copy_from_guest(&getdecision, arg, 1) != 0)
+ return -EFAULT;
+ if (getdecision.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ if (getdecision.get_decision_by1 == SSIDREF)
+ ssidref1 = getdecision.id1.ssidref;
+ else if (getdecision.get_decision_by1 == DOMAINID)
+ {
+ struct domain *subj = find_domain_by_id(getdecision.id1.domainid);
+ if (!subj)
+ {
+ rc = -ESRCH; /* domain not found */
+ break;
+ }
+ if (subj->ssid == NULL)
+ {
+ put_domain(subj);
+ rc = -ESRCH;
break;
}
ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -173,23 +164,23 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
- break;
- }
- if (op->u.getdecision.get_decision_by2 == SSIDREF)
- ssidref2 = op->u.getdecision.id2.ssidref;
- else if (op->u.getdecision.get_decision_by2 == DOMAINID)
- {
- struct domain *subj = find_domain_by_id(op->u.getdecision.id2.domainid);
- if (!subj)
- {
- ret = -ESRCH; /* domain not found */
+ rc = -ESRCH;
+ break;
+ }
+ if (getdecision.get_decision_by2 == SSIDREF)
+ ssidref2 = getdecision.id2.ssidref;
+ else if (getdecision.get_decision_by2 == DOMAINID)
+ {
+ struct domain *subj = find_domain_by_id(getdecision.id2.domainid);
+ if (!subj)
+ {
+ rc = -ESRCH; /* domain not found */
break;;
}
if (subj->ssid == NULL)
{
put_domain(subj);
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -197,34 +188,35 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
- break;
- }
- ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
-
- if (ret == ACM_ACCESS_PERMITTED)
- {
- op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
- ret = 0;
- }
- else if (ret == ACM_ACCESS_DENIED)
- {
- op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
- ret = 0;
- }
- else
- ret = -ESRCH;
-
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
- }
- break;
+ rc = -ESRCH;
+ break;
+ }
+ rc = acm_get_decision(ssidref1, ssidref2, getdecision.hook);
+
+ if (rc == ACM_ACCESS_PERMITTED)
+ {
+ getdecision.acm_decision = ACM_ACCESS_PERMITTED;
+ rc = 0;
+ }
+ else if (rc == ACM_ACCESS_DENIED)
+ {
+ getdecision.acm_decision = ACM_ACCESS_DENIED;
+ rc = 0;
+ }
+ else
+ rc = -ESRCH;
+
+ if ( (rc == 0) && (copy_to_guest(arg, &getdecision, 1) != 0) )
+ rc = -EFAULT;
+ break;
+ }

default:
- ret = -ESRCH;
- }
-
- return ret;
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
}

#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/common/elf.c
--- a/xen/common/elf.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/common/elf.c Mon May 22 14:13:38 2006 -0600
@@ -23,10 +23,10 @@ int parseelfimage(struct domain_setup_in
Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
Elf_Phdr *phdr;
Elf_Shdr *shdr;
- unsigned long kernstart = ~0UL, kernend=0UL;
+ unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
char *shstrtab, *guestinfo=NULL, *p;
char *elfbase = (char *)dsi->image_addr;
- int h;
+ int h, virt_base_defined, elf_pa_off_defined;

if ( !elf_sanity_check(ehdr) )
return -EINVAL;
@@ -81,44 +81,68 @@ int parseelfimage(struct domain_setup_in

dsi->xen_section_string = guestinfo;

- for ( h = 0; h < ehdr->e_phnum; h++ )
+ if ( guestinfo == NULL )
+ guestinfo = "";
+
+ /* Initial guess for virt_base is 0 if it is not explicitly defined. */
+ p = strstr(guestinfo, "VIRT_BASE=");
+ virt_base_defined = (p != NULL);
+ virt_base = virt_base_defined ? simple_strtoul(p+10, &p, 0) : 0;
+
+ /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
+ p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
+ elf_pa_off_defined = (p != NULL);
+ elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
+
+ if ( elf_pa_off_defined && !virt_base_defined )
+ goto bad_image;
+
+ for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
- if ( phdr->p_paddr < kernstart )
- kernstart = phdr->p_paddr;
- if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
- kernend = phdr->p_paddr + phdr->p_memsz;
- }
+ vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+ if ( (vaddr + phdr->p_memsz) < vaddr )
+ goto bad_image;
+ if ( vaddr < kernstart )
+ kernstart = vaddr;
+ if ( (vaddr + phdr->p_memsz) > kernend )
+ kernend = vaddr + phdr->p_memsz;
+ }
+
+ /*
+ * Legacy compatibility and images with no __xen_guest section: assume
+ * header addresses are virtual addresses, and that guest memory should be
+ * mapped starting at kernel load address.
+ */
+ dsi->v_start = virt_base_defined ? virt_base : kernstart;
+ dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start;
+
+ dsi->v_kernentry = ehdr->e_entry;
+ if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
+ dsi->v_kernentry = simple_strtoul(p+11, &p, 0);

if ( (kernstart > kernend) ||
- (ehdr->e_entry < kernstart) ||
- (ehdr->e_entry > kernend) )
- {
- printk("Malformed ELF image.\n");
- return -EINVAL;
- }
-
- dsi->v_start = kernstart;
-
- if ( guestinfo != NULL )
- {
- if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
- dsi->v_start = simple_strtoul(p+10, &p, 0);
-
- if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
+ (dsi->v_kernentry < kernstart) ||
+ (dsi->v_kernentry > kernend) ||
+ (dsi->v_start > kernstart) )
+ goto bad_image;
+
+ if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
dsi->load_symtab = 1;
- }

dsi->v_kernstart = kernstart;
dsi->v_kernend = kernend;
- dsi->v_kernentry = ehdr->e_entry;
dsi->v_end = dsi->v_kernend;

loadelfsymtab(dsi, 0);

return 0;
+
+ bad_image:
+ printk("Malformed ELF image.\n");
+ return -EINVAL;
}

int loadelfimage(struct domain_setup_info *dsi)
@@ -126,18 +150,19 @@ int loadelfimage(struct domain_setup_inf
char *elfbase = (char *)dsi->image_addr;
Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
Elf_Phdr *phdr;
+ unsigned long vaddr;
int h;

- for ( h = 0; h < ehdr->e_phnum; h++ )
+ for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
+ vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
if ( phdr->p_filesz != 0 )
- memcpy((char *)phdr->p_paddr, elfbase + phdr->p_offset,
- phdr->p_filesz);
+ memcpy((char *)vaddr, elfbase + phdr->p_offset, phdr->p_filesz);
if ( phdr->p_memsz > phdr->p_filesz )
- memset((char *)phdr->p_paddr + phdr->p_filesz, 0,
+ memset((char *)vaddr + phdr->p_filesz, 0,
phdr->p_memsz - phdr->p_filesz);
}

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/common/event_channel.c
--- a/xen/common/event_channel.c Mon May 22 08:53:26 2006 -0600
+++ b/xen/common/event_channel.c Mon May 22 14:13:38 2006 -0600
@@ -59,6 +59,9 @@ static int virq_is_global(int virq)
case VIRQ_DEBUG:
case VIRQ_XENOPROF:
rc = 0;
+ break;
+ case VIRQ_ARCH_0 ... VIRQ_ARCH_7:
+ rc = arch_virq_is_global(virq);
break;
default:
rc = 1;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-ia64/event.h
--- a/xen/include/asm-ia64/event.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-ia64/event.h Mon May 22 14:13:38 2006 -0600
@@ -37,4 +37,21 @@ static inline void evtchn_notify(struct
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

+static inline int arch_virq_is_global(int virq)
+{
+ int rc;
+
+ switch ( virq )
+ {
+ case VIRQ_ITC:
+ rc = 0;
+ break;
+ default:
+ rc = 1;
+ break;
+ }
+
+ return rc;
+}
+
#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-x86/event.h
--- a/xen/include/asm-x86/event.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-x86/event.h Mon May 22 14:13:38 2006 -0600
@@ -31,4 +31,10 @@ static inline void evtchn_notify(struct
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

+/* No arch specific virq definition now. Default to global. */
+static inline int arch_virq_is_global(int virq)
+{
+ return 1;
+}
+
#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-x86/hvm/svm/svm.h Mon May 22 14:13:38 2006 -0600
@@ -70,6 +70,14 @@ struct asid_pool {
u32 asid[ASID_MAX];
};

+struct svm_percore_globals {
+ void *hsa;
+ u64 hsa_pa;
+ void *scratch_hsa;
+ u64 scratch_hsa_pa;
+ struct asid_pool ASIDpool;
+};
+
#define SVM_REG_EAX (0)
#define SVM_REG_ECX (1)
#define SVM_REG_EDX (2)
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h Mon May 22 14:13:38 2006 -0600
@@ -440,7 +440,6 @@ struct arch_svm_struct {
u32 *iopm;
u32 *msrpm;
u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
- int injecting_event;
int saved_irq_vector;
u32 launch_core;
u32 asid_core;
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Mon May 22 14:13:38 2006 -0600
@@ -26,7 +26,7 @@

extern int start_vmx(void);
extern void stop_vmx(void);
-
+extern void vmcs_dump_vcpu(void);
void vmx_final_setup_guest(struct vcpu *v);

void vmx_enter_scheduler(void);
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/asm-x86/hvm/vpic.h
--- a/xen/include/asm-x86/hvm/vpic.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/asm-x86/hvm/vpic.h Mon May 22 14:13:38 2006 -0600
@@ -60,6 +60,7 @@ struct hvm_virpic {
/* IOAPIC callback support */
void (*alt_irq_func)(void *opaque, int irq_num, int level);
void *alt_irq_opaque;
+ spinlock_t lock;
};


@@ -72,7 +73,7 @@ void pic_set_alt_irq_func(struct hvm_vir
void (*alt_irq_func)(void *, int, int),
void *alt_irq_opaque);
int pic_read_irq(struct hvm_virpic *s);
-void pic_update_irq(struct hvm_virpic *s);
+void pic_update_irq(struct hvm_virpic *s); /* Caller must hold s->lock */
uint32_t pic_intack_read(struct hvm_virpic *s);
void register_pic_io_hook (void);
int cpu_get_pic_interrupt(struct vcpu *v, int *type);
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/acm_ops.h Mon May 22 14:13:38 2006 -0600
@@ -2,7 +2,7 @@
* acm_ops.h: Xen access control module hypervisor commands
*
* Reiner Sailer <sailer@watson.ibm.com>
- * Copyright (c) 2005, International Business Machines Corporation.
+ * Copyright (c) 2005,2006 International Business Machines Corporation.
*/

#ifndef __XEN_PUBLIC_ACM_OPS_H__
@@ -17,36 +17,50 @@
* This makes sure that old versions of acm tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
-#define ACM_INTERFACE_VERSION 0xAAAA0006
+#define ACM_INTERFACE_VERSION 0xAAAA0007

/************************************************************************/

-#define ACM_SETPOLICY 4
+/*
+ * Prototype for this hypercall is:
+ * int acm_op(int cmd, void *args)
+ * @cmd == ACMOP_??? (access control module operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+
+#define ACMOP_setpolicy 1
struct acm_setpolicy {
- /* OUT variables */
+ /* IN */
+ uint32_t interface_version;
void *pushcache;
uint32_t pushcache_size;
};


-#define ACM_GETPOLICY 5
+#define ACMOP_getpolicy 2
struct acm_getpolicy {
- /* OUT variables */
+ /* IN */
+ uint32_t interface_version;
void *pullcache;
uint32_t pullcache_size;
};


-#define ACM_DUMPSTATS 6
+#define ACMOP_dumpstats 3
struct acm_dumpstats {
+ /* IN */
+ uint32_t interface_version;
void *pullcache;
uint32_t pullcache_size;
};


-#define ACM_GETSSID 7
+#define ACMOP_getssid 4
enum get_type {UNSET=0, SSIDREF, DOMAINID};
struct acm_getssid {
+ /* IN */
+ uint32_t interface_version;
enum get_type get_ssid_by;
union {
domaintype_t domainid;
@@ -56,9 +70,11 @@ struct acm_getssid {
uint32_t ssidbuf_size;
};

-#define ACM_GETDECISION 8
+#define ACMOP_getdecision 5
struct acm_getdecision {
- enum get_type get_decision_by1; /* in */
+ /* IN */
+ uint32_t interface_version;
+ enum get_type get_decision_by1;
enum get_type get_decision_by2;
union {
domaintype_t domainid;
@@ -69,23 +85,11 @@ struct acm_getdecision {
ssidref_t ssidref;
} id2;
enum acm_hook_type hook;
- int acm_decision; /* out */
+ /* OUT */
+ int acm_decision;
};

-typedef struct acm_op {
- uint32_t cmd;
- uint32_t interface_version; /* ACM_INTERFACE_VERSION */
- union {
- struct acm_setpolicy setpolicy;
- struct acm_getpolicy getpolicy;
- struct acm_dumpstats dumpstats;
- struct acm_getssid getssid;
- struct acm_getdecision getdecision;
- } u;
-} acm_op_t;
-DEFINE_XEN_GUEST_HANDLE(acm_op_t);
-
-#endif /* __XEN_PUBLIC_ACM_OPS_H__ */
+#endif /* __XEN_PUBLIC_ACM_OPS_H__ */

/*
* Local variables:
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/arch-ia64.h Mon May 22 14:13:38 2006 -0600
@@ -38,15 +38,17 @@ DEFINE_XEN_GUEST_HANDLE(void);
#ifndef __ASSEMBLY__

#define MAX_NR_SECTION 32 /* at most 32 memory holes */
-typedef struct {
+struct mm_section {
unsigned long start; /* start of memory hole */
unsigned long end; /* end of memory hole */
-} mm_section_t;
-
-typedef struct {
+};
+typedef struct mm_section mm_section_t;
+
+struct pmt_entry {
unsigned long mfn : 56;
unsigned long type: 8;
-} pmt_entry_t;
+};
+typedef struct pmt_entry pmt_entry_t;

#define GPFN_MEM (0UL << 56) /* Guest pfn is normal mem */
#define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */
@@ -93,10 +95,11 @@ typedef struct {
* NB. This may become a 64-bit count with no shift. If this happens then the
* structure size will still be 8 bytes, so no other alignments will change.
*/
-typedef struct {
+struct tsc_timestamp {
unsigned int tsc_bits; /* 0: 32 bits read from the CPU's TSC. */
unsigned int tsc_bitshift; /* 4: 'tsc_bits' uses N:N+31 of TSC. */
-} tsc_timestamp_t; /* 8 bytes */
+}; /* 8 bytes */
+typedef struct tsc_timestamp tsc_timestamp_t;

struct pt_fpreg {
union {
@@ -105,7 +108,7 @@ struct pt_fpreg {
} u;
};

-typedef struct cpu_user_regs{
+struct cpu_user_regs {
/* The following registers are saved by SAVE_MIN: */
unsigned long b6; /* scratch */
unsigned long b7; /* scratch */
@@ -179,9 +182,10 @@ typedef struct cpu_user_regs{
unsigned long eml_unat; /* used for emulating instruction */
unsigned long rfi_pfs; /* used for elulating rfi */

-}cpu_user_regs_t;
-
-typedef union {
+};
+typedef struct cpu_user_regs cpu_user_regs_t;
+
+union vac {
unsigned long value;
struct {
int a_int:1;
@@ -193,9 +197,10 @@ typedef union {
int a_bsw:1;
long reserved:57;
};
-} vac_t;
-
-typedef union {
+};
+typedef union vac vac_t;
+
+union vdc {
unsigned long value;
struct {
int d_vmsw:1;
@@ -206,11 +211,12 @@ typedef union {
int d_itm:1;
long reserved:58;
};
-} vdc_t;
-
-typedef struct {
- vac_t vac;
- vdc_t vdc;
+};
+typedef union vdc vdc_t;
+
+struct mapped_regs {
+ union vac vac;
+ union vdc vdc;
unsigned long virt_env_vaddr;
unsigned long reserved1[29];
unsigned long vhpi;
@@ -290,28 +296,32 @@ typedef struct {
unsigned long reserved6[3456];
unsigned long vmm_avail[128];
unsigned long reserved7[4096];
-} mapped_regs_t;
-
-typedef struct {
-} arch_vcpu_info_t;
+};
+typedef struct mapped_regs mapped_regs_t;
+
+struct arch_vcpu_info {
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;

typedef mapped_regs_t vpd_t;

-typedef struct {
+struct arch_shared_info {
unsigned int flags;
unsigned long start_info_pfn;

/* Interrupt vector for event channel. */
int evtchn_vector;
-} arch_shared_info_t;
-
-typedef struct {
+};
+typedef struct arch_shared_info arch_shared_info_t;
+
+struct arch_initrd_info {
unsigned long start;
unsigned long size;
-} arch_initrd_info_t;
+};
+typedef struct arch_initrd_info arch_initrd_info_t;

#define IA64_COMMAND_LINE_SIZE 512
-typedef struct vcpu_guest_context {
+struct vcpu_guest_context {
#define VGCF_FPU_VALID (1<<0)
#define VGCF_VMX_GUEST (1<<1)
#define VGCF_IN_KERNEL (1<<2)
@@ -321,12 +331,13 @@ typedef struct vcpu_guest_context {
unsigned long sys_pgnr; /* System pages out of domain memory */
unsigned long vm_assist; /* VMASST_TYPE_* bitmap, now none on IPF */

- cpu_user_regs_t regs;
- mapped_regs_t *privregs;
- arch_shared_info_t shared;
- arch_initrd_info_t initrd;
+ struct cpu_user_regs regs;
+ struct mapped_regs *privregs;
+ struct arch_shared_info shared;
+ struct arch_initrd_info initrd;
char cmdline[IA64_COMMAND_LINE_SIZE];
-} vcpu_guest_context_t;
+};
+typedef struct vcpu_guest_context vcpu_guest_context_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

// dom0 vp op
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/arch-x86_32.h Mon May 22 14:13:38 2006 -0600
@@ -95,15 +95,16 @@ DEFINE_XEN_GUEST_HANDLE(void);
#define TI_GET_IF(_ti) ((_ti)->flags & 4)
#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
#define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2))
-typedef struct trap_info {
+struct trap_info {
uint8_t vector; /* exception vector */
uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */
uint16_t cs; /* code selector */
unsigned long address; /* code offset */
-} trap_info_t;
+};
+typedef struct trap_info trap_info_t;
DEFINE_XEN_GUEST_HANDLE(trap_info_t);

-typedef struct cpu_user_regs {
+struct cpu_user_regs {
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
@@ -124,7 +125,8 @@ typedef struct cpu_user_regs {
uint16_t ds, _pad3;
uint16_t fs, _pad4;
uint16_t gs, _pad5;
-} cpu_user_regs_t;
+};
+typedef struct cpu_user_regs cpu_user_regs_t;
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);

typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
@@ -133,14 +135,14 @@ typedef uint64_t tsc_timestamp_t; /* RDT
* The following is all CPU context. Note that the fpu_ctxt block is filled
* in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
*/
-typedef struct vcpu_guest_context {
+struct vcpu_guest_context {
/* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */
#define VGCF_I387_VALID (1<<0)
#define VGCF_HVM_GUEST (1<<1)
#define VGCF_IN_KERNEL (1<<2)
unsigned long flags; /* VGCF_* flags */
- cpu_user_regs_t user_regs; /* User-level CPU registers */
+ struct cpu_user_regs user_regs; /* User-level CPU registers */
struct trap_info trap_ctxt[256]; /* Virtual IDT */
unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */
unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
@@ -152,25 +154,29 @@ typedef struct vcpu_guest_context {
unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */
unsigned long failsafe_callback_eip;
unsigned long vm_assist; /* VMASST_TYPE_* bitmap */
-} vcpu_guest_context_t;
+};
+typedef struct vcpu_guest_context vcpu_guest_context_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

-typedef struct arch_shared_info {
+struct arch_shared_info {
unsigned long max_pfn; /* max pfn that appears in table */
/* Frame containing list of mfns containing list of mfns containing p2m. */
unsigned long pfn_to_mfn_frame_list_list;
unsigned long nmi_reason;
-} arch_shared_info_t;
-
-typedef struct {
+};
+typedef struct arch_shared_info arch_shared_info_t;
+
+struct arch_vcpu_info {
unsigned long cr2;
unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
-} arch_vcpu_info_t;
-
-typedef struct {
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;
+
+struct xen_callback {
unsigned long cs;
unsigned long eip;
-} xen_callback_t;
+};
+typedef struct xen_callback xen_callback_t;

#endif /* !__ASSEMBLY__ */

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/arch-x86_64.h Mon May 22 14:13:38 2006 -0600
@@ -150,12 +150,13 @@ struct iret_context {
#define TI_GET_IF(_ti) ((_ti)->flags & 4)
#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
#define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2))
-typedef struct trap_info {
+struct trap_info {
uint8_t vector; /* exception vector */
uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */
uint16_t cs; /* code selector */
unsigned long address; /* code offset */
-} trap_info_t;
+};
+typedef struct trap_info trap_info_t;
DEFINE_XEN_GUEST_HANDLE(trap_info_t);

#ifdef __GNUC__
@@ -166,7 +167,7 @@ DEFINE_XEN_GUEST_HANDLE(trap_info_t);
#define __DECL_REG(name) uint64_t r ## name
#endif

-typedef struct cpu_user_regs {
+struct cpu_user_regs {
uint64_t r15;
uint64_t r14;
uint64_t r13;
@@ -195,7 +196,8 @@ typedef struct cpu_user_regs {
uint16_t ds, _pad4[3];
uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */
uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
-} cpu_user_regs_t;
+};
+typedef struct cpu_user_regs cpu_user_regs_t;
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);

#undef __DECL_REG
@@ -206,14 +208,14 @@ typedef uint64_t tsc_timestamp_t; /* RDT
* The following is all CPU context. Note that the fpu_ctxt block is filled
* in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
*/
-typedef struct vcpu_guest_context {
+struct vcpu_guest_context {
/* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */
#define VGCF_I387_VALID (1<<0)
#define VGCF_HVM_GUEST (1<<1)
#define VGCF_IN_KERNEL (1<<2)
unsigned long flags; /* VGCF_* flags */
- cpu_user_regs_t user_regs; /* User-level CPU registers */
+ struct cpu_user_regs user_regs; /* User-level CPU registers */
struct trap_info trap_ctxt[256]; /* Virtual IDT */
unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */
unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
@@ -228,20 +230,23 @@ typedef struct vcpu_guest_context {
uint64_t fs_base;
uint64_t gs_base_kernel;
uint64_t gs_base_user;
-} vcpu_guest_context_t;
+};
+typedef struct vcpu_guest_context vcpu_guest_context_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);

-typedef struct arch_shared_info {
+struct arch_shared_info {
unsigned long max_pfn; /* max pfn that appears in table */
/* Frame containing list of mfns containing list of mfns containing p2m. */
unsigned long pfn_to_mfn_frame_list_list;
unsigned long nmi_reason;
-} arch_shared_info_t;
-
-typedef struct {
+};
+typedef struct arch_shared_info arch_shared_info_t;
+
+struct arch_vcpu_info {
unsigned long cr2;
unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
-} arch_vcpu_info_t;
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;

typedef unsigned long xen_callback_t;

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/callback.h
--- a/xen/include/public/callback.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/callback.h Mon May 22 14:13:38 2006 -0600
@@ -32,10 +32,11 @@
* Register a callback.
*/
#define CALLBACKOP_register 0
-typedef struct callback_register {
+struct callback_register {
int type;
xen_callback_t address;
-} callback_register_t;
+};
+typedef struct callback_register callback_register_t;
DEFINE_XEN_GUEST_HANDLE(callback_register_t);

/*
@@ -45,9 +46,10 @@ DEFINE_XEN_GUEST_HANDLE(callback_registe
* you attempt to unregister such a callback.
*/
#define CALLBACKOP_unregister 1
-typedef struct callback_unregister {
+struct callback_unregister {
int type;
-} callback_unregister_t;
+};
+typedef struct callback_unregister callback_unregister_t;
DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);

#endif /* __XEN_PUBLIC_CALLBACK_H__ */
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/dom0_ops.h Mon May 22 14:13:38 2006 -0600
@@ -24,14 +24,15 @@
/************************************************************************/

#define DOM0_GETMEMLIST 2
-typedef struct dom0_getmemlist {
+struct dom0_getmemlist {
/* IN variables. */
domid_t domain;
unsigned long max_pfns;
XEN_GUEST_HANDLE(ulong) buffer;
/* OUT variables. */
unsigned long num_pfns;
-} dom0_getmemlist_t;
+};
+typedef struct dom0_getmemlist dom0_getmemlist_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getmemlist_t);

#define DOM0_SCHEDCTL 6
@@ -45,39 +46,43 @@ DEFINE_XEN_GUEST_HANDLE(dom0_adjustdom_t
DEFINE_XEN_GUEST_HANDLE(dom0_adjustdom_t);

#define DOM0_CREATEDOMAIN 8
-typedef struct dom0_createdomain {
+struct dom0_createdomain {
/* IN parameters */
uint32_t ssidref;
xen_domain_handle_t handle;
/* IN/OUT parameters. */
/* Identifier for new domain (auto-allocate if zero is specified). */
domid_t domain;
-} dom0_createdomain_t;
+};
+typedef struct dom0_createdomain dom0_createdomain_t;
DEFINE_XEN_GUEST_HANDLE(dom0_createdomain_t);

#define DOM0_DESTROYDOMAIN 9
-typedef struct dom0_destroydomain {
- /* IN variables. */
- domid_t domain;
-} dom0_destroydomain_t;
+struct dom0_destroydomain {
+ /* IN variables. */
+ domid_t domain;
+};
+typedef struct dom0_destroydomain dom0_destroydomain_t;
DEFINE_XEN_GUEST_HANDLE(dom0_destroydomain_t);

#define DOM0_PAUSEDOMAIN 10
-typedef struct dom0_pausedomain {
+struct dom0_pausedomain {
/* IN parameters. */
domid_t domain;
-} dom0_pausedomain_t;
+};
+typedef struct dom0_pausedomain dom0_pausedomain_t;
DEFINE_XEN_GUEST_HANDLE(dom0_pausedomain_t);

#define DOM0_UNPAUSEDOMAIN 11
-typedef struct dom0_unpausedomain {
+struct dom0_unpausedomain {
/* IN parameters. */
domid_t domain;
-} dom0_unpausedomain_t;
+};
+typedef struct dom0_unpausedomain dom0_unpausedomain_t;
DEFINE_XEN_GUEST_HANDLE(dom0_unpausedomain_t);

#define DOM0_GETDOMAININFO 12
-typedef struct dom0_getdomaininfo {
+struct dom0_getdomaininfo {
/* IN variables. */
domid_t domain; /* NB. IN/OUT variable. */
/* OUT variables. */
@@ -99,21 +104,23 @@ typedef struct dom0_getdomaininfo {
uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
uint32_t ssidref;
xen_domain_handle_t handle;
-} dom0_getdomaininfo_t;
+};
+typedef struct dom0_getdomaininfo dom0_getdomaininfo_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfo_t);

#define DOM0_SETVCPUCONTEXT 13
-typedef struct dom0_setvcpucontext {
+struct dom0_setvcpucontext {
/* IN variables. */
domid_t domain;
uint32_t vcpu;
/* IN/OUT parameters */
XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt;
-} dom0_setvcpucontext_t;
+};
+typedef struct dom0_setvcpucontext dom0_setvcpucontext_t;
DEFINE_XEN_GUEST_HANDLE(dom0_setvcpucontext_t);

#define DOM0_MSR 15
-typedef struct dom0_msr {
+struct dom0_msr {
/* IN variables. */
uint32_t write;
cpumap_t cpu_mask;
@@ -123,7 +130,8 @@ typedef struct dom0_msr {
/* OUT variables. */
uint32_t out1;
uint32_t out2;
-} dom0_msr_t;
+};
+typedef struct dom0_msr dom0_msr_t;
DEFINE_XEN_GUEST_HANDLE(dom0_msr_t);

/*
@@ -131,12 +139,13 @@ DEFINE_XEN_GUEST_HANDLE(dom0_msr_t);
* 1 January, 1970 if the current system time was <system_time>.
*/
#define DOM0_SETTIME 17
-typedef struct dom0_settime {
+struct dom0_settime {
/* IN variables. */
uint32_t secs;
uint32_t nsecs;
uint64_t system_time;
-} dom0_settime_t;
+};
+typedef struct dom0_settime dom0_settime_t;
DEFINE_XEN_GUEST_HANDLE(dom0_settime_t);

#define DOM0_GETPAGEFRAMEINFO 18
@@ -151,44 +160,47 @@ DEFINE_XEN_GUEST_HANDLE(dom0_settime_t);
#define LTAB_MASK XTAB
#define LTABTYPE_MASK (0x7<<LTAB_SHIFT)

-typedef struct dom0_getpageframeinfo {
+struct dom0_getpageframeinfo {
/* IN variables. */
unsigned long mfn; /* Machine page frame number to query. */
domid_t domain; /* To which domain does the frame belong? */
/* OUT variables. */
/* Is the page PINNED to a type? */
uint32_t type; /* see above type defs */
-} dom0_getpageframeinfo_t;
+};
+typedef struct dom0_getpageframeinfo dom0_getpageframeinfo_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo_t);

/*
* Read console content from Xen buffer ring.
*/
#define DOM0_READCONSOLE 19
-typedef struct dom0_readconsole {
+struct dom0_readconsole {
/* IN variables. */
uint32_t clear; /* Non-zero -> clear after reading. */
/* IN/OUT variables. */
XEN_GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
uint32_t count; /* In: Buffer size; Out: Used buffer size */
-} dom0_readconsole_t;
+};
+typedef struct dom0_readconsole dom0_readconsole_t;
DEFINE_XEN_GUEST_HANDLE(dom0_readconsole_t);

/*
* Set which physical cpus a vcpu can execute on.
*/
#define DOM0_SETVCPUAFFINITY 20
-typedef struct dom0_setvcpuaffinity {
+struct dom0_setvcpuaffinity {
/* IN variables. */
domid_t domain;
uint32_t vcpu;
cpumap_t cpumap;
-} dom0_setvcpuaffinity_t;
+};
+typedef struct dom0_setvcpuaffinity dom0_setvcpuaffinity_t;
DEFINE_XEN_GUEST_HANDLE(dom0_setvcpuaffinity_t);

/* Get trace buffers machine base address */
#define DOM0_TBUFCONTROL 21
-typedef struct dom0_tbufcontrol {
+struct dom0_tbufcontrol {
/* IN variables */
#define DOM0_TBUF_GET_INFO 0
#define DOM0_TBUF_SET_CPU_MASK 1
@@ -203,14 +215,15 @@ typedef struct dom0_tbufcontrol {
/* OUT variables */
unsigned long buffer_mfn;
uint32_t size;
-} dom0_tbufcontrol_t;
+};
+typedef struct dom0_tbufcontrol dom0_tbufcontrol_t;
DEFINE_XEN_GUEST_HANDLE(dom0_tbufcontrol_t);

/*
* Get physical information about the host machine
*/
#define DOM0_PHYSINFO 22
-typedef struct dom0_physinfo {
+struct dom0_physinfo {
uint32_t threads_per_core;
uint32_t cores_per_socket;
uint32_t sockets_per_node;
@@ -219,17 +232,19 @@ typedef struct dom0_physinfo {
unsigned long total_pages;
unsigned long free_pages;
uint32_t hw_cap[8];
-} dom0_physinfo_t;
+};
+typedef struct dom0_physinfo dom0_physinfo_t;
DEFINE_XEN_GUEST_HANDLE(dom0_physinfo_t);

/*
* Get the ID of the current scheduler.
*/
#define DOM0_SCHED_ID 24
-typedef struct dom0_sched_id {
+struct dom0_sched_id {
/* OUT variable */
uint32_t sched_id;
-} dom0_sched_id_t;
+};
+typedef struct dom0_physinfo dom0_sched_id_t;
DEFINE_XEN_GUEST_HANDLE(dom0_sched_id_t);

/*
@@ -246,15 +261,16 @@ DEFINE_XEN_GUEST_HANDLE(dom0_sched_id_t)
#define DOM0_SHADOW_CONTROL_OP_CLEAN 11
#define DOM0_SHADOW_CONTROL_OP_PEEK 12

-typedef struct dom0_shadow_control_stats {
+struct dom0_shadow_control_stats {
uint32_t fault_count;
uint32_t dirty_count;
uint32_t dirty_net_count;
uint32_t dirty_block_count;
-} dom0_shadow_control_stats_t;
+};
+typedef struct dom0_shadow_control_stats dom0_shadow_control_stats_t;
DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t);

-typedef struct dom0_shadow_control {
+struct dom0_shadow_control {
/* IN variables. */
domid_t domain;
uint32_t op;
@@ -262,26 +278,29 @@ typedef struct dom0_shadow_control {
/* IN/OUT variables. */
unsigned long pages; /* size of buffer, updated with actual size */
/* OUT variables. */
- dom0_shadow_control_stats_t stats;
-} dom0_shadow_control_t;
+ struct dom0_shadow_control_stats stats;
+};
+typedef struct dom0_shadow_control dom0_shadow_control_t;
DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_t);

#define DOM0_SETDOMAINMAXMEM 28
-typedef struct dom0_setdomainmaxmem {
+struct dom0_setdomainmaxmem {
/* IN variables. */
domid_t domain;
unsigned long max_memkb;
-} dom0_setdomainmaxmem_t;
+};
+typedef struct dom0_setdomainmaxmem dom0_setdomainmaxmem_t;
DEFINE_XEN_GUEST_HANDLE(dom0_setdomainmaxmem_t);

#define DOM0_GETPAGEFRAMEINFO2 29 /* batched interface */
-typedef struct dom0_getpageframeinfo2 {
+struct dom0_getpageframeinfo2 {
/* IN variables. */
domid_t domain;
unsigned long num;
/* IN/OUT variables. */
XEN_GUEST_HANDLE(ulong) array;
-} dom0_getpageframeinfo2_t;
+};
+typedef struct dom0_getpageframeinfo2 dom0_getpageframeinfo2_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo2_t);

/*
@@ -292,7 +311,7 @@ DEFINE_XEN_GUEST_HANDLE(dom0_getpagefram
* (x86-specific).
*/
#define DOM0_ADD_MEMTYPE 31
-typedef struct dom0_add_memtype {
+struct dom0_add_memtype {
/* IN variables. */
unsigned long mfn;
unsigned long nr_mfns;
@@ -300,7 +319,8 @@ typedef struct dom0_add_memtype {
/* OUT variables. */
uint32_t handle;
uint32_t reg;
-} dom0_add_memtype_t;
+};
+typedef struct dom0_add_memtype dom0_add_memtype_t;
DEFINE_XEN_GUEST_HANDLE(dom0_add_memtype_t);

/*
@@ -311,23 +331,25 @@ DEFINE_XEN_GUEST_HANDLE(dom0_add_memtype
* (x86-specific).
*/
#define DOM0_DEL_MEMTYPE 32
-typedef struct dom0_del_memtype {
+struct dom0_del_memtype {
/* IN variables. */
uint32_t handle;
uint32_t reg;
-} dom0_del_memtype_t;
+};
+typedef struct dom0_del_memtype dom0_del_memtype_t;
DEFINE_XEN_GUEST_HANDLE(dom0_del_memtype_t);

/* Read current type of an MTRR (x86-specific). */
#define DOM0_READ_MEMTYPE 33
-typedef struct dom0_read_memtype {
+struct dom0_read_memtype {
/* IN variables. */
uint32_t reg;
/* OUT variables. */
unsigned long mfn;
unsigned long nr_mfns;
uint32_t type;
-} dom0_read_memtype_t;
+};
+typedef struct dom0_read_memtype dom0_read_memtype_t;
DEFINE_XEN_GUEST_HANDLE(dom0_read_memtype_t);

/* Interface for controlling Xen software performance counters. */
@@ -335,50 +357,56 @@ DEFINE_XEN_GUEST_HANDLE(dom0_read_memtyp
/* Sub-operations: */
#define DOM0_PERFCCONTROL_OP_RESET 1 /* Reset all counters to zero. */
#define DOM0_PERFCCONTROL_OP_QUERY 2 /* Get perfctr information. */
-typedef struct dom0_perfc_desc {
+struct dom0_perfc_desc {
char name[80]; /* name of perf counter */
uint32_t nr_vals; /* number of values for this counter */
uint32_t vals[64]; /* array of values */
-} dom0_perfc_desc_t;
+};
+typedef struct dom0_perfc_desc dom0_perfc_desc_t;
DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t);
-typedef struct dom0_perfccontrol {
+
+struct dom0_perfccontrol {
/* IN variables. */
uint32_t op; /* DOM0_PERFCCONTROL_OP_??? */
/* OUT variables. */
uint32_t nr_counters; /* number of counters */
XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /* counter information (or NULL) */
-} dom0_perfccontrol_t;
+};
+typedef struct dom0_perfccontrol dom0_perfccontrol_t;
DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t);

#define DOM0_MICROCODE 35
-typedef struct dom0_microcode {
+struct dom0_microcode {
/* IN variables. */
XEN_GUEST_HANDLE(void) data; /* Pointer to microcode data */
uint32_t length; /* Length of microcode data. */
-} dom0_microcode_t;
+};
+typedef struct dom0_microcode dom0_microcode_t;
DEFINE_XEN_GUEST_HANDLE(dom0_microcode_t);

#define DOM0_IOPORT_PERMISSION 36
-typedef struct dom0_ioport_permission {
+struct dom0_ioport_permission {
domid_t domain; /* domain to be affected */
uint32_t first_port; /* first port int range */
uint32_t nr_ports; /* size of port range */
uint8_t allow_access; /* allow or deny access to range? */
-} dom0_ioport_permission_t;
+};
+typedef struct dom0_ioport_permission dom0_ioport_permission_t;
DEFINE_XEN_GUEST_HANDLE(dom0_ioport_permission_t);

#define DOM0_GETVCPUCONTEXT 37
-typedef struct dom0_getvcpucontext {
+struct dom0_getvcpucontext {
/* IN variables. */
domid_t domain; /* domain to be affected */
uint32_t vcpu; /* vcpu # */
/* OUT variables. */
XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt;
-} dom0_getvcpucontext_t;
+};
+typedef struct dom0_getvcpucontext dom0_getvcpucontext_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getvcpucontext_t);

#define DOM0_GETVCPUINFO 43
-typedef struct dom0_getvcpuinfo {
+struct dom0_getvcpuinfo {
/* IN variables. */
domid_t domain; /* domain to be affected */
uint32_t vcpu; /* vcpu # */
@@ -389,92 +417,104 @@ typedef struct dom0_getvcpuinfo {
uint64_t cpu_time; /* total cpu time consumed (ns) */
uint32_t cpu; /* current mapping */
cpumap_t cpumap; /* allowable mapping */
-} dom0_getvcpuinfo_t;
+};
+typedef struct dom0_getvcpuinfo dom0_getvcpuinfo_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getvcpuinfo_t);

#define DOM0_GETDOMAININFOLIST 38
-typedef struct dom0_getdomaininfolist {
+struct dom0_getdomaininfolist {
/* IN variables. */
domid_t first_domain;
uint32_t max_domains;
XEN_GUEST_HANDLE(dom0_getdomaininfo_t) buffer;
/* OUT variables. */
uint32_t num_domains;
-} dom0_getdomaininfolist_t;
+};
+typedef struct dom0_getdomaininfolist dom0_getdomaininfolist_t;
DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfolist_t);

#define DOM0_PLATFORM_QUIRK 39
#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */
#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */
#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */
-typedef struct dom0_platform_quirk {
+struct dom0_platform_quirk {
/* IN variables. */
uint32_t quirk_id;
-} dom0_platform_quirk_t;
+};
+typedef struct dom0_platform_quirk dom0_platform_quirk_t;
DEFINE_XEN_GUEST_HANDLE(dom0_platform_quirk_t);

-#define DOM0_PHYSICAL_MEMORY_MAP 40
-typedef struct dom0_memory_map_entry {
+#define DOM0_PHYSICAL_MEMORY_MAP 40 /* Unimplemented from 3.0.3 onwards */
+struct dom0_memory_map_entry {
uint64_t start, end;
uint32_t flags; /* reserved */
uint8_t is_ram;
-} dom0_memory_map_entry_t;
+};
+typedef struct dom0_memory_map_entry dom0_memory_map_entry_t;
DEFINE_XEN_GUEST_HANDLE(dom0_memory_map_entry_t);
-typedef struct dom0_physical_memory_map {
+
+struct dom0_physical_memory_map {
/* IN variables. */
uint32_t max_map_entries;
/* OUT variables. */
uint32_t nr_map_entries;
XEN_GUEST_HANDLE(dom0_memory_map_entry_t) memory_map;
-} dom0_physical_memory_map_t;
+};
+typedef struct dom0_physical_memory_map dom0_physical_memory_map_t;
DEFINE_XEN_GUEST_HANDLE(dom0_physical_memory_map_t);

#define DOM0_MAX_VCPUS 41
-typedef struct dom0_max_vcpus {
+struct dom0_max_vcpus {
domid_t domain; /* domain to be affected */
uint32_t max; /* maximum number of vcpus */
-} dom0_max_vcpus_t;
+};
+typedef struct dom0_max_vcpus dom0_max_vcpus_t;
DEFINE_XEN_GUEST_HANDLE(dom0_max_vcpus_t);

#define DOM0_SETDOMAINHANDLE 44
-typedef struct dom0_setdomainhandle {
+struct dom0_setdomainhandle {
domid_t domain;
xen_domain_handle_t handle;
-} dom0_setdomainhandle_t;
+};
+typedef struct dom0_setdomainhandle dom0_setdomainhandle_t;
DEFINE_XEN_GUEST_HANDLE(dom0_setdomainhandle_t);

#define DOM0_SETDEBUGGING 45
-typedef struct dom0_setdebugging {
+struct dom0_setdebugging {
domid_t domain;
uint8_t enable;
-} dom0_setdebugging_t;
+};
+typedef struct dom0_setdebugging dom0_setdebugging_t;
DEFINE_XEN_GUEST_HANDLE(dom0_setdebugging_t);

#define DOM0_IRQ_PERMISSION 46
-typedef struct dom0_irq_permission {
+struct dom0_irq_permission {
domid_t domain; /* domain to be affected */
uint8_t pirq;
uint8_t allow_access; /* flag to specify enable/disable of IRQ access */
-} dom0_irq_permission_t;
+};
+typedef struct dom0_irq_permission dom0_irq_permission_t;
DEFINE_XEN_GUEST_HANDLE(dom0_irq_permission_t);

#define DOM0_IOMEM_PERMISSION 47
-typedef struct dom0_iomem_permission {
+struct dom0_iomem_permission {
domid_t domain; /* domain to be affected */
unsigned long first_mfn; /* first page (physical page number) in range */
unsigned long nr_mfns; /* number of pages in range (>0) */
uint8_t allow_access; /* allow (!0) or deny (0) access to range? */
-} dom0_iomem_permission_t;
+};
+typedef struct dom0_iomem_permission dom0_iomem_permission_t;
DEFINE_XEN_GUEST_HANDLE(dom0_iomem_permission_t);

#define DOM0_HYPERCALL_INIT 48
-typedef struct dom0_hypercall_init {
+struct dom0_hypercall_init {
domid_t domain; /* domain to be affected */
unsigned long mfn; /* machine frame to be initialised */
-} dom0_hypercall_init_t;
+};
+typedef struct dom0_hypercall_init dom0_hypercall_init_t;
DEFINE_XEN_GUEST_HANDLE(dom0_hypercall_init_t);

-typedef struct dom0_op {
+struct dom0_op {
uint32_t cmd;
uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
union {
@@ -517,7 +557,8 @@ typedef struct dom0_op {
struct dom0_hypercall_init hypercall_init;
uint8_t pad[128];
} u;
-} dom0_op_t;
+};
+typedef struct dom0_op dom0_op_t;
DEFINE_XEN_GUEST_HANDLE(dom0_op_t);

#endif /* __XEN_PUBLIC_DOM0_OPS_H__ */
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/event_channel.h Mon May 22 14:13:38 2006 -0600
@@ -28,12 +28,13 @@ DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
* 2. <rdom> may be DOMID_SELF, allowing loopback connections.
*/
#define EVTCHNOP_alloc_unbound 6
-typedef struct evtchn_alloc_unbound {
+struct evtchn_alloc_unbound {
/* IN parameters */
domid_t dom, remote_dom;
/* OUT parameters */
evtchn_port_t port;
-} evtchn_alloc_unbound_t;
+};
+typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t;

/*
* EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
@@ -45,13 +46,14 @@ typedef struct evtchn_alloc_unbound {
* 2. <remote_dom> may be DOMID_SELF, allowing loopback connections.
*/
#define EVTCHNOP_bind_interdomain 0
-typedef struct evtchn_bind_interdomain {
+struct evtchn_bind_interdomain {
/* IN parameters. */
domid_t remote_dom;
evtchn_port_t remote_port;
/* OUT parameters. */
evtchn_port_t local_port;
-} evtchn_bind_interdomain_t;
+};
+typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t;

/*
* EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
@@ -66,13 +68,14 @@ typedef struct evtchn_bind_interdomain {
* binding cannot be changed.
*/
#define EVTCHNOP_bind_virq 1
-typedef struct evtchn_bind_virq {
+struct evtchn_bind_virq {
/* IN parameters. */
uint32_t virq;
uint32_t vcpu;
/* OUT parameters. */
evtchn_port_t port;
-} evtchn_bind_virq_t;
+};
+typedef struct evtchn_bind_virq evtchn_bind_virq_t;

/*
* EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>.
@@ -81,14 +84,15 @@ typedef struct evtchn_bind_virq {
* 2. Only a sufficiently-privileged domain may bind to a physical IRQ.
*/
#define EVTCHNOP_bind_pirq 2
-typedef struct evtchn_bind_pirq {
+struct evtchn_bind_pirq {
/* IN parameters. */
uint32_t pirq;
#define BIND_PIRQ__WILL_SHARE 1
uint32_t flags; /* BIND_PIRQ__* */
/* OUT parameters. */
evtchn_port_t port;
-} evtchn_bind_pirq_t;
+};
+typedef struct evtchn_bind_pirq evtchn_bind_pirq_t;

/*
* EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
@@ -97,11 +101,12 @@ typedef struct evtchn_bind_pirq {
* may not be changed.
*/
#define EVTCHNOP_bind_ipi 7
-typedef struct evtchn_bind_ipi {
- uint32_t vcpu;
- /* OUT parameters. */
- evtchn_port_t port;
-} evtchn_bind_ipi_t;
+struct evtchn_bind_ipi {
+ uint32_t vcpu;
+ /* OUT parameters. */
+ evtchn_port_t port;
+};
+typedef struct evtchn_bind_ipi evtchn_bind_ipi_t;

/*
* EVTCHNOP_close: Close a local event channel <port>. If the channel is
@@ -109,20 +114,22 @@ typedef struct evtchn_bind_ipi {
* (EVTCHNSTAT_unbound), awaiting a new connection.
*/
#define EVTCHNOP_close 3
-typedef struct evtchn_close {
- /* IN parameters. */
- evtchn_port_t port;
-} evtchn_close_t;
+struct evtchn_close {
+ /* IN parameters. */
+ evtchn_port_t port;
+};
+typedef struct evtchn_close evtchn_close_t;

/*
* EVTCHNOP_send: Send an event to the remote end of the channel whose local
* endpoint is <port>.
*/
#define EVTCHNOP_send 4
-typedef struct evtchn_send {
- /* IN parameters. */
- evtchn_port_t port;
-} evtchn_send_t;
+struct evtchn_send {
+ /* IN parameters. */
+ evtchn_port_t port;
+};
+typedef struct evtchn_send evtchn_send_t;

/*
* EVTCHNOP_status: Get the current status of the communication channel which
@@ -133,7 +140,7 @@ typedef struct evtchn_send {
* channel for which <dom> is not DOMID_SELF.
*/
#define EVTCHNOP_status 5
-typedef struct evtchn_status {
+struct evtchn_status {
/* IN parameters */
domid_t dom;
evtchn_port_t port;
@@ -157,7 +164,8 @@ typedef struct evtchn_status {
uint32_t pirq; /* EVTCHNSTAT_pirq */
uint32_t virq; /* EVTCHNSTAT_virq */
} u;
-} evtchn_status_t;
+};
+typedef struct evtchn_status evtchn_status_t;

/*
* EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
@@ -172,41 +180,44 @@ typedef struct evtchn_status {
* has its binding reset to vcpu0).
*/
#define EVTCHNOP_bind_vcpu 8
-typedef struct evtchn_bind_vcpu {
- /* IN parameters. */
- evtchn_port_t port;
- uint32_t vcpu;
-} evtchn_bind_vcpu_t;
+struct evtchn_bind_vcpu {
+ /* IN parameters. */
+ evtchn_port_t port;
+ uint32_t vcpu;
+};
+typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t;

/*
* EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
* a notification to the appropriate VCPU if an event is pending.
*/
#define EVTCHNOP_unmask 9
-typedef struct evtchn_unmask {
- /* IN parameters. */
- evtchn_port_t port;
-} evtchn_unmask_t;
+struct evtchn_unmask {
+ /* IN parameters. */
+ evtchn_port_t port;
+};
+typedef struct evtchn_unmask evtchn_unmask_t;

/*
* Argument to event_channel_op_compat() hypercall. Superceded by new
* event_channel_op() hypercall since 0x00030202.
*/
-typedef struct evtchn_op {
+struct evtchn_op {
uint32_t cmd; /* EVTCHNOP_* */
union {
- evtchn_alloc_unbound_t alloc_unbound;
- evtchn_bind_interdomain_t bind_interdomain;
- evtchn_bind_virq_t bind_virq;
- evtchn_bind_pirq_t bind_pirq;
- evtchn_bind_ipi_t bind_ipi;
- evtchn_close_t close;
- evtchn_send_t send;
- evtchn_status_t status;
- evtchn_bind_vcpu_t bind_vcpu;
- evtchn_unmask_t unmask;
+ struct evtchn_alloc_unbound alloc_unbound;
+ struct evtchn_bind_interdomain bind_interdomain;
+ struct evtchn_bind_virq bind_virq;
+ struct evtchn_bind_pirq bind_pirq;
+ struct evtchn_bind_ipi bind_ipi;
+ struct evtchn_close close;
+ struct evtchn_send send;
+ struct evtchn_status status;
+ struct evtchn_bind_vcpu bind_vcpu;
+ struct evtchn_unmask unmask;
} u;
-} evtchn_op_t;
+};
+typedef struct evtchn_op evtchn_op_t;
DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);

#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/grant_table.h Mon May 22 14:13:38 2006 -0600
@@ -71,7 +71,7 @@
* [XEN]: This field is written by Xen and read by the sharing guest.
* [GST]: This field is written by the guest and read by Xen.
*/
-typedef struct grant_entry {
+struct grant_entry {
/* GTF_xxx: various type and flag information. [XEN,GST] */
uint16_t flags;
/* The domain being granted foreign privileges. [GST] */
@@ -81,7 +81,8 @@ typedef struct grant_entry {
* GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]
*/
uint32_t frame;
-} grant_entry_t;
+};
+typedef struct grant_entry grant_entry_t;

/*
* Type of grant entry.
@@ -156,7 +157,7 @@ typedef uint32_t grant_handle_t;
* to be accounted to the correct grant reference!
*/
#define GNTTABOP_map_grant_ref 0
-typedef struct gnttab_map_grant_ref {
+struct gnttab_map_grant_ref {
/* IN parameters. */
uint64_t host_addr;
uint32_t flags; /* GNTMAP_* */
@@ -166,7 +167,8 @@ typedef struct gnttab_map_grant_ref {
int16_t status; /* GNTST_* */
grant_handle_t handle;
uint64_t dev_bus_addr;
-} gnttab_map_grant_ref_t;
+};
+typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);

/*
@@ -181,14 +183,15 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant
* mappings will remain in the device or host TLBs.
*/
#define GNTTABOP_unmap_grant_ref 1
-typedef struct gnttab_unmap_grant_ref {
+struct gnttab_unmap_grant_ref {
/* IN parameters. */
uint64_t host_addr;
uint64_t dev_bus_addr;
grant_handle_t handle;
/* OUT parameters. */
int16_t status; /* GNTST_* */
-} gnttab_unmap_grant_ref_t;
+};
+typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);

/*
@@ -201,14 +204,15 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_gra
* 3. Xen may not support more than a single grant-table page per domain.
*/
#define GNTTABOP_setup_table 2
-typedef struct gnttab_setup_table {
+struct gnttab_setup_table {
/* IN parameters. */
domid_t dom;
uint32_t nr_frames;
/* OUT parameters. */
int16_t status; /* GNTST_* */
XEN_GUEST_HANDLE(ulong) frame_list;
-} gnttab_setup_table_t;
+};
+typedef struct gnttab_setup_table gnttab_setup_table_t;
DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t);

/*
@@ -216,12 +220,13 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_setup_tab
* xen console. Debugging use only.
*/
#define GNTTABOP_dump_table 3
-typedef struct gnttab_dump_table {
+struct gnttab_dump_table {
/* IN parameters. */
domid_t dom;
/* OUT parameters. */
int16_t status; /* GNTST_* */
-} gnttab_dump_table_t;
+};
+typedef struct gnttab_dump_table gnttab_dump_table_t;
DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);

/*
@@ -233,14 +238,15 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_dump_tabl
* to the calling domain *unless* the error is GNTST_bad_page.
*/
#define GNTTABOP_transfer 4
-typedef struct gnttab_transfer {
+struct gnttab_transfer {
/* IN parameters. */
unsigned long mfn;
domid_t domid;
grant_ref_t ref;
/* OUT parameters. */
int16_t status;
-} gnttab_transfer_t;
+};
+typedef struct gnttab_transfer gnttab_transfer_t;
DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);

/*
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/hvm/ioreq.h Mon May 22 14:13:38 2006 -0600
@@ -41,7 +41,7 @@
* prepare this structure and notify service OS and DM by sending
* virq
*/
-typedef struct {
+struct ioreq {
uint64_t addr; /* physical address */
uint64_t size; /* size in bytes */
uint64_t count; /* for rep prefixes */
@@ -55,31 +55,35 @@ typedef struct {
uint8_t df:1;
uint8_t type; /* I/O type */
uint64_t io_count; /* How many IO done on a vcpu */
-} ioreq_t;
+};
+typedef struct ioreq ioreq_t;

#define MAX_VECTOR 256
#define BITS_PER_BYTE 8
#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t)))
#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t)))

-typedef struct {
+struct global_iodata {
uint16_t pic_elcr;
uint16_t pic_irr;
uint16_t pic_last_irr;
uint16_t pic_clear_irr;
-} global_iodata_t;
+};
+typedef struct global_iodata global_iodata_t;

-typedef struct {
- ioreq_t vp_ioreq;
+struct vcpu_iodata {
+ struct ioreq vp_ioreq;
/* Event channel port */
unsigned int vp_eport; /* VMX vcpu uses this to notify DM */
unsigned int dm_eport; /* DM uses this to notify VMX vcpu */
-} vcpu_iodata_t;
+};
+typedef struct vcpu_iodata vcpu_iodata_t;

-typedef struct {
- global_iodata_t sp_global;
- vcpu_iodata_t vcpu_iodata[1];
-} shared_iopage_t;
+struct shared_iopage {
+ struct global_iodata sp_global;
+ struct vcpu_iodata vcpu_iodata[1];
+};
+typedef struct shared_iopage shared_iopage_t;

#endif /* _IOREQ_H_ */

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/hvm/vmx_assist.h
--- a/xen/include/public/hvm/vmx_assist.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/hvm/vmx_assist.h Mon May 22 14:13:38 2006 -0600
@@ -37,7 +37,7 @@ union vmcs_arbytes {
/*
* World switch state
*/
-typedef struct vmx_assist_context {
+struct vmx_assist_context {
uint32_t eip; /* execution pointer */
uint32_t esp; /* stack pointer */
uint32_t eflags; /* flags register */
@@ -80,7 +80,8 @@ typedef struct vmx_assist_context {
uint32_t ldtr_limit;
uint32_t ldtr_base;
union vmcs_arbytes ldtr_arbytes;
-} vmx_assist_context_t;
+};
+typedef struct vmx_assist_context vmx_assist_context_t;

#endif /* __ASSEMBLY__ */

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/io/blkif.h
--- a/xen/include/public/io/blkif.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/io/blkif.h Mon May 22 14:13:38 2006 -0600
@@ -39,7 +39,7 @@
*/
#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11

-typedef struct blkif_request {
+struct blkif_request {
uint8_t operation; /* BLKIF_OP_??? */
uint8_t nr_segments; /* number of segments */
blkif_vdev_t handle; /* only for read/write requests */
@@ -51,13 +51,15 @@ typedef struct blkif_request {
/* @last_sect: last sector in frame to transfer (inclusive). */
uint8_t first_sect, last_sect;
} seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-} blkif_request_t;
+};
+typedef struct blkif_request blkif_request_t;

-typedef struct blkif_response {
+struct blkif_response {
uint64_t id; /* copied from request */
uint8_t operation; /* copied from request */
int16_t status; /* BLKIF_RSP_??? */
-} blkif_response_t;
+};
+typedef struct blkif_response blkif_response_t;

#define BLKIF_RSP_ERROR -1 /* non-specific 'error' */
#define BLKIF_RSP_OKAY 0 /* non-specific 'okay' */
@@ -66,7 +68,7 @@ typedef struct blkif_response {
* Generate blkif ring structures and types.
*/

-DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t);
+DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);

#define VDISK_CDROM 0x1
#define VDISK_REMOVABLE 0x2
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/io/netif.h Mon May 22 14:13:38 2006 -0600
@@ -13,10 +13,10 @@
#include "../grant_table.h"

/*
- * Note that there is *never* any need to notify the backend when enqueuing
- * receive requests (netif_rx_request_t). Notifications after enqueuing any
- * other type of message should be conditional on the appropriate req_event
- * or rsp_event field in the shared ring.
+ * Note that there is *never* any need to notify the backend when
+ * enqueuing receive requests (struct netif_rx_request). Notifications
+ * after enqueuing any other type of message should be conditional on
+ * the appropriate req_event or rsp_event field in the shared ring.
*/

/* Protocol checksum field is blank in the packet (hardware offload)? */
@@ -27,23 +27,26 @@
#define _NETTXF_data_validated (1)
#define NETTXF_data_validated (1U<<_NETTXF_data_validated)

-typedef struct netif_tx_request {
+struct netif_tx_request {
grant_ref_t gref; /* Reference to buffer page */
uint16_t offset; /* Offset within buffer page */
uint16_t flags; /* NETTXF_* */
uint16_t id; /* Echoed in response message. */
uint16_t size; /* Packet size in bytes. */
-} netif_tx_request_t;
+};
+typedef struct netif_tx_request netif_tx_request_t;

-typedef struct netif_tx_response {
+struct netif_tx_response {
uint16_t id;
int16_t status; /* NETIF_RSP_* */
-} netif_tx_response_t;
+};
+typedef struct netif_tx_response netif_tx_response_t;

-typedef struct {
+struct netif_rx_request {
uint16_t id; /* Echoed in response message. */
grant_ref_t gref; /* Reference to incoming granted frame */
-} netif_rx_request_t;
+};
+typedef struct netif_rx_request netif_rx_request_t;

/* Packet data has been validated against protocol checksum. */
#define _NETRXF_data_validated (0)
@@ -53,19 +56,20 @@ typedef struct {
#define _NETRXF_csum_blank (1)
#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank)

-typedef struct {
+struct netif_rx_response {
uint16_t id;
uint16_t offset; /* Offset in page of start of received packet */
uint16_t flags; /* NETRXF_* */
int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
-} netif_rx_response_t;
+};
+typedef struct netif_rx_response netif_rx_response_t;

/*
* Generate netif ring structures and types.
*/

-DEFINE_RING_TYPES(netif_tx, netif_tx_request_t, netif_tx_response_t);
-DEFINE_RING_TYPES(netif_rx, netif_rx_request_t, netif_rx_response_t);
+DEFINE_RING_TYPES(netif_tx, struct netif_tx_request, struct netif_tx_response);
+DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);

#define NETIF_RSP_DROPPED -2
#define NETIF_RSP_ERROR -1
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/io/tpmif.h
--- a/xen/include/public/io/tpmif.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/io/tpmif.h Mon May 22 14:13:38 2006 -0600
@@ -18,12 +18,13 @@

#include "../grant_table.h"

-typedef struct {
+struct tpmif_tx_request {
unsigned long addr; /* Machine address of packet. */
grant_ref_t ref; /* grant table access reference */
uint16_t unused;
uint16_t size; /* Packet size in bytes. */
-} tpmif_tx_request_t;
+};
+typedef struct tpmif_tx_request tpmif_tx_request_t;

/*
* The TPMIF_TX_RING_SIZE defines the number of pages the
@@ -35,13 +36,15 @@ typedef uint32_t TPMIF_RING_IDX;

/* This structure must fit in a memory page. */

-typedef struct {
- tpmif_tx_request_t req;
-} tpmif_ring_t;
+struct tpmif_ring {
+ struct tpmif_tx_request req;
+};
+typedef struct tpmif_ring tpmif_ring_t;

-typedef struct {
- tpmif_ring_t ring[TPMIF_TX_RING_SIZE];
-} tpmif_tx_interface_t;
+struct tpmif_tx_interface {
+ struct tpmif_ring ring[TPMIF_TX_RING_SIZE];
+};
+typedef struct tpmif_tx_interface tpmif_tx_interface_t;

#endif

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/memory.h
--- a/xen/include/public/memory.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/memory.h Mon May 22 14:13:38 2006 -0600
@@ -17,7 +17,7 @@
#define XENMEM_increase_reservation 0
#define XENMEM_decrease_reservation 1
#define XENMEM_populate_physmap 6
-typedef struct xen_memory_reservation {
+struct xen_memory_reservation {

/*
* XENMEM_increase_reservation:
@@ -49,7 +49,8 @@ typedef struct xen_memory_reservation {
*/
domid_t domid;

-} xen_memory_reservation_t;
+};
+typedef struct xen_memory_reservation xen_memory_reservation_t;
DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);

/*
@@ -74,7 +75,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_reser
* arg == addr of xen_machphys_mfn_list_t.
*/
#define XENMEM_machphys_mfn_list 5
-typedef struct xen_machphys_mfn_list {
+struct xen_machphys_mfn_list {
/*
* Size of the 'extent_start' array. Fewer entries will be filled if the
* machphys table is smaller than max_extents * 2MB.
@@ -93,7 +94,8 @@ typedef struct xen_machphys_mfn_list {
* than 'max_extents' if the machphys table is smaller than max_e * 2MB.
*/
unsigned int nr_extents;
-} xen_machphys_mfn_list_t;
+};
+typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t;
DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);

/*
@@ -102,7 +104,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn
* arg == addr of xen_add_to_physmap_t.
*/
#define XENMEM_add_to_physmap 7
-typedef struct xen_add_to_physmap {
+struct xen_add_to_physmap {
/* Which domain to change the mapping for. */
domid_t domid;

@@ -116,7 +118,8 @@ typedef struct xen_add_to_physmap {

/* GPFN where the source mapping page should appear. */
unsigned long gpfn;
-} xen_add_to_physmap_t;
+};
+typedef struct xen_add_to_physmap xen_add_to_physmap_t;
DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);

/*
@@ -124,7 +127,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_add_to_physm
* code on failure. This call only works for auto-translated guests.
*/
#define XENMEM_translate_gpfn_list 8
-typedef struct xen_translate_gpfn_list {
+struct xen_translate_gpfn_list {
/* Which domain to translate for? */
domid_t domid;

@@ -139,8 +142,37 @@ typedef struct xen_translate_gpfn_list {
* list (in which case each input GPFN is overwritten with the output MFN).
*/
XEN_GUEST_HANDLE(ulong) mfn_list;
-} xen_translate_gpfn_list_t;
+};
+typedef struct xen_translate_gpfn_list xen_translate_gpfn_list_t;
DEFINE_XEN_GUEST_HANDLE(xen_translate_gpfn_list_t);
+
+/*
+ * Returns the pseudo-physical memory map as it was when the domain
+ * was started.
+ */
+#define XENMEM_memory_map 9
+struct xen_memory_map {
+ /*
+ * On call the number of entries which can be stored in buffer. On
+ * return the number of entries which have been stored in
+ * buffer.
+ */
+ unsigned int nr_entries;
+
+ /*
+ * Entries in the buffer are in the same format as returned by the
+ * BIOS INT 0x15 EAX=0xE820 call.
+ */
+ XEN_GUEST_HANDLE(void) buffer;
+};
+typedef struct xen_memory_map xen_memory_map_t;
+DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
+
+/*
+ * Returns the real physical memory map. Passes the same structure as
+ * XENMEM_memory_map.
+ */
+#define XENMEM_machine_memory_map 10

#endif /* __XEN_PUBLIC_MEMORY_H__ */

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/nmi.h
--- a/xen/include/public/nmi.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/nmi.h Mon May 22 14:13:38 2006 -0600
@@ -34,10 +34,11 @@
* arg == pointer to xennmi_callback structure.
*/
#define XENNMI_register_callback 0
-typedef struct xennmi_callback {
+struct xennmi_callback {
unsigned long handler_address;
unsigned long pad;
-} xennmi_callback_t;
+};
+typedef struct xennmi_callback xennmi_callback_t;
DEFINE_XEN_GUEST_HANDLE(xennmi_callback_t);

/*
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/physdev.h Mon May 22 14:13:38 2006 -0600
@@ -14,10 +14,11 @@
* @arg == pointer to physdev_eoi structure.
*/
#define PHYSDEVOP_eoi 12
-typedef struct physdev_eoi {
+struct physdev_eoi {
/* IN */
uint32_t irq;
-} physdev_eoi_t;
+};
+typedef struct physdev_eoi physdev_eoi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);

/*
@@ -25,12 +26,13 @@ DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
* @arg == pointer to physdev_irq_status_query structure.
*/
#define PHYSDEVOP_irq_status_query 5
-typedef struct physdev_irq_status_query {
+struct physdev_irq_status_query {
/* IN */
uint32_t irq;
/* OUT */
uint32_t flags; /* XENIRQSTAT_* */
-} physdev_irq_status_query_t;
+};
+typedef struct physdev_irq_status_query physdev_irq_status_query_t;
DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);

/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
@@ -42,10 +44,11 @@ DEFINE_XEN_GUEST_HANDLE(physdev_irq_stat
* @arg == pointer to physdev_set_iopl structure.
*/
#define PHYSDEVOP_set_iopl 6
-typedef struct physdev_set_iopl {
+struct physdev_set_iopl {
/* IN */
uint32_t iopl;
-} physdev_set_iopl_t;
+};
+typedef struct physdev_set_iopl physdev_set_iopl_t;
DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);

/*
@@ -53,11 +56,12 @@ DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl
* @arg == pointer to physdev_set_iobitmap structure.
*/
#define PHYSDEVOP_set_iobitmap 7
-typedef struct physdev_set_iobitmap {
+struct physdev_set_iobitmap {
/* IN */
uint8_t *bitmap;
uint32_t nr_ports;
-} physdev_set_iobitmap_t;
+};
+typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);

/*
@@ -66,13 +70,14 @@ DEFINE_XEN_GUEST_HANDLE(physdev_set_iobi
*/
#define PHYSDEVOP_apic_read 8
#define PHYSDEVOP_apic_write 9
-typedef struct physdev_apic {
+struct physdev_apic {
/* IN */
unsigned long apic_physbase;
uint32_t reg;
/* IN or OUT */
uint32_t value;
-} physdev_apic_t;
+};
+typedef struct physdev_apic physdev_apic_t;
DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);

/*
@@ -81,28 +86,30 @@ DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
*/
#define PHYSDEVOP_alloc_irq_vector 10
#define PHYSDEVOP_free_irq_vector 11
-typedef struct physdev_irq {
+struct physdev_irq {
/* IN */
uint32_t irq;
/* IN or OUT */
uint32_t vector;
-} physdev_irq_t;
+};
+typedef struct physdev_irq physdev_irq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);

/*
* Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
* hypercall since 0x00030202.
*/
-typedef struct physdev_op {
+struct physdev_op {
uint32_t cmd;
union {
- physdev_irq_status_query_t irq_status_query;
- physdev_set_iopl_t set_iopl;
- physdev_set_iobitmap_t set_iobitmap;
- physdev_apic_t apic_op;
- physdev_irq_t irq_op;
+ struct physdev_irq_status_query irq_status_query;
+ struct physdev_set_iopl set_iopl;
+ struct physdev_set_iobitmap set_iobitmap;
+ struct physdev_apic apic_op;
+ struct physdev_irq irq_op;
} u;
-} physdev_op_t;
+};
+typedef struct physdev_op physdev_op_t;
DEFINE_XEN_GUEST_HANDLE(physdev_op_t);

/*
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/sched.h
--- a/xen/include/public/sched.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/sched.h Mon May 22 14:13:38 2006 -0600
@@ -46,9 +46,10 @@
* @arg == pointer to sched_shutdown structure.
*/
#define SCHEDOP_shutdown 2
-typedef struct sched_shutdown {
+struct sched_shutdown {
unsigned int reason; /* SHUTDOWN_* */
-} sched_shutdown_t;
+};
+typedef struct sched_shutdown sched_shutdown_t;
DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);

/*
@@ -57,11 +58,12 @@ DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t
* @arg == pointer to sched_poll structure.
*/
#define SCHEDOP_poll 3
-typedef struct sched_poll {
+struct sched_poll {
XEN_GUEST_HANDLE(evtchn_port_t) ports;
unsigned int nr_ports;
uint64_t timeout;
-} sched_poll_t;
+};
+typedef struct sched_poll sched_poll_t;
DEFINE_XEN_GUEST_HANDLE(sched_poll_t);

/*
@@ -71,10 +73,11 @@ DEFINE_XEN_GUEST_HANDLE(sched_poll_t);
* @arg == pointer to sched_remote_shutdown structure.
*/
#define SCHEDOP_remote_shutdown 4
-typedef struct sched_remote_shutdown {
+struct sched_remote_shutdown {
domid_t domain_id; /* Remote domain ID */
unsigned int reason; /* SHUTDOWN_xxx reason */
-} sched_remote_shutdown_t;
+};
+typedef struct sched_remote_shutdown sched_remote_shutdown_t;
DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);

/*
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/vcpu.h
--- a/xen/include/public/vcpu.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/vcpu.h Mon May 22 14:13:38 2006 -0600
@@ -56,7 +56,7 @@
* @extra_arg == pointer to vcpu_runstate_info structure.
*/
#define VCPUOP_get_runstate_info 4
-typedef struct vcpu_runstate_info {
+struct vcpu_runstate_info {
/* VCPU's current state (RUNSTATE_*). */
int state;
/* When was current state entered (system time, ns)? */
@@ -66,7 +66,8 @@ typedef struct vcpu_runstate_info {
* guaranteed not to drift from system time.
*/
uint64_t time[4];
-} vcpu_runstate_info_t;
+};
+typedef struct vcpu_runstate_info vcpu_runstate_info_t;

/* VCPU is currently running on a physical CPU. */
#define RUNSTATE_running 0
@@ -99,12 +100,13 @@ typedef struct vcpu_runstate_info {
* @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
*/
#define VCPUOP_register_runstate_memory_area 5
-typedef struct vcpu_register_runstate_memory_area {
+struct vcpu_register_runstate_memory_area {
union {
struct vcpu_runstate_info *v;
uint64_t p;
} addr;
-} vcpu_register_runstate_memory_area_t;
+};
+typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_memory_area_t;

#endif /* __XEN_PUBLIC_VCPU_H__ */

diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/version.h
--- a/xen/include/public/version.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/version.h Mon May 22 14:13:38 2006 -0600
@@ -22,12 +22,13 @@ typedef char xen_extraversion_t[16];

/* arg == xen_compile_info_t. */
#define XENVER_compile_info 2
-typedef struct xen_compile_info {
+struct xen_compile_info {
char compiler[64];
char compile_by[16];
char compile_domain[32];
char compile_date[32];
-} xen_compile_info_t;
+};
+typedef struct xen_compile_info xen_compile_info_t;

#define XENVER_capabilities 3
typedef char xen_capabilities_info_t[1024];
@@ -38,15 +39,17 @@ typedef char xen_changeset_info_t[64];
#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))

#define XENVER_platform_parameters 5
-typedef struct xen_platform_parameters {
+struct xen_platform_parameters {
unsigned long virt_start;
-} xen_platform_parameters_t;
+};
+typedef struct xen_platform_parameters xen_platform_parameters_t;

#define XENVER_get_features 6
-typedef struct xen_feature_info {
+struct xen_feature_info {
unsigned int submap_idx; /* IN: which 32-bit submap to return */
uint32_t submap; /* OUT: 32-bit submap */
-} xen_feature_info_t;
+};
+typedef struct xen_feature_info xen_feature_info_t;

/* Declares the features reported by XENVER_get_features. */
#include "features.h"
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/xen.h
--- a/xen/include/public/xen.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/xen.h Mon May 22 14:13:38 2006 -0600
@@ -193,7 +193,7 @@
#define MMUEXT_NEW_USER_BASEPTR 15

#ifndef __ASSEMBLY__
-typedef struct mmuext_op {
+struct mmuext_op {
unsigned int cmd;
union {
/* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
@@ -207,7 +207,8 @@ typedef struct mmuext_op {
/* TLB_FLUSH_MULTI, INVLPG_MULTI */
void *vcpumask;
} arg2;
-} mmuext_op_t;
+};
+typedef struct mmuext_op mmuext_op_t;
DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
#endif

@@ -271,20 +272,22 @@ typedef uint16_t domid_t;
* Send an array of these to HYPERVISOR_mmu_update().
* NB. The fields are natural pointer/address size for this architecture.
*/
-typedef struct mmu_update {
+struct mmu_update {
uint64_t ptr; /* Machine address of PTE. */
uint64_t val; /* New contents of PTE. */
-} mmu_update_t;
+};
+typedef struct mmu_update mmu_update_t;
DEFINE_XEN_GUEST_HANDLE(mmu_update_t);

/*
* Send an array of these to HYPERVISOR_multicall().
* NB. The fields are natural register size for this architecture.
*/
-typedef struct multicall_entry {
+struct multicall_entry {
unsigned long op, result;
unsigned long args[6];
-} multicall_entry_t;
+};
+typedef struct multicall_entry multicall_entry_t;
DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);

/*
@@ -293,7 +296,7 @@ DEFINE_XEN_GUEST_HANDLE(multicall_entry_
*/
#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)

-typedef struct vcpu_time_info {
+struct vcpu_time_info {
/*
* Updates to the following values are preceded and followed by an
* increment of 'version'. The guest can therefore detect updates by
@@ -317,9 +320,10 @@ typedef struct vcpu_time_info {
uint32_t tsc_to_system_mul;
int8_t tsc_shift;
int8_t pad1[3];
-} vcpu_time_info_t; /* 32 bytes */
-
-typedef struct vcpu_info {
+}; /* 32 bytes */
+typedef struct vcpu_time_info vcpu_time_info_t;
+
+struct vcpu_info {
/*
* 'evtchn_upcall_pending' is written non-zero by Xen to indicate
* a pending notification for a particular VCPU. It is then cleared
@@ -348,16 +352,17 @@ typedef struct vcpu_info {
uint8_t evtchn_upcall_pending;
uint8_t evtchn_upcall_mask;
unsigned long evtchn_pending_sel;
- arch_vcpu_info_t arch;
- vcpu_time_info_t time;
-} vcpu_info_t; /* 64 bytes (x86) */
+ struct arch_vcpu_info arch;
+ struct vcpu_time_info time;
+}; /* 64 bytes (x86) */
+typedef struct vcpu_info vcpu_info_t;

/*
* Xen/kernel shared data -- pointer provided in start_info.
* NB. We expect that this struct is smaller than a page.
*/
-typedef struct shared_info {
- vcpu_info_t vcpu_info[MAX_VIRT_CPUS];
+struct shared_info {
+ struct vcpu_info vcpu_info[MAX_VIRT_CPUS];

/*
* A domain can create "event channels" on which it can send and receive
@@ -401,9 +406,10 @@ typedef struct shared_info {
uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */

- arch_shared_info_t arch;
-
-} shared_info_t;
+ struct arch_shared_info arch;
+
+};
+typedef struct shared_info shared_info_t;

/*
* Start-of-day memory layout for the initial domain (DOM0):
@@ -431,7 +437,7 @@ typedef struct shared_info {
*/

#define MAX_GUEST_CMDLINE 1024
-typedef struct start_info {
+struct start_info {
/* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
char magic[32]; /* "xen-<version>-<platform>". */
unsigned long nr_pages; /* Total pages allocated to this domain. */
@@ -448,7 +454,8 @@ typedef struct start_info {
unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
int8_t cmd_line[MAX_GUEST_CMDLINE];
-} start_info_t;
+};
+typedef struct start_info start_info_t;

/* These flags are passed in the 'flags' field of start_info_t. */
#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/public/xenoprof.h Mon May 22 14:13:38 2006 -0600
@@ -41,7 +41,7 @@ struct event_log {
};

/* Xenoprof buffer shared between Xen and domain - 1 per VCPU */
-typedef struct xenoprof_buf {
+struct xenoprof_buf {
uint32_t event_head;
uint32_t event_tail;
uint32_t event_size;
@@ -51,10 +51,11 @@ typedef struct xenoprof_buf {
uint64_t user_samples;
uint64_t lost_samples;
struct event_log event_log[1];
-} xenoprof_buf_t;
+};
+typedef struct xenoprof_buf xenoprof_buf_t;
DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);

-typedef struct xenoprof_init {
+struct xenoprof_init {
int32_t max_samples;
int32_t num_events;
int32_t is_primary;
@@ -62,10 +63,11 @@ typedef struct xenoprof_init {
int32_t bufsize;
uint64_t buf_maddr;
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
-} xenoprof_init_t;
+};
+typedef struct xenoprof_init xenoprof_init_t;
DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);

-typedef struct xenoprof_counter {
+struct xenoprof_counter {
uint32_t ind;
uint64_t count;
uint32_t enabled;
@@ -74,7 +76,8 @@ typedef struct xenoprof_counter {
uint32_t kernel;
uint32_t user;
uint64_t unit_mask;
-} xenoprof_counter_t;
+};
+typedef struct xenoprof_counter xenoprof_counter_t;
DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);


diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/xen/hypercall.h Mon May 22 14:13:38 2006 -0600
@@ -80,7 +80,7 @@ do_vcpu_op(

extern long
do_acm_op(
- XEN_GUEST_HANDLE(acm_op_t) u_acm_op);
+ int cmd, XEN_GUEST_HANDLE(void) arg);

extern long
do_nmi_op(
diff -r fbf676a36ee4 -r 72c5d8206d48 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon May 22 08:53:26 2006 -0600
+++ b/xen/include/xen/sched.h Mon May 22 14:13:38 2006 -0600
@@ -173,6 +173,7 @@ struct domain_setup_info
unsigned long v_kernend;
unsigned long v_kernentry;
/* Initialised by loader: Private. */
+ unsigned long elf_paddr_offset;
unsigned int load_symtab;
unsigned long symtab_addr;
unsigned long symtab_len;
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/include/asm-x86_64/e820.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/e820.h Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,63 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, setup.S populates a scratch table in the
+ * empty_zero_block that contains a list of usable address/size
+ * duples. setup.c, this information is transferred into the e820map,
+ * and in init.c/numa.c, that new information is used to mark pages
+ * reserved or not.
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#include <linux/mmzone.h>
+
+#define E820MAP 0x2d0 /* our map */
+#define E820MAX 128 /* number of entries in E820MAP */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
+#define E820_NVS 4
+
+#define HIGH_MEMORY (1024*1024)
+
+#define LOWMEMSIZE() (0x9f000)
+
+#ifndef __ASSEMBLY__
+struct e820entry {
+ u64 addr; /* start of memory segment */
+ u64 size; /* size of memory segment */
+ u32 type; /* type of memory segment */
+} __attribute__((packed));
+
+struct e820map {
+ int nr_map;
+ struct e820entry map[E820MAX];
+};
+
+extern unsigned long find_e820_area(unsigned long start, unsigned long end,
+ unsigned size);
+extern void add_memory_region(unsigned long start, unsigned long size,
+ int type);
+extern void setup_memory_region(void);
+extern void contig_e820_setup(void);
+extern unsigned long e820_end_of_ram(void);
+extern void e820_reserve_resources(struct e820entry *e820, int nr_map);
+extern void e820_print_map(char *who);
+extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
+
+extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
+extern void e820_setup_gap(struct e820entry *e820, int nr_map);
+extern unsigned long e820_hole_size(unsigned long start_pfn,
+ unsigned long end_pfn);
+
+extern void __init parse_memopt(char *p, char **end);
+extern void __init parse_memmapopt(char *p, char **end);
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/
diff -r fbf676a36ee4 -r 72c5d8206d48 patches/linux-2.6.16.13/xen-hotplug.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/xen-hotplug.patch Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,11 @@
+--- ../pristine-linux-2.6.16.13/fs/proc/proc_misc.c 2006-05-02 22:38:44.000000000 +0100
++++ ./fs/proc/proc_misc.c 2006-05-22 15:29:34.000000000 +0100
+@@ -433,7 +433,7 @@ static int show_stat(struct seq_file *p,
+ (unsigned long long)cputime64_to_clock_t(irq),
+ (unsigned long long)cputime64_to_clock_t(softirq),
+ (unsigned long long)cputime64_to_clock_t(steal));
+- for_each_online_cpu(i) {
++ for_each_cpu(i) {
+
+ /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
+ user = kstat_cpu(i).cpustat.user;
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/ioemu/hw/acpi.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/acpi.c Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,178 @@
+/*
+ * ACPI emulation
+ *
+ * Copyright (c) 2006 Virtual Iron Software
+ *
+ * This module provides the beginnings of some ACPI emulation.
+ * Initially, this code handles writes to the sleep state
+ * registers. This is done to detect requests to power-off
+ * a guest domain.
+ *
+ * Later, and driven by empirical evidence, additional capabilities
+ * and emulation might be added.
+ *
+ * Currently, the FADT specifies a small register set, of which
+ * only PM1_CNTa is available. In addition, the ASL code specifies
+ * the proper values to write on an S5 (poweroff) request, which
+ * this code understands.
+ *
+ */
+
+#include "vl.h"
+extern FILE* logfile;
+
+// Define some basic offsets to ACPI registers
+
+//#define DEBUG_ACPI
+#define PM1a_STS 0x0
+#define PM1a_EN 0x1
+#define PM1b_STS 0x2
+#define PM1b_EN 0x3
+#define PM1_CNTa 0x4
+#define PM1_CNTb 0x6
+
+// Values within PM1_CNTa that we need for power handling
+
+#define SLP_TYP_MASK 0x1C00
+#define SLP_VAL 0x1C00
+#define SLP_EN 0x2000
+
+// Base ACPI register address
+
+static unsigned int acpi_base = 0;
+
+/* acpi_write_byte - handle byte writes for ACPI I/O region
+ *
+ * Input:
+ * opaque pointer to private data structure (currently NULL)
+ * addr I/O space address to be written
+ * data data to be written
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * none
+ */
+
+static void acpi_write_byte(void *opaque, uint32_t addr, uint32_t data) {
+
+#ifdef DEBUG_ACPI
+ fprintf(logfile, "%s - addr 0x%x, data 0x%x\n", __FUNCTION__, addr, data);
+#endif
+
+ // All byte writes are currently ignored
+
+ return;
+}
+
+/* acpi_write_word - handle word writes for ACPI I/O region
+ *
+ * Input:
+ * opaque pointer to private data structure (currently NULL)
+ * addr I/O space address to be written
+ * data data to be written
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * none
+ */
+
+static void acpi_write_word(void *opaque, uint32_t addr, uint32_t data) {
+
+#ifdef DEBUG_ACPI
+ fprintf(logfile, "%s - addr 0x%x, data 0x%x\n", __FUNCTION__, addr, data);
+#endif
+
+ // Only a write to PM1_CNTa for power operations is handled
+ // All others are ignored
+
+ if (addr == acpi_base + PM1_CNTa) {
+ if ( ( (data & SLP_EN) != 0) &&
+ ( (data & SLP_TYP_MASK) == SLP_VAL) ) {
+ qemu_system_shutdown_request();
+ fprintf(logfile, "%s - ACPI Power State 5 (poweroff) requested\n", __FUNCTION__);
+ }
+ }
+
+ return;
+}
+
+/* acpi_read_byte - handle byte reads for ACPI I/O region
+ *
+ * Input:
+ * opaque pointer to private data structure (currently NULL)
+ * addr I/O space address to be written
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * data read
+ */
+
+static uint32_t acpi_read_byte(void *opaque, uint32_t addr) {
+
+#ifdef DEBUG_ACPI
+ fprintf(logfile, "%s - addr 0x%x\n", __FUNCTION__, addr);
+#endif
+
+ // All reads return 0
+
+ return 0;
+}
+
+/* acpi_read_word - handle word reads for ACPI I/O region
+ *
+ * Input:
+ * opaque pointer to private data structure (currently NULL)
+ * addr I/O space address to be written
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * data read
+ */
+
+static uint32_t acpi_read_word(void *opaque, uint32_t addr) {
+
+#ifdef DEBUG_ACPI
+ fprintf(logfile, "%s - addr 0x%x\n", __FUNCTION__, addr);
+#endif
+
+ // All reads return 0
+
+ return 0;
+}
+
+/* acpi_init - initialize for ACPI I/O space operation handling
+ *
+ * Input:
+ * base base I/O address
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * status
+ */
+
+int acpi_init(unsigned int base) {
+
+ fprintf(logfile, "%s - registering ACPI addresses at 0x%x\n", __FUNCTION__, base);
+
+ // Map 16 bytes of reads/writes for bytes/words
+
+ register_ioport_write(base, 16, sizeof(unsigned char), acpi_write_byte, NULL);
+ register_ioport_read(base, 16, sizeof(unsigned char), acpi_read_byte, NULL);
+
+ register_ioport_write(base, 16, sizeof(unsigned short), acpi_write_word, NULL);
+ register_ioport_read(base, 16, sizeof(unsigned short), acpi_read_word, NULL);
+
+ acpi_base = base;
+
+ return 0;
+}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_ipc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,141 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+//
+// vtpm_ipc.c Implements ipc routines using file io. This file can
+// be replaced with other ipc types.
+//
+// ===================================================================
+
+#include <sys/stat.h>
+#include "vtpm_ipc.h"
+#include "vtpmpriv.h"
+#include "log.h"
+
+int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) {
+ ipc_h->name = name;
+ ipc_h->flags = flags;
+ ipc_h->fh = VTPM_IPC_CLOSED;
+
+ if (create)
+ return(vtpm_ipc_create(ipc_h));
+ else
+ return 0;
+}
+
+// Create the file that needs opening. Used only for FIFOs
+// FYI: This may cause problems in other file IO schemes. We'll see.
+int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
+ int fh;
+ struct stat file_info;
+
+ if ((!ipc_h) || (!ipc_h->name))
+ return -1;
+
+ if ( stat(ipc_h->name, &file_info) == -1) {
+ if ( mkfifo(ipc_h->name, S_IWUSR | S_IRUSR ) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to create fifo %s.\n", ipc_h->name);
+ return -1;
+ }
+ }
+
+ ipc_h->fh = VTPM_IPC_CLOSED;
+
+ return 0;
+}
+
+
+// Read size bytes. If FH isn't open, open it.
+int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size){
+ vtpm_ipc_handle_t *my_ipc_h;
+ int result;
+
+ if (ipc_h) {
+ my_ipc_h = ipc_h;
+ } else {
+ my_ipc_h = alt_ipc_h;
+ }
+
+ if (my_ipc_h->fh == VTPM_IPC_CLOSED) {
+ my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags);
+ }
+
+ if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for reading.\n", my_ipc_h->name);
+ return -1;
+ }
+
+ result = read(my_ipc_h->fh, bytes, size);
+ if (result < 0) {
+ my_ipc_h->fh = VTPM_IPC_CLOSED;
+ }
+
+ return (result);
+}
+
+// Write size bytes. If FH isn't open, open it.
+int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size) {
+ vtpm_ipc_handle_t *my_ipc_h;
+ int result;
+
+ if (ipc_h) {
+ my_ipc_h = ipc_h;
+ } else {
+ my_ipc_h = alt_ipc_h;
+ }
+
+ if (my_ipc_h->fh == VTPM_IPC_CLOSED) {
+ my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags);
+ }
+
+ if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for writing.\n", my_ipc_h->name);
+ return -1;
+ }
+
+ result = write(my_ipc_h->fh, bytes, size);
+ if (result < 0) {
+ my_ipc_h->fh = VTPM_IPC_CLOSED;
+ }
+
+ return (result);
+}
+
+// Mark file as closed and try and close it. Errors not reported.
+void vtpm_ipc_close(vtpm_ipc_handle_t *ipc_h) {
+
+ if (ipc_h) {
+ close(ipc_h->fh);
+ }
+ ipc_h->fh = VTPM_IPC_CLOSED;
+
+}
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_ipc.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/vtpm_ipc.h Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,71 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+//
+// vtpm_ipc.h Header for interprocess communication between VTPM manager
+// and Guests or VTPMs
+//
+// ===================================================================
+
+#ifndef __VTPM_IO_H__
+#define __VTPM_IO_H__
+
+#include "tcg.h"
+
+#define VTPM_IPC_CLOSED -1
+
+// Represents an (somewhat) abstracted io handle.
+typedef struct vtpm_ipc_handle_t {
+ int fh; // IO handle.
+ int flags; // Flags for opening. This may need to become
+ // a void *, but for now files use an int.
+ char *name; // Names for debugging as well as filenames
+ // for file-based io.
+} vtpm_ipc_handle_t;
+
+
+int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create);
+
+// Create the file that needs opening. Used only for FIFOs
+// FYI: This may cause problems in other file IO schemes. We'll see.
+int vtpm_ipc_create(vtpm_ipc_handle_t *ioh);
+
+// Read size bytes. If FH isn't open, open it.
+int vtpm_ipc_read(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size);
+
+// Write size bytes. If FH isn't open, open it.
+int vtpm_ipc_write(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size);
+
+// Mark file as closed and try and close it. Errors not reported.
+void vtpm_ipc_close(vtpm_ipc_handle_t *ioh);
+
+#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_lock.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/vtpm_lock.c Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,63 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+//
+// vtpm_lock.c Provided controlled sync around access to vtpm structures
+//
+// ===================================================================
+
+#include <pthread.h>
+#include "vtpm_lock.h"
+
+static pthread_rwlock_t vtpm_lock;
+
+void vtpm_lock_init() {
+
+ pthread_rwlock_init( &vtpm_lock, NULL);
+}
+
+void vtpm_lock_destroy(){
+ pthread_rwlock_destroy(&vtpm_lock);
+}
+
+void vtpm_lock_rdlock(){
+ pthread_rwlock_rdlock(&vtpm_lock);
+}
+
+void vtpm_lock_wrlock(){
+ pthread_rwlock_wrlock(&vtpm_lock);
+}
+
+void vtpm_lock_unlock(){
+ pthread_rwlock_unlock(&vtpm_lock);
+}
+
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_lock.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/vtpm_lock.h Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,48 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+//
+// vtpm_lock.h Provided controlled sync around access to vtpm structures
+//
+// ===================================================================
+
+#ifndef __VTPM_LOCK_H__
+#define __VTPM_LOCK_H__
+
+void vtpm_lock_init();
+void vtpm_lock_destroy();
+
+void vtpm_lock_rdlock();
+void vtpm_lock_wrlock();
+void vtpm_lock_unlock();
+
+#endif
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/vtpm_manager/manager/vtpm_manager_handler.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,455 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+//
+// vtpm_manager_handler.c
+//
+// This file will house the main logic of the VTPM Manager
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "bsg.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+#include "log.h"
+#include "buffer.h"
+
+#define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%s]: " fmt, thread_name, ##args );
+#define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
+#define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args );
+
+// ---------------------- Prototypes -------------------
+TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
+ TPM_COMMAND_CODE ord,
+ buffer_t *command_buf,
+ buffer_t *result_buf,
+ BOOL is_priv,
+ char *thread_name);
+
+TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
+ vtpm_ipc_handle_t *rx_ipc_h,
+ VTPM_DMI_RESOURCE *dmi_res,
+ BYTE *cmd_header,
+ buffer_t *param_buf,
+ buffer_t *result_buf,
+ char *thread_name);
+
+TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h,
+ vtpm_ipc_handle_t *rx_ipc_h,
+ BOOL fw_tpm, // Forward TPM cmds?
+ vtpm_ipc_handle_t *fw_tx_ipc_h,
+ vtpm_ipc_handle_t *fw_rx_ipc_h,
+ BOOL is_priv,
+ char *thread_name) {
+ TPM_RESULT status = TPM_FAIL; // Should never return
+ UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full;
+ BYTE *cmd_header, *in_param, *out_message;
+ buffer_t *command_buf=NULL, *result_buf=NULL;
+ TPM_TAG tag;
+ TPM_COMMAND_CODE ord;
+ VTPM_DMI_RESOURCE *dmi_res;
+ int size_read, size_write, i;
+
+ cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
+ command_buf = (buffer_t *) malloc(sizeof(buffer_t));
+ result_buf = (buffer_t *) malloc(sizeof(buffer_t));
+
+ // ------------------------ Main Loop --------------------------------
+ while(1) {
+
+ vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name);
+
+ // --------------------- Read Cmd from Sender ----------------
+
+ // Read command header
+ size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+ if (size_read > 0) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[.%d}: 0x", size_read);
+ for (i=0; i<size_read; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Aborting... \n", thread_name);
+ goto abort_command;
+ }
+
+ if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read);
+ goto abort_command;
+ }
+
+ // Unpack header
+ BSG_UnpackList(cmd_header, 4,
+ BSG_TYPE_UINT32, &dmi,
+ BSG_TPM_TAG, &tag,
+ BSG_TYPE_UINT32, &in_param_size,
+ BSG_TPM_COMMAND_CODE, &ord );
+
+ // Using the header info, read the parameters of the command
+ // Note that in_param_size is in the client's context
+ cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+ if (cmd_size > 0) {
+ in_param = (BYTE *) malloc(cmd_size);
+ size_read = vtpm_ipc_read( rx_ipc_h, NULL, in_param, cmd_size);
+ if (size_read > 0) {
+ for (i=0; i<size_read; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
+
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error reading cmd from ipc. Aborting... \n", thread_name);
+ goto abort_command;
+ }
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ if (size_read < (int) cmd_size) {
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
+ goto abort_command;
+ }
+ } else {
+ in_param = NULL;
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+ }
+
+ // Init the buffers used to handle the command and the response
+ if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) ||
+ (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
+ goto abort_command;
+ }
+
+ // -------------- Dispatch Commands to Handlers -----------
+ if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) {
+ vtpm_lock_wrlock();
+ } else {
+ vtpm_lock_rdlock();
+ }
+
+ if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) ||
+ (!dmi_res->connected) ) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi);
+ status = TPM_BAD_PARAMETER;
+ }
+
+ if (tag == VTPM_TAG_REQ) {
+
+ status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name);
+
+ } else { // This is not a VTPM Command at all.
+ if (fw_tpm) {
+ status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name);
+
+ // This means calling the DMI failed, not that the cmd failed in the DMI
+ if (status != TPM_SUCCESS) {
+ goto abort_with_error;
+ }
+ } else {
+ // We are not supposed to forward TPM commands at all.
+ int i;
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
+ for (i=0; i<cmd_size; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
+
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ status = TPM_FAIL;
+ goto abort_with_error;
+ }
+
+ } // end else for is VTPM Command
+
+ // ------------------- Respond to Sender ------------------
+
+ // Errors while handling responses jump here to reply with error messages
+ // NOTE: Currently there are no recoverable errors in multi-VM mode. If one
+ // is added to the code, this ifdef should be removed.
+ // Also note this is NOT referring to errors in commands, but rather
+ // this is about I/O errors and such.
+#ifndef VTPM_MULTI_VM
+ abort_with_error:
+#endif
+
+ // Prepend VTPM header with destination DM stamped
+ out_param_size = buffer_len(result_buf);
+ out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
+ out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
+ out_message = (BYTE *) malloc (out_message_size_full);
+
+ BSG_PackList(out_message, 4,
+ BSG_TYPE_UINT32, (BYTE *) &dmi,
+ BSG_TPM_TAG, (BYTE *) &tag,
+ BSG_TYPE_UINT32, (BYTE *) &out_message_size,
+ BSG_TPM_RESULT, (BYTE *) &status);
+
+ if (buffer_len(result_buf) > 0)
+ memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
+
+ //Note: Send message + dmi_id
+ size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message, out_message_size_full );
+ if (size_write > 0) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
+ for (i=0; i < out_message_size_full; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
+
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name);
+ goto abort_command;
+ }
+ free(out_message);
+
+ if (size_write < (int)out_message_size_full) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, out_message_size_full);
+ goto abort_command;
+ }
+
+ // On certain failures an error message cannot be sent.
+ // This marks the beginning of cleanup in preperation for the next command.
+ abort_command:
+ //free buffers
+ bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+ //free(in_param); // This was converted to command_buf. No need to free
+ if (command_buf != result_buf)
+ buffer_free(result_buf);
+
+ buffer_free(command_buf);
+
+ // If we have a write lock, save the manager table
+ if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&
+ (VTPM_SaveManagerData() != TPM_SUCCESS) ) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n");
+ }
+
+ vtpm_lock_unlock();
+ } // End while(1)
+
+}
+
+/////////////////////////////////////////////////////////////////////////
+TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
+ TPM_COMMAND_CODE ord,
+ buffer_t *command_buf,
+ buffer_t *result_buf,
+ BOOL is_priv,
+ char *thread_name) {
+
+ TPM_RESULT status = TPM_FAIL;
+
+ switch (ord) {
+ case VTPM_ORD_SAVENVM:
+ status= VTPM_Handle_Save_NVM(dmi_res,
+ command_buf,
+ result_buf);
+ break;
+
+ case VTPM_ORD_LOADNVM:
+ status= VTPM_Handle_Load_NVM(dmi_res,
+ command_buf,
+ result_buf);
+ break;
+
+ case VTPM_ORD_TPMCOMMAND:
+ status= VTPM_Handle_TPM_Command(dmi_res,
+ command_buf,
+ result_buf);
+ break;
+
+ default:
+ // Privileged handlers can do maintanance
+ if (is_priv) {
+ switch (ord) {
+ case VTPM_ORD_OPEN:
+ status = VTPM_Handle_New_DMI(command_buf);
+ break;
+
+ case VTPM_ORD_CLOSE:
+ status = VTPM_Handle_Close_DMI(command_buf);
+ break;
+
+ case VTPM_ORD_DELETE:
+ status = VTPM_Handle_Delete_DMI(command_buf);
+ break;
+
+ default:
+ status = TPM_BAD_ORDINAL;
+ } // switch
+ } else { // is priv command
+
+ status = TPM_BAD_ORDINAL;
+ } // inner switch
+ } // outer switch
+
+ return(status);
+}
+
+/////////////////////////////////////////////////////////////////////
+TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
+ vtpm_ipc_handle_t *rx_ipc_h,
+ VTPM_DMI_RESOURCE *dmi_res,
+ BYTE *cmd_header,
+ buffer_t *param_buf,
+ buffer_t *result_buf,
+ char *thread_name) {
+
+ TPM_RESULT status = TPM_FAIL;
+ UINT32 dmi_dst;
+ TPM_COMMAND_CODE ord;
+ TPM_TAG tag_out;
+ UINT32 dmi_cmd_size, in_param_size, adj_param_size;
+ BYTE *dmi_cmd, *in_param;
+ int size_read, size_write, i;
+
+ //// Dom0 can't talk to the BE, so this must be a broken FE/BE or badness
+ if (dmi_res->dmi_id == VTPM_CTL_DM) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n");
+ status = TPM_FAIL;
+ goto abort_with_error;
+ }
+
+ vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
+
+ //Forward TPM CMD stamped with dmi_id to DMI for handling
+ if (buffer_len(param_buf)) {
+ dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf));
+ dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf);
+ memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+ memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, param_buf->bytes, buffer_len(param_buf));
+ size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, dmi_cmd, dmi_cmd_size);
+
+ if (size_write > 0) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
+ for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf); i++) {
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
+ }
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
+ status = TPM_IOERROR;
+ goto abort_with_error;
+ }
+ free(dmi_cmd);
+ } else {
+ dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
+ size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
+ if (size_write > 0) {
+ for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
+
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
+ status = TPM_IOERROR;
+ goto abort_with_error;
+ }
+ }
+
+ if (size_write != (int) dmi_cmd_size)
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size);
+
+ buffer_free(param_buf);
+
+ // Read header for response to TPM command from DMI
+ size_read = vtpm_ipc_read( rx_ipc_h, dmi_res->rx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+ if (size_read > 0) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
+ for (i=0; i<size_read; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
+
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n");
+ status = TPM_IOERROR;
+ goto abort_with_error;
+ }
+
+ if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n");
+ status = TPM_IOERROR;
+ goto abort_with_error;
+ }
+
+ // Unpack response from DMI for TPM command
+ BSG_UnpackList(cmd_header, 4,
+ BSG_TYPE_UINT32, &dmi_dst,
+ BSG_TPM_TAG, &tag_out,
+ BSG_TYPE_UINT32, &in_param_size,
+ BSG_TPM_COMMAND_CODE, &status );
+
+ // If response has parameters, read them.
+ // Note that in_param_size is in the client's context
+ adj_param_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+ if (adj_param_size > 0) {
+ in_param = (BYTE *) malloc(adj_param_size);
+ size_read = vtpm_ipc_read(rx_ipc_h, dmi_res->rx_tpm_ipc_h, in_param, adj_param_size);
+ if (size_read > 0) {
+ for (i=0; i<size_read; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
+
+ } else {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
+ goto abort_with_error;
+ }
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+
+ if (size_read < (int)adj_param_size) {
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, adj_param_size);
+ status = TPM_IOERROR;
+ goto abort_with_error;
+ }
+ } else {
+ in_param = NULL;
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+ }
+
+ if (buffer_init_convert(result_buf, adj_param_size, in_param) != TPM_SUCCESS) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
+ status = TPM_FAIL;
+ goto abort_with_error;
+ }
+
+ vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n");
+
+ status = TPM_SUCCESS;
+
+ abort_with_error:
+
+ return status;
+}
+
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/block-integrity/01_block_device_read_verify.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/block-integrity/01_block_device_read_verify.py Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Harry Butterworth <butterwo@uk.ibm.com>
+
+# This test initialises a ram disk in dom0 with data from /dev/urandom and
+# then imports the ram disk device as a physical device into a domU. The md5
+# checksum of the data in the ramdisk is calculated in dom0 and also
+# calculated by the domU reading the data through the blk frontend and
+# backend drivers. The test succeeds if the checksums match indicating that
+# the domU successfully read all the correct data from the device.
+
+import re
+
+from XmTestLib import *
+from XmTestLib.block_utils import *
+
+if ENABLE_HVM_SUPPORT:
+ SKIP("Block-attach not supported for HVM domains")
+
+domain = XmTestDomain()
+
+try:
+ console = domain.start()
+except DomainError, e:
+ FAIL(str(e))
+
+console.setHistorySaveCmds(value=True)
+
+traceCommand("cat /dev/urandom > /dev/ram1")
+
+s, o = traceCommand("md5sum /dev/ram1")
+
+dom0_md5sum_match = re.search(r"^[\dA-Fa-f]{32}", o)
+
+block_attach(domain, "phy:ram1", "hda1")
+
+try:
+ run = console.runCmd("md5sum /dev/hda1")
+except ConsoleError, e:
+ FAIL(str(e))
+
+domU_md5sum_match = re.search(r"^[\dA-Fa-f]{32}", run["output"])
+
+domain.closeConsole()
+
+domain.stop()
+
+if dom0_md5sum_match == None:
+ FAIL("Failed to get md5sum of test ram disk in dom0.")
+
+if domU_md5sum_match == None:
+ FAIL("Failed to get md5sum of test ram disk in domU.")
+
+if verbose:
+ print "md5sum dom0:"
+ print dom0_md5sum_match.group()
+ print "md5sum domU:"
+ print domU_md5sum_match.group()
+
+if dom0_md5sum_match.group() != domU_md5sum_match.group():
+ FAIL("MISCOMPARE: data read in domU did not match data provided by domO.")
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/block-integrity/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/block-integrity/Makefile.am Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,21 @@
+
+SUBDIRS =
+
+TESTS = 01_block_device_read_verify.test
+
+XFAIL_TESTS =
+
+EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+
+TESTS_ENVIRONMENT=@TENV@
+
+%.test: %.py
+ cp $< $@
+ chmod +x $@
+
+clean-local: am_config_clean-local
+
+am_config_clean-local:
+ rm -f *test
+ rm -f *log
+ rm -f *~
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py Mon May 22 14:13:38 2006 -0600
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@us.ibm.com>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+# check list of pcrs; locally migrate the domain and
+# check list of pcrs again
+# This test does local (non-live) migration.
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+consoleHistory = ""
+
+try:
+ console = domain.start()
+except DomainError, e:
+ if verbose:
+ print e.extra
+ vtpm_cleanup(domain.getName())
+ FAIL("Unable to create domain")
+
+domName = domain.getName()
+
+try:
+ console.sendInput("input")
+except ConsoleError, e:
+ saveLog(console.getHistory())
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+
+try:
+ run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+except ConsoleError, e:
+ saveLog(console.getHistory())
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+
+if re.search("No such file",run["output"]):
+ vtpm_cleanup(domName)
+ FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+old_domid = domid(domName)
+
+loop = 0
+while loop < 3:
+ try:
+ status, ouptut = traceCommand("xm migrate %s localhost" %
+ domName,
+ timeout=90)
+ except TimeoutError, e:
+ saveLog(consoleHistory)
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+
+ if status != 0:
+ saveLog(consoleHistory)
+ vtpm_cleanup(domName)
+ FAIL("xm migrate did not succeed. External device migration activated?")
+
+
+ domName = domain.getName()
+ new_domid = domid(domName)
+
+ if (old_domid == new_domid):
+ vtpm_cleanup(domName)
+ FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+ (old_domid,loop))
+
+ try:
+ console = domain.getConsole()
+ except ConsoleError, e:
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+
+ try:
+ run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+ except ConsoleError, e:
+ saveLog(console.getHistory())
+ vtpm_cleanup(domName)
+ FAIL(str(e))
+ loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)
+
+if not re.search("PCR-00:",run["output"]):
+ FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
diff -r fbf676a36ee4 -r 72c5d8206d48 linux-2.6-xen-sparse/arch/ia64/xen/xen_ksyms.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xen_ksyms.c Mon May 22 08:53:26 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-/*
- * Architecture-specific kernel symbols
- *
- * Don't put any exports here unless it's defined in an assembler file.
- * All other exports should be put directly after the definition.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-extern int is_running_on_xen(void);
-EXPORT_SYMBOL(is_running_on_xen);
diff -r fbf676a36ee4 -r 72c5d8206d48 tools/xentrace/tbctl.c
--- a/tools/xentrace/tbctl.c Mon May 22 08:53:26 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <xenctrl.h>
-
-int main(int argc, char * argv[])
-{
- int enable;
- int xc_handle = xc_interface_open();
-
- if (argc < 2) {
- printf("usage: %s [0|1]\n", argv[0]);
- exit(1);
- }
- enable = atoi(argv[1]);
-
- if (xc_tbuf_enable(xc_handle, enable) != 0) {
- perror("Enable/Disable Hypercall failure");
- exit(1);
- }
- else
- printf("Tracing now %s\n", (enable ? "enabled" : "disabled"));
-
- xc_interface_close(xc_handle);
- return 0;
-}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog
merge with xen-unstable.hg [ In reply to ]
# HG changeset patch
# User awilliam@xenbuild.aw
# Node ID c073ebdbde8c0f5c9437706b46c4a34f35033c0c
# Parent 9d52a66c74996a66adf5ee71a0d7f91bb880f7fb
# Parent 954f4dea9da6336aaa35d0706aed55fde7909644
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/drivers/xen/net_driver_util.c | 58
linux-2.6-xen-sparse/include/asm-x86_64/e820.h | 63
linux-2.6-xen-sparse/include/xen/net_driver_util.h | 48
tools/xenstore/xenstored_proc.h | 27
.hgignore | 2
extras/mini-os/Makefile | 9
extras/mini-os/lib/printf.c | 4
extras/mini-os/lib/string.c | 4
linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile | 1
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 2
linux-2.6-xen-sparse/drivers/xen/Makefile | 1
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 8
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 2
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 2
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c | 4
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c | 2
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 2
linux-2.6-xen-sparse/drivers/xen/console/console.c | 28
linux-2.6-xen-sparse/drivers/xen/core/Makefile | 11
linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c | 185 +
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 31
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 3
linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 9
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 215 --
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 4
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 31
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 56
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c | 2
linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c | 4
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 23
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c | 6
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 8
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 4
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/e820.h | 63
linux-2.6-xen-sparse/include/xen/cpu_hotplug.h | 42
linux-2.6-xen-sparse/include/xen/xenbus.h | 8
patches/linux-2.6.16.13/fix-ide-cd-pio-mode.patch | 13
tools/libxc/Makefile | 1
tools/libxc/xc_csched.c | 50
tools/libxc/xc_linux_build.c | 13
tools/libxc/xc_linux_restore.c | 122 -
tools/libxc/xc_private.c | 22
tools/libxc/xc_ptrace.c | 77
tools/libxc/xc_ptrace.h | 3
tools/libxc/xc_ptrace_core.c | 7
tools/libxc/xc_tbuf.c | 56
tools/libxc/xenctrl.h | 11
tools/libxc/xg_private.h | 10
tools/python/xen/lowlevel/xc/xc.c | 61
tools/python/xen/lowlevel/xs/xs.c | 11
tools/python/xen/xend/XendDomain.py | 22
tools/python/xen/xend/XendDomainInfo.py | 14
tools/python/xen/xend/balloon.py | 11
tools/python/xen/xend/server/SrvDomain.py | 14
tools/python/xen/xend/xenstore/xstransact.py | 28
tools/python/xen/xm/main.py | 45
tools/tests/test_x86_emulator.c | 67
tools/xenstore/Makefile | 8
tools/xenstore/xenstored_core.c | 7
tools/xenstore/xenstored_core.h | 8
tools/xenstore/xenstored_domain.c | 37
tools/xenstore/xenstored_linux.c | 69
xen/arch/x86/domain_build.c | 5
xen/arch/x86/hvm/hvm.c | 16
xen/arch/x86/hvm/i8254.c | 405 +--
xen/arch/x86/hvm/intercept.c | 82
xen/arch/x86/hvm/svm/intr.c | 47
xen/arch/x86/hvm/svm/svm.c | 44
xen/arch/x86/hvm/svm/vmcb.c | 14
xen/arch/x86/hvm/vmx/io.c | 62
xen/arch/x86/hvm/vmx/vmx.c | 37
xen/arch/x86/mm.c | 129 +
xen/arch/x86/traps.c | 4
xen/arch/x86/x86_emulate.c | 81
xen/common/Makefile | 1
xen/common/grant_table.c | 15
xen/common/kernel.c | 5
xen/common/sched_credit.c | 1233 ++++++++++++
xen/common/schedule.c | 5
xen/common/trace.c | 6
xen/include/asm-x86/domain.h | 12
xen/include/asm-x86/hvm/domain.h | 6
xen/include/asm-x86/hvm/svm/intr.h | 1
xen/include/asm-x86/hvm/svm/svm.h | 1
xen/include/asm-x86/hvm/vcpu.h | 3
xen/include/asm-x86/hvm/vmx/vmx.h | 1
xen/include/asm-x86/hvm/vpit.h | 67
xen/include/asm-x86/string.h | 162 -
xen/include/asm-x86/x86_emulate.h | 66
xen/include/public/io/xenbus.h | 59
xen/include/public/sched_ctl.h | 5
xen/include/xen/sched-if.h | 2
xen/include/xen/softirq.h | 13
93 files changed, 2802 insertions(+), 1546 deletions(-)

diff -r 9d52a66c7499 -r c073ebdbde8c .hgignore
--- a/.hgignore Thu May 25 15:59:18 2006 -0600
+++ b/.hgignore Fri May 26 13:41:49 2006 -0600
@@ -14,7 +14,7 @@
.*\.orig$
.*\.rej$
.*/a\.out$
-.*/cscope\.*$
+.*/cscope\..*$
^[^/]*\.bz2$
^TAGS$
^dist/.*$
diff -r 9d52a66c7499 -r c073ebdbde8c extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/extras/mini-os/Makefile Fri May 26 13:41:49 2006 -0600
@@ -13,6 +13,7 @@ override CPPFLAGS := -Iinclude $(CPPFLAG
override CPPFLAGS := -Iinclude $(CPPFLAGS)
ASFLAGS = -D__ASSEMBLY__

+LDLIBS = -L. -lminios
LDFLAGS := -N -T minios-$(TARGET_ARCH).lds

ifeq ($(TARGET_ARCH),x86_32)
@@ -55,11 +56,11 @@ links:
links:
[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen

-libminios.a: $(OBJS) $(HEAD)
- ar r libminios.a $(HEAD) $(OBJS)
+libminios.a: links $(OBJS) $(HEAD)
+ $(AR) r libminios.a $(HEAD) $(OBJS)

-$(TARGET): links libminios.a $(HEAD)
- $(LD) $(LDFLAGS) $(HEAD) -L. -lminios -o $@.elf
+$(TARGET): libminios.a $(HEAD)
+ $(LD) $(LDFLAGS) $(HEAD) $(LDLIBS) -o $@.elf
gzip -f -9 -c $@.elf >$@.gz

.PHONY: clean
diff -r 9d52a66c7499 -r c073ebdbde8c extras/mini-os/lib/printf.c
--- a/extras/mini-os/lib/printf.c Thu May 25 15:59:18 2006 -0600
+++ b/extras/mini-os/lib/printf.c Fri May 26 13:41:49 2006 -0600
@@ -53,6 +53,8 @@
*
* $FreeBSD: src/sys/libkern/divdi3.c,v 1.6 1999/08/28 00:46:31 peter Exp $
*/
+
+#if !defined HAVE_LIBC

#include <os.h>
#include <types.h>
@@ -789,4 +791,4 @@ int sscanf(const char * buf, const char
return i;
}

-
+#endif
diff -r 9d52a66c7499 -r c073ebdbde8c extras/mini-os/lib/string.c
--- a/extras/mini-os/lib/string.c Thu May 25 15:59:18 2006 -0600
+++ b/extras/mini-os/lib/string.c Fri May 26 13:41:49 2006 -0600
@@ -17,6 +17,8 @@
* $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
****************************************************************************
*/
+
+#if !defined HAVE_LIBC

#include <os.h>
#include <types.h>
@@ -153,3 +155,5 @@ char * strstr(const char * s1,const char
}
return NULL;
}
+
+#endif
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile Fri May 26 13:41:49 2006 -0600
@@ -2,7 +2,6 @@ ifneq ($(CONFIG_XEN_IA64_DOM0_VP),y)
ifneq ($(CONFIG_XEN_IA64_DOM0_VP),y)
obj-y += util.o
endif
-obj-$(CONFIG_XEN_IA64_DOM0_VP) += net_driver_util.o

obj-y += core/
#obj-y += char/
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Fri May 26 13:41:49 2006 -0600
@@ -329,7 +329,7 @@ out:
* Callback received when the backend's state changes.
*/
static void backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
+ enum xenbus_state backend_state)
{
struct tpm_private *tp = dev->data;
DPRINTK("\n");
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Fri May 26 13:41:49 2006 -0600
@@ -1,5 +1,4 @@

-obj-y += net_driver_util.o
obj-y += util.o

obj-y += core/
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Fri May 26 13:41:49 2006 -0600
@@ -67,7 +67,7 @@ static DECLARE_MUTEX(balloon_mutex);
* Also protects non-atomic updates of current_pages and driver_pages, and
* balloon lists.
*/
-spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(balloon_lock);

/* We aim for 'current allocation' == 'target allocation'. */
static unsigned long current_pages;
@@ -360,6 +360,12 @@ static void balloon_process(void *unused
/* Resets the Xen limit, sets new target, and kicks off processing. */
static void set_new_target(unsigned long target)
{
+ unsigned long min_target;
+
+ /* Do not allow target to reduce below 2% of maximum memory size. */
+ min_target = max_pfn / 50;
+ target = max(target, min_target);
+
/* No need for lock. Not read-modify-write updates. */
hard_limit = ~0UL;
target_pages = target;
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Fri May 26 13:41:49 2006 -0600
@@ -82,7 +82,7 @@ typedef struct {

static pending_req_t *pending_reqs;
static struct list_head pending_free;
-static spinlock_t pending_free_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pending_free_lock);
static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);

#define BLKBACK_INVALID_HANDLE (~0)
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri May 26 13:41:49 2006 -0600
@@ -247,7 +247,7 @@ static void backend_changed(struct xenbu
* Callback received when the frontend's state changes.
*/
static void frontend_changed(struct xenbus_device *dev,
- XenbusState frontend_state)
+ enum xenbus_state frontend_state)
{
struct backend_info *be = dev->data;
int err;
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri May 26 13:41:49 2006 -0600
@@ -247,7 +247,7 @@ fail:
* Callback received when the backend's state changes.
*/
static void backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
+ enum xenbus_state backend_state)
{
struct blkfront_info *info = dev->data;
struct block_device *bd;
@@ -434,7 +434,7 @@ int blkif_release(struct inode *inode, s
have ignored this request initially, as the device was
still mounted. */
struct xenbus_device * dev = info->xbdev;
- XenbusState state = xenbus_read_driver_state(dev->otherend);
+ enum xenbus_state state = xenbus_read_driver_state(dev->otherend);

if (state == XenbusStateClosing)
blkfront_closing(dev);
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Fri May 26 13:41:49 2006 -0600
@@ -93,7 +93,7 @@ static struct block_device_operations xl
.ioctl = blkif_ioctl,
};

-spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(blkif_io_lock);

static struct xlbd_major_info *
xlbd_alloc_major_info(int major, int minor, int index)
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri May 26 13:41:49 2006 -0600
@@ -138,7 +138,7 @@ typedef struct {
*/
static pending_req_t pending_reqs[MAX_PENDING_REQS];
static unsigned char pending_ring[MAX_PENDING_REQS];
-static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pend_prod_lock);
/* NB. We use a different index type to differentiate from shared blk rings. */
typedef unsigned int PEND_RING_IDX;
#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Fri May 26 13:41:49 2006 -0600
@@ -117,14 +117,17 @@ static int __init xencons_bufsz_setup(ch
{
unsigned int goal;
goal = simple_strtoul(str, NULL, 0);
- while (wbuf_size < goal)
- wbuf_size <<= 1;
+ if (goal) {
+ goal = roundup_pow_of_two(goal);
+ if (wbuf_size < goal)
+ wbuf_size = goal;
+ }
return 1;
}
__setup("xencons_bufsz=", xencons_bufsz_setup);

/* This lock protects accesses to the common transmit buffer. */
-static spinlock_t xencons_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xencons_lock);

/* Common transmit-kick routine. */
static void __xencons_tx_flush(void);
@@ -133,8 +136,7 @@ static struct tty_driver *xencons_driver

/******************** Kernel console driver ********************************/

-static void kcons_write(
- struct console *c, const char *s, unsigned int count)
+static void kcons_write(struct console *c, const char *s, unsigned int count)
{
int i = 0;
unsigned long flags;
@@ -155,14 +157,14 @@ static void kcons_write(
spin_unlock_irqrestore(&xencons_lock, flags);
}

-static void kcons_write_dom0(
- struct console *c, const char *s, unsigned int count)
-{
- int rc;
-
- while ((count > 0) &&
- ((rc = HYPERVISOR_console_io(
- CONSOLEIO_write, count, (char *)s)) > 0)) {
+static void kcons_write_dom0(struct console *c, const char *s, unsigned int count)
+{
+
+ while (count > 0) {
+ int rc;
+ rc = HYPERVISOR_console_io( CONSOLEIO_write, count, (char *)s);
+ if (rc <= 0)
+ break;
count -= rc;
s += rc;
}
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Fri May 26 13:41:49 2006 -0600
@@ -4,8 +4,9 @@

obj-y := evtchn.o reboot.o gnttab.o features.o

-obj-$(CONFIG_PROC_FS) += xen_proc.o
-obj-$(CONFIG_NET) += skbuff.o
-obj-$(CONFIG_SMP) += smpboot.o
-obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o
-obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o
+obj-$(CONFIG_PROC_FS) += xen_proc.o
+obj-$(CONFIG_NET) += skbuff.o
+obj-$(CONFIG_SMP) += smpboot.o
+obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
+obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o
+obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Fri May 26 13:41:49 2006 -0600
@@ -51,10 +51,10 @@
* This lock protects updates to the following mapping and reference-count
* arrays. The lock does not need to be acquired to read the mapping tables.
*/
-static spinlock_t irq_mapping_update_lock;
+static DEFINE_SPINLOCK(irq_mapping_update_lock);

/* IRQ <-> event-channel mappings. */
-static int evtchn_to_irq[NR_EVENT_CHANNELS];
+static int evtchn_to_irq[NR_EVENT_CHANNELS] = {[0 ... NR_EVENT_CHANNELS-1] = -1};

/* Packed IRQ information: binding type, sub-type index, and event channel. */
static u32 irq_info[NR_IRQS];
@@ -91,13 +91,13 @@ static inline unsigned int type_from_irq
}

/* IRQ <-> VIRQ mapping. */
-DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
+DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};

/* IRQ <-> IPI mapping. */
#ifndef NR_IPIS
#define NR_IPIS 1
#endif
-DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
+DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1};

/* Reference counts for bindings to IRQs. */
static int irq_bindcount[NR_IRQS];
@@ -751,7 +751,9 @@ void irq_resume(void)
BUG_ON(irq_info[pirq_to_irq(pirq)] != IRQ_UNBOUND);

/* Secondary CPUs must have no VIRQ or IPI bindings. */
- for (cpu = 1; cpu < NR_CPUS; cpu++) {
+ for_each_possible_cpu(cpu) {
+ if (cpu == 0)
+ continue;
for (virq = 0; virq < NR_VIRQS; virq++)
BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
for (ipi = 0; ipi < NR_IPIS; ipi++)
@@ -813,25 +815,12 @@ void __init xen_init_IRQ(void)
void __init xen_init_IRQ(void)
{
int i;
- int cpu;
-
- spin_lock_init(&irq_mapping_update_lock);

init_evtchn_cpu_bindings();

- /* No VIRQ or IPI bindings. */
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- for (i = 0; i < NR_VIRQS; i++)
- per_cpu(virq_to_irq, cpu)[i] = -1;
- for (i = 0; i < NR_IPIS; i++)
- per_cpu(ipi_to_irq, cpu)[i] = -1;
- }
-
- /* No event-channel -> IRQ mappings. */
- for (i = 0; i < NR_EVENT_CHANNELS; i++) {
- evtchn_to_irq[i] = -1;
- mask_evtchn(i); /* No event channels are 'live' right now. */
- }
+ /* No event channels are 'live' right now. */
+ for (i = 0; i < NR_EVENT_CHANNELS; i++)
+ mask_evtchn(i);

/* No IRQ -> event-channel mappings. */
for (i = 0; i < NR_IRQS; i++)
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Fri May 26 13:41:49 2006 -0600
@@ -38,7 +38,6 @@
#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include <xen/interface/xen.h>
-#include <asm/fixmap.h>
#include <asm/uaccess.h>
#include <xen/gnttab.h>
#include <asm/synch_bitops.h>
@@ -81,7 +80,7 @@ static grant_ref_t gnttab_list[NR_GRANT_
static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
static int gnttab_free_count;
static grant_ref_t gnttab_free_head;
-static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(gnttab_list_lock);

static grant_entry_t *shared = NULL;

diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri May 26 13:41:49 2006 -0600
@@ -17,6 +17,7 @@
#include <linux/kthread.h>
#include <xen/gnttab.h>
#include <xen/xencons.h>
+#include <xen/cpu_hotplug.h>

#if defined(__i386__) || defined(__x86_64__)
/*
@@ -80,14 +81,6 @@ static int shutting_down = SHUTDOWN_INVA
static int shutting_down = SHUTDOWN_INVALID;
static void __shutdown_handler(void *unused);
static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
-
-#ifdef CONFIG_SMP
-int smp_suspend(void);
-void smp_resume(void);
-#else
-#define smp_suspend() (0)
-#define smp_resume() ((void)0)
-#endif

/* Ensure we run on the idle task page tables so that we will
switch page tables before running user space. This is needed
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Fri May 26 13:41:49 2006 -0600
@@ -23,6 +23,7 @@
#include <asm/pgalloc.h>
#include <xen/evtchn.h>
#include <xen/interface/vcpu.h>
+#include <xen/cpu_hotplug.h>
#include <xen/xenbus.h>

#ifdef CONFIG_SMP_ALTERNATIVES
@@ -78,15 +79,6 @@ EXPORT_SYMBOL(x86_cpu_to_apicid);
#elif !defined(CONFIG_X86_IO_APIC)
unsigned int maxcpus = NR_CPUS;
#endif
-
-/*
- * Set of CPUs that remote admin software will allow us to bring online.
- * Notified to us via xenbus.
- */
-static cpumask_t xenbus_allowed_cpumask;
-
-/* Set of CPUs that local admin will allow us to bring online. */
-static cpumask_t local_allowed_cpumask = CPU_MASK_ALL;

void __init prefill_possible_map(void)
{
@@ -167,17 +159,17 @@ static void cpu_bringup(void)
cpu_idle();
}

-static void vcpu_prepare(int vcpu)
+void cpu_initialize_context(unsigned int cpu)
{
vcpu_guest_context_t ctxt;
- struct task_struct *idle = idle_task(vcpu);
+ struct task_struct *idle = idle_task(cpu);
#ifdef __x86_64__
- struct desc_ptr *gdt_descr = &cpu_gdt_descr[vcpu];
+ struct desc_ptr *gdt_descr = &cpu_gdt_descr[cpu];
#else
- struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, vcpu);
-#endif
-
- if (vcpu == 0)
+ struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
+#endif
+
+ if (cpu == 0)
return;

memset(&ctxt, 0, sizeof(ctxt));
@@ -226,10 +218,10 @@ static void vcpu_prepare(int vcpu)

ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;

- ctxt.gs_base_kernel = (unsigned long)(cpu_pda(vcpu));
-#endif
-
- BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt));
+ ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
+#endif
+
+ BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt));
}

void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -304,10 +296,10 @@ void __init smp_prepare_cpus(unsigned in
cpu_set(cpu, cpu_present_map);
#endif

- vcpu_prepare(cpu);
- }
-
- xenbus_allowed_cpumask = cpu_present_map;
+ cpu_initialize_context(cpu);
+ }
+
+ init_xenbus_allowed_cpumask();

/* Currently, Xen gives no dynamic NUMA/HT info. */
for (cpu = 1; cpu < NR_CPUS; cpu++) {
@@ -332,15 +324,6 @@ void __devinit smp_prepare_boot_cpu(void
cpu_online_map = cpumask_of_cpu(0);
}

-static int local_cpu_hotplug_request(void)
-{
- /*
- * We assume a CPU hotplug request comes from local admin if it is made
- * via a userspace process (i.e., one with a real mm_struct).
- */
- return (current->mm != NULL);
-}
-
#ifdef CONFIG_HOTPLUG_CPU

/*
@@ -355,141 +338,6 @@ static int __init initialize_cpu_present
}
core_initcall(initialize_cpu_present_map);

-static void vcpu_hotplug(unsigned int cpu)
-{
- int err;
- char dir[32], state[32];
-
- if ((cpu >= NR_CPUS) || !cpu_possible(cpu))
- return;
-
- sprintf(dir, "cpu/%d", cpu);
- err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state);
- if (err != 1) {
- printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
- return;
- }
-
- if (strcmp(state, "online") == 0) {
- cpu_set(cpu, xenbus_allowed_cpumask);
- (void)cpu_up(cpu);
- } else if (strcmp(state, "offline") == 0) {
- cpu_clear(cpu, xenbus_allowed_cpumask);
- (void)cpu_down(cpu);
- } else {
- printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
- state, cpu);
- }
-}
-
-static void handle_vcpu_hotplug_event(
- struct xenbus_watch *watch, const char **vec, unsigned int len)
-{
- int cpu;
- char *cpustr;
- const char *node = vec[XS_WATCH_PATH];
-
- if ((cpustr = strstr(node, "cpu/")) != NULL) {
- sscanf(cpustr, "cpu/%d", &cpu);
- vcpu_hotplug(cpu);
- }
-}
-
-static int smpboot_cpu_notify(struct notifier_block *notifier,
- unsigned long action, void *hcpu)
-{
- int cpu = (long)hcpu;
-
- /*
- * We do this in a callback notifier rather than __cpu_disable()
- * because local_cpu_hotplug_request() does not work in the latter
- * as it's always executed from within a stopmachine kthread.
- */
- if ((action == CPU_DOWN_PREPARE) && local_cpu_hotplug_request())
- cpu_clear(cpu, local_allowed_cpumask);
-
- return NOTIFY_OK;
-}
-
-static int setup_cpu_watcher(struct notifier_block *notifier,
- unsigned long event, void *data)
-{
- int i;
-
- static struct xenbus_watch cpu_watch = {
- .node = "cpu",
- .callback = handle_vcpu_hotplug_event,
- .flags = XBWF_new_thread };
- (void)register_xenbus_watch(&cpu_watch);
-
- if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
- for_each_cpu(i)
- vcpu_hotplug(i);
- printk(KERN_INFO "Brought up %ld CPUs\n",
- (long)num_online_cpus());
- }
-
- return NOTIFY_DONE;
-}
-
-static int __init setup_vcpu_hotplug_event(void)
-{
- static struct notifier_block hotplug_cpu = {
- .notifier_call = smpboot_cpu_notify };
- static struct notifier_block xsn_cpu = {
- .notifier_call = setup_cpu_watcher };
-
- register_cpu_notifier(&hotplug_cpu);
- register_xenstore_notifier(&xsn_cpu);
-
- return 0;
-}
-
-arch_initcall(setup_vcpu_hotplug_event);
-
-int smp_suspend(void)
-{
- int i, err;
-
- lock_cpu_hotplug();
-
- /*
- * Take all other CPUs offline. We hold the hotplug mutex to
- * avoid other processes bringing up CPUs under our feet.
- */
- while (num_online_cpus() > 1) {
- unlock_cpu_hotplug();
- for_each_online_cpu(i) {
- if (i == 0)
- continue;
- err = cpu_down(i);
- if (err) {
- printk(KERN_CRIT "Failed to take all CPUs "
- "down: %d.\n", err);
- for_each_cpu(i)
- vcpu_hotplug(i);
- return err;
- }
- }
- lock_cpu_hotplug();
- }
-
- return 0;
-}
-
-void smp_resume(void)
-{
- int i;
-
- for_each_cpu(i)
- vcpu_prepare(i);
-
- unlock_cpu_hotplug();
-
- for_each_cpu(i)
- vcpu_hotplug(i);
-}
-
static void
remove_siblinginfo(int cpu)
{
@@ -536,20 +384,6 @@ void __cpu_die(unsigned int cpu)

#else /* !CONFIG_HOTPLUG_CPU */

-int smp_suspend(void)
-{
- if (num_online_cpus() > 1) {
- printk(KERN_WARNING "Can't suspend SMP guests "
- "without CONFIG_HOTPLUG_CPU\n");
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-void smp_resume(void)
-{
-}
-
int __cpu_disable(void)
{
return -ENOSYS;
@@ -566,17 +400,9 @@ int __devinit __cpu_up(unsigned int cpu)
{
int rc;

- if (local_cpu_hotplug_request()) {
- cpu_set(cpu, local_allowed_cpumask);
- if (!cpu_isset(cpu, xenbus_allowed_cpumask)) {
- printk("%s: attempt to bring up CPU %u disallowed by "
- "remote admin.\n", __FUNCTION__, cpu);
- return -EBUSY;
- }
- } else if (!cpu_isset(cpu, local_allowed_cpumask) ||
- !cpu_isset(cpu, xenbus_allowed_cpumask)) {
- return -EBUSY;
- }
+ rc = cpu_up_is_allowed(cpu);
+ if (rc)
+ return rc;

#ifdef CONFIG_SMP_ALTERNATIVES
if (num_online_cpus() == 1)
@@ -591,8 +417,7 @@ int __devinit __cpu_up(unsigned int cpu)
cpu_set(cpu, cpu_online_map);

rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
- if (rc != 0)
- BUG();
+ BUG_ON(rc);

return 0;
}
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri May 26 13:41:49 2006 -0600
@@ -99,7 +99,7 @@ static spinlock_t net_schedule_list_lock
#define MAX_MFN_ALLOC 64
static unsigned long mfn_list[MAX_MFN_ALLOC];
static unsigned int alloc_index = 0;
-static spinlock_t mfn_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mfn_lock);

static unsigned long alloc_mfn(void)
{
@@ -691,7 +691,7 @@ static void net_tx_action(unsigned long

static void netif_idx_release(u16 pending_idx)
{
- static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(_lock);
unsigned long flags;

spin_lock_irqsave(&_lock, flags);
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri May 26 13:41:49 2006 -0600
@@ -17,13 +17,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

-
#include <stdarg.h>
#include <linux/module.h>
#include <xen/xenbus.h>
-#include <xen/net_driver_util.h>
#include "common.h"
-

#if 0
#undef DPRINTK
@@ -31,22 +28,19 @@
printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
#endif

-
struct backend_info
{
struct xenbus_device *dev;
netif_t *netif;
struct xenbus_watch backend_watch;
- XenbusState frontend_state;
+ enum xenbus_state frontend_state;
};
-

static int connect_rings(struct backend_info *);
static void connect(struct backend_info *);
static void maybe_connect(struct backend_info *);
static void backend_changed(struct xenbus_watch *, const char **,
unsigned int);
-

static int netback_remove(struct xenbus_device *dev)
{
@@ -191,7 +185,7 @@ static void backend_changed(struct xenbu
* Callback received when the frontend's state changes.
*/
static void frontend_changed(struct xenbus_device *dev,
- XenbusState frontend_state)
+ enum xenbus_state frontend_state)
{
struct backend_info *be = dev->data;

@@ -273,6 +267,27 @@ static void xen_net_read_rate(struct xen
kfree(ratestr);
}

+static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
+{
+ char *s, *e, *macstr;
+ int i;
+
+ macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
+ if (IS_ERR(macstr))
+ return PTR_ERR(macstr);
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ mac[i] = simple_strtoul(s, &e, 16);
+ if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
+ kfree(macstr);
+ return -ENOENT;
+ }
+ s = e+1;
+ }
+
+ kfree(macstr);
+ return 0;
+}

static void connect(struct backend_info *be)
{
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri May 26 13:41:49 2006 -0600
@@ -60,7 +60,6 @@
#include <asm/uaccess.h>
#include <xen/interface/grant_table.h>
#include <xen/gnttab.h>
-#include <xen/net_driver_util.h>

#define GRANT_INVALID_REF 0

@@ -88,12 +87,6 @@ struct netfront_info {

unsigned int handle;
unsigned int evtchn, irq;
-
- /* What is the status of our connection to the remote backend? */
-#define BEST_CLOSED 0
-#define BEST_DISCONNECTED 1
-#define BEST_CONNECTED 2
- unsigned int backend_state;

/* Receive-ring batched refills. */
#define RX_MIN_TARGET 8
@@ -143,14 +136,6 @@ static inline unsigned short get_id_from
list[0] = list[id];
return id;
}
-
-#ifdef DEBUG
-static const char *be_state_name[] = {
- [BEST_CLOSED] = "closed",
- [BEST_DISCONNECTED] = "disconnected",
- [BEST_CONNECTED] = "connected",
-};
-#endif

#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
__FUNCTION__, __LINE__, ##args)
@@ -247,6 +232,27 @@ static int netfront_resume(struct xenbus
return talk_to_backend(dev, info);
}

+static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
+{
+ char *s, *e, *macstr;
+ int i;
+
+ macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
+ if (IS_ERR(macstr))
+ return PTR_ERR(macstr);
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ mac[i] = simple_strtoul(s, &e, 16);
+ if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
+ kfree(macstr);
+ return -ENOENT;
+ }
+ s = e+1;
+ }
+
+ kfree(macstr);
+ return 0;
+}

/* Common code used when first setting up, and when resuming. */
static int talk_to_backend(struct xenbus_device *dev,
@@ -342,7 +348,6 @@ static int setup_device(struct xenbus_de
}
memset(txs, 0, PAGE_SIZE);
memset(rxs, 0, PAGE_SIZE);
- info->backend_state = BEST_DISCONNECTED;

SHARED_RING_INIT(txs);
FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
@@ -384,7 +389,7 @@ static int setup_device(struct xenbus_de
* Callback received when the backend's state changes.
*/
static void backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
+ enum xenbus_state backend_state)
{
DPRINTK("\n");

@@ -465,7 +470,7 @@ static void network_tx_buf_gc(struct net
struct netfront_info *np = netdev_priv(dev);
struct sk_buff *skb;

- if (np->backend_state != BEST_CONNECTED)
+ if (unlikely(!netif_carrier_ok(dev)))
return;

do {
@@ -527,7 +532,7 @@ static void network_alloc_rx_buffers(str
struct xen_memory_reservation reservation;
grant_ref_t ref;

- if (unlikely(np->backend_state != BEST_CONNECTED))
+ if (unlikely(!netif_carrier_ok(dev)))
return;

/*
@@ -662,7 +667,7 @@ static int network_start_xmit(struct sk_

spin_lock_irq(&np->tx_lock);

- if (np->backend_state != BEST_CONNECTED) {
+ if (unlikely(!netif_carrier_ok(dev))) {
spin_unlock_irq(&np->tx_lock);
goto drop;
}
@@ -748,7 +753,7 @@ static int netif_poll(struct net_device

spin_lock(&np->rx_lock);

- if (np->backend_state != BEST_CONNECTED) {
+ if (unlikely(!netif_carrier_ok(dev))) {
spin_unlock(&np->rx_lock);
return 0;
}
@@ -1041,7 +1046,7 @@ static void network_connect(struct net_d
* domain a kick because we've probably just requeued some
* packets.
*/
- np->backend_state = BEST_CONNECTED;
+ netif_carrier_on(dev);
notify_remote_via_irq(np->irq);
network_tx_buf_gc(dev);

@@ -1055,7 +1060,7 @@ static void show_device(struct netfront_
if (np) {
IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
np->handle,
- be_state_name[np->backend_state],
+ netif_carrier_ok(np->netdev) ? "on" : "off",
netif_running(np->netdev) ? "open" : "closed",
np->evtchn,
np->tx,
@@ -1241,9 +1246,10 @@ static struct net_device * __devinit cre
}

np = netdev_priv(netdev);
- np->backend_state = BEST_CLOSED;
np->handle = handle;
np->xbdev = dev;
+
+ netif_carrier_off(netdev);

spin_lock_init(&np->tx_lock);
spin_lock_init(&np->rx_lock);
@@ -1392,7 +1398,7 @@ static void netif_disconnect_backend(str
/* Stop old i/f to prevent errors whilst we rebuild the state. */
spin_lock_irq(&info->tx_lock);
spin_lock(&info->rx_lock);
- info->backend_state = BEST_DISCONNECTED;
+ netif_carrier_off(info->netdev);
spin_unlock(&info->rx_lock);
spin_unlock_irq(&info->tx_lock);

diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Fri May 26 13:41:49 2006 -0600
@@ -166,7 +166,7 @@ static int pciback_attach(struct pciback
}

static void pciback_frontend_changed(struct xenbus_device *xdev,
- XenbusState fe_state)
+ enum xenbus_state fe_state)
{
struct pciback_device *pdev = xdev->data;

diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Fri May 26 13:41:49 2006 -0600
@@ -196,7 +196,7 @@ static int pcifront_try_disconnect(struc
static int pcifront_try_disconnect(struct pcifront_device *pdev)
{
int err = 0;
- XenbusState prev_state;
+ enum xenbus_state prev_state;

spin_lock(&pdev->dev_lock);

@@ -214,7 +214,7 @@ static int pcifront_try_disconnect(struc
}

static void pcifront_backend_changed(struct xenbus_device *xdev,
- XenbusState be_state)
+ enum xenbus_state be_state)
{
struct pcifront_device *pdev = xdev->data;

diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Fri May 26 13:41:49 2006 -0600
@@ -159,10 +159,6 @@ static int privcmd_ioctl(struct inode *i
break;

case IOCTL_PRIVCMD_MMAPBATCH: {
-#ifndef __ia64__
- mmu_update_t u;
- uint64_t ptep;
-#endif
privcmd_mmapbatch_t m;
struct vm_area_struct *vma = NULL;
unsigned long __user *p;
@@ -200,24 +196,12 @@ static int privcmd_ioctl(struct inode *i
for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
if (get_user(mfn, p))
return -EFAULT;
-#ifdef __ia64__
+
ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
- mfn, 1 << PAGE_SHIFT,
+ mfn, PAGE_SIZE,
vma->vm_page_prot, m.dom);
if (ret < 0)
- goto batch_err;
-#else
-
- ret = create_lookup_pte_addr(vma->vm_mm, addr, &ptep);
- if (ret)
- goto batch_err;
-
- u.val = pte_val_ma(pfn_pte_ma(mfn, vma->vm_page_prot));
- u.ptr = ptep;
-
- if (HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0)
put_user(0xF0000000 | mfn, p);
-#endif
}

ret = 0;
@@ -283,6 +267,9 @@ static int __init privcmd_init(void)
set_bit(__HYPERVISOR_mmuext_op, hypercall_permission_map);
set_bit(__HYPERVISOR_xen_version, hypercall_permission_map);
set_bit(__HYPERVISOR_sched_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_sched_op_compat, hypercall_permission_map);
+ set_bit(__HYPERVISOR_event_channel_op_compat,
+ hypercall_permission_map);

privcmd_intf = create_xen_proc_entry("privcmd", 0400);
if (privcmd_intf != NULL)
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri May 26 13:41:49 2006 -0600
@@ -34,7 +34,7 @@ struct backend_info

/* watch front end for changes */
struct xenbus_watch backend_watch;
- XenbusState frontend_state;
+ enum xenbus_state frontend_state;
};

static void maybe_connect(struct backend_info *be);
@@ -43,7 +43,7 @@ static void backend_changed(struct xenbu
static void backend_changed(struct xenbus_watch *watch,
const char **vec, unsigned int len);
static void frontend_changed(struct xenbus_device *dev,
- XenbusState frontend_state);
+ enum xenbus_state frontend_state);

static int tpmback_remove(struct xenbus_device *dev)
{
@@ -129,7 +129,7 @@ static void backend_changed(struct xenbu


static void frontend_changed(struct xenbus_device *dev,
- XenbusState frontend_state)
+ enum xenbus_state frontend_state)
{
struct backend_info *be = dev->data;
int err;
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Fri May 26 13:41:49 2006 -0600
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path2);
EXPORT_SYMBOL_GPL(xenbus_watch_path2);


-int xenbus_switch_state(struct xenbus_device *dev, XenbusState state)
+int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
{
/* We check whether the state is currently set to the given value, and
if not, then the state is set. We don't want to unconditionally
@@ -269,9 +269,9 @@ int xenbus_free_evtchn(struct xenbus_dev
}


-XenbusState xenbus_read_driver_state(const char *path)
-{
- XenbusState result;
+enum xenbus_state xenbus_read_driver_state(const char *path)
+{
+ enum xenbus_state result;
int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
if (err)
result = XenbusStateClosed;
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri May 26 13:41:49 2006 -0600
@@ -284,7 +284,7 @@ static void otherend_changed(struct xenb
struct xenbus_device *dev =
container_of(watch, struct xenbus_device, otherend_watch);
struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
- XenbusState state;
+ enum xenbus_state state;

/* Protect us against watches firing on old details when the otherend
details change, say immediately after a resume. */
@@ -539,7 +539,7 @@ static int xenbus_probe_node(struct xen_
size_t stringlen;
char *tmpstring;

- XenbusState state = xenbus_read_driver_state(nodename);
+ enum xenbus_state state = xenbus_read_driver_state(nodename);

if (state != XenbusStateInitialising) {
/* Device is not new, so ignore it. This can happen if a
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Thu May 25 15:59:18 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Fri May 26 13:41:49 2006 -0600
@@ -75,7 +75,7 @@ struct xenbus_device {
int otherend_id;
struct xenbus_watch otherend_watch;
struct device dev;
- XenbusState state;
+ enum xenbus_state state;
void *data;
};

@@ -98,7 +98,7 @@ struct xenbus_driver {
int (*probe)(struct xenbus_device *dev,
const struct xenbus_device_id *id);
void (*otherend_changed)(struct xenbus_device *dev,
- XenbusState backend_state);
+ enum xenbus_state backend_state);
int (*remove)(struct xenbus_device *dev);
int (*suspend)(struct xenbus_device *dev);
int (*resume)(struct xenbus_device *dev);
@@ -207,7 +207,7 @@ int xenbus_watch_path2(struct xenbus_dev
* Return 0 on success, or -errno on error. On error, the device will switch
* to XenbusStateClosing, and the error will be saved in the store.
*/
-int xenbus_switch_state(struct xenbus_device *dev, XenbusState new_state);
+int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state new_state);


/**
@@ -273,7 +273,7 @@ int xenbus_free_evtchn(struct xenbus_dev
* Return the state of the driver rooted at the given store path, or
* XenbusStateClosed if no state can be read.
*/
-XenbusState xenbus_read_driver_state(const char *path);
+enum xenbus_state xenbus_read_driver_state(const char *path);


/***
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/Makefile
--- a/tools/libxc/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/Makefile Fri May 26 13:41:49 2006 -0600
@@ -20,6 +20,7 @@ SRCS += xc_physdev.c
SRCS += xc_physdev.c
SRCS += xc_private.c
SRCS += xc_sedf.c
+SRCS += xc_csched.c
SRCS += xc_tbuf.c

ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_linux_build.c Fri May 26 13:41:49 2006 -0600
@@ -268,21 +268,10 @@ static int setup_pg_tables_pae(int xc_ha
l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
uint64_t l1tab, l2tab, l3tab, pl1tab, pl2tab, pl3tab;
- unsigned long ppt_alloc, count, nmfn;
+ unsigned long ppt_alloc, count;

/* First allocate page for page dir. */
ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
-
- if ( page_array[ppt_alloc] > 0xfffff )
- {
- nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
- if ( nmfn == 0 )
- {
- fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
- goto error_out;
- }
- page_array[ppt_alloc] = nmfn;
- }

alloc_pt(l3tab, vl3tab, pl3tab);
vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_linux_restore.c Fri May 26 13:41:49 2006 -0600
@@ -331,25 +331,17 @@ int xc_linux_restore(int xc_handle, int
** A page table page - need to 'uncanonicalize' it, i.e.
** replace all the references to pfns with the corresponding
** mfns for the new domain.
- **
- ** On PAE we need to ensure that PGDs are in MFNs < 4G, and
- ** so we may need to update the p2m after the main loop.
- ** Hence we defer canonicalization of L1s until then.
*/
- if(pt_levels != 3 || pagetype != L1TAB) {
-
- if(!uncanonicalize_pagetable(pagetype, page)) {
- /*
- ** Failing to uncanonicalize a page table can be ok
- ** under live migration since the pages type may have
- ** changed by now (and we'll get an update later).
- */
- DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n",
- pagetype >> 28, pfn, mfn);
- nraces++;
- continue;
- }
-
+ if(!uncanonicalize_pagetable(pagetype, page)) {
+ /*
+ ** Failing to uncanonicalize a page table can be ok
+ ** under live migration since the pages type may have
+ ** changed by now (and we'll get an update later).
+ */
+ DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n",
+ pagetype >> 28, pfn, mfn);
+ nraces++;
+ continue;
}

} else if(pagetype != NOTAB) {
@@ -397,100 +389,6 @@ int xc_linux_restore(int xc_handle, int
}

DPRINTF("Received all pages (%d races)\n", nraces);
-
- if(pt_levels == 3) {
-
- /*
- ** XXX SMH on PAE we need to ensure PGDs are in MFNs < 4G. This
- ** is a little awkward and involves (a) finding all such PGDs and
- ** replacing them with 'lowmem' versions; (b) upating the p2m[]
- ** with the new info; and (c) canonicalizing all the L1s using the
- ** (potentially updated) p2m[].
- **
- ** This is relatively slow (and currently involves two passes through
- ** the pfn_type[] array), but at least seems to be correct. May wish
- ** to consider more complex approaches to optimize this later.
- */
-
- int j, k;
-
- /* First pass: find all L3TABs current in > 4G mfns and get new mfns */
- for (i = 0; i < max_pfn; i++) {
-
- if (((pfn_type[i] & LTABTYPE_MASK)==L3TAB) && (p2m[i]>0xfffffUL)) {
-
- unsigned long new_mfn;
- uint64_t l3ptes[4];
- uint64_t *l3tab;
-
- l3tab = (uint64_t *)
- xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ, p2m[i]);
-
- for(j = 0; j < 4; j++)
- l3ptes[j] = l3tab[j];
-
- munmap(l3tab, PAGE_SIZE);
-
- if (!(new_mfn=xc_make_page_below_4G(xc_handle, dom, p2m[i]))) {
- ERR("Couldn't get a page below 4GB :-(");
- goto out;
- }
-
- p2m[i] = new_mfn;
- if (xc_add_mmu_update(xc_handle, mmu,
- (((unsigned long long)new_mfn)
- << PAGE_SHIFT) |
- MMU_MACHPHYS_UPDATE, i)) {
- ERR("Couldn't m2p on PAE root pgdir");
- goto out;
- }
-
- l3tab = (uint64_t *)
- xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ | PROT_WRITE, p2m[i]);
-
- for(j = 0; j < 4; j++)
- l3tab[j] = l3ptes[j];
-
- munmap(l3tab, PAGE_SIZE);
-
- }
- }
-
- /* Second pass: find all L1TABs and uncanonicalize them */
- j = 0;
-
- for(i = 0; i < max_pfn; i++) {
-
- if (((pfn_type[i] & LTABTYPE_MASK)==L1TAB)) {
- region_mfn[j] = p2m[i];
- j++;
- }
-
- if(i == (max_pfn-1) || j == MAX_BATCH_SIZE) {
-
- if (!(region_base = xc_map_foreign_batch(
- xc_handle, dom, PROT_READ | PROT_WRITE,
- region_mfn, j))) {
- ERR("map batch failed");
- goto out;
- }
-
- for(k = 0; k < j; k++) {
- if(!uncanonicalize_pagetable(L1TAB,
- region_base + k*PAGE_SIZE)) {
- ERR("failed uncanonicalize pt!");
- goto out;
- }
- }
-
- munmap(region_base, j*PAGE_SIZE);
- j = 0;
- }
- }
-
- }


if (xc_finish_mmu_updates(xc_handle, mmu)) {
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_private.c Fri May 26 13:41:49 2006 -0600
@@ -430,28 +430,6 @@ int xc_version(int xc_handle, int cmd, v
return rc;
}

-unsigned long xc_make_page_below_4G(
- int xc_handle, uint32_t domid, unsigned long mfn)
-{
- unsigned long new_mfn;
-
- if ( xc_domain_memory_decrease_reservation(
- xc_handle, domid, 1, 0, &mfn) != 0 )
- {
- fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
- return 0;
- }
-
- if ( xc_domain_memory_increase_reservation(
- xc_handle, domid, 1, 0, 32, &new_mfn) != 0 )
- {
- fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
- return 0;
- }
-
- return new_mfn;
-}
-
/*
* Local variables:
* mode: C
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_ptrace.c Fri May 26 13:41:49 2006 -0600
@@ -185,7 +185,7 @@ map_domain_va_32(
void *guest_va,
int perm)
{
- unsigned long l1p, p, va = (unsigned long)guest_va;
+ unsigned long l2e, l1e, l1p, p, va = (unsigned long)guest_va;
uint32_t *l2, *l1;
static void *v[MAX_VIRT_CPUS];

@@ -194,18 +194,20 @@ map_domain_va_32(
if ( l2 == NULL )
return NULL;

- l1p = to_ma(cpu, l2[l2_table_offset(va)]);
+ l2e = l2[l2_table_offset_i386(va)];
munmap(l2, PAGE_SIZE);
- if ( !(l1p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l2e & _PAGE_PRESENT) )
+ return NULL;
+ l1p = to_ma(cpu, l2e);
l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l1p >> PAGE_SHIFT);
if ( l1 == NULL )
return NULL;

- p = to_ma(cpu, l1[l1_table_offset(va)]);
+ l1e = l1[l1_table_offset_i386(va)];
munmap(l1, PAGE_SIZE);
- if ( !(p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l1e & _PAGE_PRESENT) )
+ return NULL;
+ p = to_ma(cpu, l1e);
if ( v[cpu] != NULL )
munmap(v[cpu], PAGE_SIZE);
v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
@@ -223,7 +225,7 @@ map_domain_va_pae(
void *guest_va,
int perm)
{
- unsigned long l2p, l1p, p, va = (unsigned long)guest_va;
+ unsigned long l3e, l2e, l1e, l2p, l1p, p, va = (unsigned long)guest_va;
uint64_t *l3, *l2, *l1;
static void *v[MAX_VIRT_CPUS];

@@ -232,26 +234,29 @@ map_domain_va_pae(
if ( l3 == NULL )
return NULL;

- l2p = to_ma(cpu, l3[l3_table_offset_pae(va)]);
+ l3e = l3[l3_table_offset_pae(va)];
munmap(l3, PAGE_SIZE);
- if ( !(l2p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l3e & _PAGE_PRESENT) )
+ return NULL;
+ l2p = to_ma(cpu, l3e);
l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
if ( l2 == NULL )
return NULL;

- l1p = to_ma(cpu, l2[l2_table_offset_pae(va)]);
+ l2e = l2[l2_table_offset_pae(va)];
munmap(l2, PAGE_SIZE);
- if ( !(l1p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l2e & _PAGE_PRESENT) )
+ return NULL;
+ l1p = to_ma(cpu, l2e);
l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
if ( l1 == NULL )
return NULL;

- p = to_ma(cpu, l1[l1_table_offset_pae(va)]);
+ l1e = l1[l1_table_offset_pae(va)];
munmap(l1, PAGE_SIZE);
- if ( !(p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l1e & _PAGE_PRESENT) )
+ return NULL;
+ p = to_ma(cpu, l1e);
if ( v[cpu] != NULL )
munmap(v[cpu], PAGE_SIZE);
v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
@@ -269,9 +274,10 @@ map_domain_va_64(
void *guest_va,
int perm)
{
- unsigned long l3p, l2p, l1p, l1e, p, va = (unsigned long)guest_va;
+ unsigned long l4e, l3e, l2e, l1e, l3p, l2p, l1p, p, va = (unsigned long)guest_va;
uint64_t *l4, *l3, *l2, *l1;
static void *v[MAX_VIRT_CPUS];
+

if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
return map_domain_va_32(xc_handle, cpu, guest_va, perm);
@@ -281,40 +287,41 @@ map_domain_va_64(
if ( l4 == NULL )
return NULL;

- l3p = to_ma(cpu, l4[l4_table_offset(va)]);
+ l4e = l4[l4_table_offset(va)];
munmap(l4, PAGE_SIZE);
- if ( !(l3p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l4e & _PAGE_PRESENT) )
+ return NULL;
+ l3p = to_ma(cpu, l4e);
l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p >> PAGE_SHIFT);
if ( l3 == NULL )
return NULL;

- l2p = to_ma(cpu, l3[l3_table_offset(va)]);
+ l3e = l3[l3_table_offset(va)];
munmap(l3, PAGE_SIZE);
- if ( !(l2p & _PAGE_PRESENT) )
- return NULL;
+ if ( !(l3e & _PAGE_PRESENT) )
+ return NULL;
+ l2p = to_ma(cpu, l3e);
l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
if ( l2 == NULL )
return NULL;

l1 = NULL;
- l1e = to_ma(cpu, l2[l2_table_offset(va)]);
- if ( !(l1e & _PAGE_PRESENT) )
- {
- munmap(l2, PAGE_SIZE);
- return NULL;
- }
- l1p = l1e >> PAGE_SHIFT;
- if (l1e & 0x80) { /* 2M pages */
+ l2e = l2[l2_table_offset(va)];
+ munmap(l2, PAGE_SIZE);
+ if ( !(l2e & _PAGE_PRESENT) )
+ return NULL;
+ l1p = to_ma(cpu, l2e);
+ if (l2e & 0x80) { /* 2M pages */
p = to_ma(cpu, (l1p + l1_table_offset(va)) << PAGE_SHIFT);
} else { /* 4K pages */
- l1p = to_ma(cpu, l1p);
l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
- munmap(l2, PAGE_SIZE);
if ( l1 == NULL )
return NULL;

- p = to_ma(cpu, l1[l1_table_offset(va)]);
+ l1e = l1[l1_table_offset(va)];
+ if ( !(l1e & _PAGE_PRESENT) )
+ return NULL;
+ p = to_ma(cpu, l1e);
}
if ( v[cpu] != NULL )
munmap(v[cpu], PAGE_SIZE);
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_ptrace.h Fri May 26 13:41:49 2006 -0600
@@ -7,7 +7,6 @@
#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
#define X86_CR0_PG 0x80000000 /* Paging (RW) */
#define BSD_PAGE_MASK (PAGE_SIZE-1)
-#define PDRSHIFT 22
#define PSL_T 0x00000100 /* trace enable bit */

#ifdef __x86_64__
@@ -162,8 +161,6 @@ struct gdb_regs {
#endif

#define printval(x) printf("%s = %lx\n", #x, (long)x);
-#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
#endif

typedef void (*thr_ev_handler_t)(long);
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_ptrace_core.c Fri May 26 13:41:49 2006 -0600
@@ -3,6 +3,7 @@
#include <sys/ptrace.h>
#include <sys/wait.h>
#include "xc_private.h"
+#include "xg_private.h"
#include "xc_ptrace.h"
#include <time.h>

@@ -54,7 +55,7 @@ map_domain_va_core(unsigned long domfd,
}
cr3_virt[cpu] = v;
}
- if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
+ if ((pde = cr3_virt[cpu][l2_table_offset_i386(va)]) == 0) /* logical address */
return NULL;
if (ctxt[cpu].flags & VGCF_HVM_GUEST)
pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
@@ -70,7 +71,7 @@ map_domain_va_core(unsigned long domfd,
return NULL;
pde_virt[cpu] = v;
}
- if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
+ if ((page = pde_virt[cpu][l1_table_offset_i386(va)]) == 0) /* logical address */
return NULL;
if (ctxt[cpu].flags & VGCF_HVM_GUEST)
page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
@@ -84,7 +85,7 @@ map_domain_va_core(unsigned long domfd,
map_mtop_offset(page_phys[cpu]));
if (v == MAP_FAILED)
{
- printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
+ printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, l1_table_offset_i386(va));
page_phys[cpu] = 0;
return NULL;
}
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_tbuf.c
--- a/tools/libxc/xc_tbuf.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xc_tbuf.c Fri May 26 13:41:49 2006 -0600
@@ -18,53 +18,57 @@

static int tbuf_enable(int xc_handle, int enable)
{
- DECLARE_DOM0_OP;
+ DECLARE_DOM0_OP;

- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- if (enable)
- op.u.tbufcontrol.op = DOM0_TBUF_ENABLE;
- else
- op.u.tbufcontrol.op = DOM0_TBUF_DISABLE;
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ if (enable)
+ op.u.tbufcontrol.op = DOM0_TBUF_ENABLE;
+ else
+ op.u.tbufcontrol.op = DOM0_TBUF_DISABLE;

- return xc_dom0_op(xc_handle, &op);
+ return xc_dom0_op(xc_handle, &op);
}

int xc_tbuf_set_size(int xc_handle, unsigned long size)
{
- DECLARE_DOM0_OP;
+ DECLARE_DOM0_OP;

- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- op.u.tbufcontrol.op = DOM0_TBUF_SET_SIZE;
- op.u.tbufcontrol.size = size;
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ op.u.tbufcontrol.op = DOM0_TBUF_SET_SIZE;
+ op.u.tbufcontrol.size = size;

- return xc_dom0_op(xc_handle, &op);
+ return xc_dom0_op(xc_handle, &op);
}

int xc_tbuf_get_size(int xc_handle, unsigned long *size)
{
- int rc;
- DECLARE_DOM0_OP;
+ int rc;
+ DECLARE_DOM0_OP;

- op.cmd = DOM0_TBUFCONTROL;
- op.interface_version = DOM0_INTERFACE_VERSION;
- op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO;
+ op.cmd = DOM0_TBUFCONTROL;
+ op.interface_version = DOM0_INTERFACE_VERSION;
+ op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO;

- rc = xc_dom0_op(xc_handle, &op);
- if (rc == 0)
- *size = op.u.tbufcontrol.size;
- return rc;
+ rc = xc_dom0_op(xc_handle, &op);
+ if (rc == 0)
+ *size = op.u.tbufcontrol.size;
+ return rc;
}

int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn,
- unsigned long *size)
+ unsigned long *size)
{
DECLARE_DOM0_OP;
int rc;

- if ( xc_tbuf_set_size(xc_handle, cnt) != 0 )
- return -1;
+ /*
+ * Ignore errors (at least for now) as we get an error if size is already
+ * set (since trace buffers cannot be reallocated). If we really have no
+ * buffers at all then tbuf_enable() will fail, so this is safe.
+ */
+ (void)xc_tbuf_set_size(xc_handle, cnt);

if ( tbuf_enable(xc_handle, 1) != 0 )
return -1;
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xenctrl.h Fri May 26 13:41:49 2006 -0600
@@ -354,6 +354,14 @@ int xc_sedf_domain_get(int xc_handle,
uint64_t *latency, uint16_t *extratime,
uint16_t *weight);

+int xc_csched_domain_set(int xc_handle,
+ uint32_t domid,
+ struct csched_domain *sdom);
+
+int xc_csched_domain_get(int xc_handle,
+ uint32_t domid,
+ struct csched_domain *sdom);
+
typedef evtchn_status_t xc_evtchn_status_t;

/*
@@ -444,9 +452,6 @@ int xc_domain_iomem_permission(int xc_ha
unsigned long first_mfn,
unsigned long nr_mfns,
uint8_t allow_access);
-
-unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
- unsigned long mfn);

typedef dom0_perfc_desc_t xc_perfc_desc_t;
/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Thu May 25 15:59:18 2006 -0600
+++ b/tools/libxc/xg_private.h Fri May 26 13:41:49 2006 -0600
@@ -48,6 +48,8 @@ unsigned long csum_page (void * page);
#define L2_PAGETABLE_SHIFT_PAE 21
#define L3_PAGETABLE_SHIFT_PAE 30

+#define L2_PAGETABLE_SHIFT_I386 22
+
#if defined(__i386__)
#define L1_PAGETABLE_SHIFT 12
#define L2_PAGETABLE_SHIFT 22
@@ -61,6 +63,9 @@ unsigned long csum_page (void * page);
#define L1_PAGETABLE_ENTRIES_PAE 512
#define L2_PAGETABLE_ENTRIES_PAE 512
#define L3_PAGETABLE_ENTRIES_PAE 4
+
+#define L1_PAGETABLE_ENTRIES_I386 1024
+#define L2_PAGETABLE_ENTRIES_I386 1024

#if defined(__i386__)
#define L1_PAGETABLE_ENTRIES 1024
@@ -95,6 +100,11 @@ typedef unsigned long l4_pgentry_t;
#define l3_table_offset_pae(_a) \
(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))

+#define l1_table_offset_i386(_a) \
+ (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES_I386 - 1))
+#define l2_table_offset_i386(_a) \
+ (((_a) >> L2_PAGETABLE_SHIFT_I386) & (L2_PAGETABLE_ENTRIES_I386 - 1))
+
#if defined(__i386__)
#define l1_table_offset(_a) \
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri May 26 13:41:49 2006 -0600
@@ -716,6 +716,49 @@ static PyObject *pyxc_sedf_domain_get(Xc
"weight", weight);
}

+static PyObject *pyxc_csched_domain_set(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ uint32_t domid;
+ uint16_t weight;
+ uint16_t cap;
+ static char *kwd_list[] = { "dom", "weight", "cap", NULL };
+ static char kwd_type[] = "I|HH";
+ struct csched_domain sdom;
+
+ weight = 0;
+ cap = (uint16_t)~0U;
+ if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
+ &domid, &weight, &cap) )
+ return NULL;
+
+ sdom.weight = weight;
+ sdom.cap = cap;
+
+ if ( xc_csched_domain_set(self->xc_handle, domid, &sdom) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
+static PyObject *pyxc_csched_domain_get(XcObject *self, PyObject *args)
+{
+ uint32_t domid;
+ struct csched_domain sdom;
+
+ if( !PyArg_ParseTuple(args, "I", &domid) )
+ return NULL;
+
+ if ( xc_csched_domain_get(self->xc_handle, domid, &sdom) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ return Py_BuildValue("{s:H,s:H}",
+ "weight", sdom.weight,
+ "cap", sdom.cap);
+}
+
static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
{
uint32_t dom;
@@ -1040,6 +1083,24 @@ static PyMethodDef pyxc_methods[] = {
" slice [long]: CPU reservation per period\n"
" latency [long]: domain's wakeup latency hint\n"
" extratime [int]: domain aware of extratime?\n"},
+
+ { "csched_domain_set",
+ (PyCFunction)pyxc_csched_domain_set,
+ METH_KEYWORDS, "\n"
+ "Set the scheduling parameters for a domain when running with the\n"
+ "SMP credit scheduler.\n"
+ " domid [int]: domain id to set\n"
+ " weight [short]: domain's scheduling weight\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "csched_domain_get",
+ (PyCFunction)pyxc_csched_domain_get,
+ METH_VARARGS, "\n"
+ "Get the scheduling parameters for a domain when running with the\n"
+ "SMP credit scheduler.\n"
+ " domid [int]: domain id to get\n"
+ "Returns: [dict]\n"
+ " weight [short]: domain's scheduling weight\n"},

{ "evtchn_alloc_unbound",
(PyCFunction)pyxc_evtchn_alloc_unbound,
diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/lowlevel/xs/xs.c Fri May 26 13:41:49 2006 -0600
@@ -272,11 +272,12 @@ static PyObject *xspy_get_permissions(Xs

if (perms) {
PyObject *val = PyList_New(perms_n);
- for (i = 0; i < perms_n; i++, perms++) {
- PyObject *p = Py_BuildValue("{s:i,s:i,s:i}",
- "dom", perms->id,
- "read", perms->perms & XS_PERM_READ,
- "write",perms->perms & XS_PERM_WRITE);
+ for (i = 0; i < perms_n; i++) {
+ PyObject *p =
+ Py_BuildValue("{s:i,s:i,s:i}",
+ "dom", perms[i].id,
+ "read", perms[i].perms & XS_PERM_READ,
+ "write", perms[i].perms & XS_PERM_WRITE);
PyList_SetItem(val, i, p);
}

diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xend/XendDomain.py Fri May 26 13:41:49 2006 -0600
@@ -522,6 +522,28 @@ class XendDomain:
except Exception, ex:
raise XendError(str(ex))

+ def domain_csched_get(self, domid):
+ """Get credit scheduler parameters for a domain.
+ """
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+ try:
+ return xc.csched_domain_get(dominfo.getDomid())
+ except Exception, ex:
+ raise XendError(str(ex))
+
+ def domain_csched_set(self, domid, weight, cap):
+ """Set credit scheduler parameters for a domain.
+ """
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+ try:
+ return xc.csched_domain_set(dominfo.getDomid(), weight, cap)
+ except Exception, ex:
+ raise XendError(str(ex))
+
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.

diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri May 26 13:41:49 2006 -0600
@@ -701,6 +701,16 @@ class XendDomainInfo:
log.debug("Storing VM details: %s", to_store)

self.writeVm(to_store)
+ self.setVmPermissions()
+
+
+ def setVmPermissions(self):
+ """Allow the guest domain to read its UUID. We don't allow it to
+ access any other entry, for security."""
+ xstransact.SetPermissions('%s/uuid' % self.vmpath,
+ { 'dom' : self.domid,
+ 'read' : True,
+ 'write' : False })


def storeDomDetails(self):
@@ -1535,6 +1545,10 @@ class XendDomainInfo:

self.configure_bootloader()
config = self.sxpr()
+
+ if self.infoIsSet('cpus') and len(self.info['cpus']) != 0:
+ config.append([.'cpus', reduce(lambda x, y: str(x) + "," + str(y),
+ self.info['cpus'])])

if self.readVm(RESTART_IN_PROGRESS):
log.error('Xend failed during restart of domain %d. '
diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xend/balloon.py Fri May 26 13:41:49 2006 -0600
@@ -32,6 +32,7 @@ BALLOON_OUT_SLACK = 1 # MiB. We need th
BALLOON_OUT_SLACK = 1 # MiB. We need this because the physinfo details are
# rounded.
RETRY_LIMIT = 10
+RETRY_LIMIT_INCR = 5
##
# The time to sleep between retries grows linearly, using this value (in
# seconds). When the system is lightly loaded, memory should be scrubbed and
@@ -118,7 +119,8 @@ def free(required):
retries = 0
sleep_time = SLEEP_TIME_GROWTH
last_new_alloc = None
- while retries < RETRY_LIMIT:
+ rlimit = RETRY_LIMIT
+ while retries < rlimit:
free_mem = xc.physinfo()['free_memory']

if free_mem >= need_mem:
@@ -127,7 +129,9 @@ def free(required):
return

if retries == 0:
- log.debug("Balloon: free %d; need %d.", free_mem, need_mem)
+ rlimit += ((need_mem - free_mem)/1024) * RETRY_LIMIT_INCR
+ log.debug("Balloon: free %d; need %d; retries: %d.",
+ free_mem, need_mem, rlimit)

if dom0_min_mem > 0:
dom0_alloc = get_dom0_current_alloc()
@@ -143,8 +147,9 @@ def free(required):
# Continue to retry, waiting for ballooning.

time.sleep(sleep_time)
+ if retries < 2 * RETRY_LIMIT:
+ sleep_time += SLEEP_TIME_GROWTH
retries += 1
- sleep_time += SLEEP_TIME_GROWTH

# Not enough memory; diagnose the problem.
if dom0_min_mem == 0:
diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xend/server/SrvDomain.py Fri May 26 13:41:49 2006 -0600
@@ -129,6 +129,20 @@ class SrvDomain(SrvDir):
['latency', 'int'],
['extratime', 'int'],
['weight', 'int']])
+ val = fn(req.args, {'dom': self.dom.domid})
+ return val
+
+ def op_domain_csched_get(self, _, req):
+ fn = FormFn(self.xd.domain_csched_get,
+ [['dom', 'int']])
+ val = fn(req.args, {'dom': self.dom.domid})
+ return val
+
+
+ def op_domain_csched_set(self, _, req):
+ fn = FormFn(self.xd.domain_csched_set,
+ [['dom', 'int'],
+ ['weight', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val

diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xend/xenstore/xstransact.py Fri May 26 13:41:49 2006 -0600
@@ -221,6 +221,34 @@ class xstransact:
xshandle().mkdir(self.transaction, self.prependPath(key))


+ def get_permissions(self, *args):
+ """If no arguments are given, return the permissions at this
+ transaction's path. If one argument is given, treat that argument as
+ a subpath to this transaction's path, and return the permissions at
+ that path. Otherwise, treat each argument as a subpath to this
+ transaction's path, and return a list composed of the permissions at
+ each of those instead.
+ """
+ if len(args) == 0:
+ return xshandle().get_permissions(self.transaction, self.path)
+ if len(args) == 1:
+ return self._get_permissions(args[0])
+ ret = []
+ for key in args:
+ ret.append(self._get_permissions(key))
+ return ret
+
+
+ def _get_permissions(self, key):
+ path = self.prependPath(key)
+ try:
+ return xshandle().get_permissions(self.transaction, path)
+ except RuntimeError, ex:
+ raise RuntimeError(ex.args[0],
+ '%s, while getting permissions from %s' %
+ (ex.args[1], path))
+
+
def set_permissions(self, *args):
if len(args) == 0:
raise TypeError
diff -r 9d52a66c7499 -r c073ebdbde8c tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Thu May 25 15:59:18 2006 -0600
+++ b/tools/python/xen/xm/main.py Fri May 26 13:41:49 2006 -0600
@@ -99,6 +99,7 @@ sched_sedf_help = "sched-sedf [DOM] [.OPT
specifies another way of setting a domain's\n\
cpu period/slice."

+csched_help = "csched Set or get credit scheduler parameters"
block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
[BackDomId] Create a new virtual block device"""
block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device,
@@ -174,6 +175,7 @@ host_commands = [
]

scheduler_commands = [.
+ "csched",
"sched-bvt",
"sched-bvt-ctxallow",
"sched-sedf",
@@ -735,6 +737,48 @@ def xm_sched_sedf(args):
else:
print_sedf(sedf_info)

+def xm_csched(args):
+ usage_msg = """Csched: Set or get credit scheduler parameters
+ Usage:
+
+ csched -d domain [-w weight] [-c cap]
+ """
+ try:
+ opts, args = getopt.getopt(args[0:], "d:w:c:",
+ ["domain=", "weight=", "cap="])
+ except getopt.GetoptError:
+ # print help information and exit:
+ print usage_msg
+ sys.exit(1)
+
+ domain = None
+ weight = None
+ cap = None
+
+ for o, a in opts:
+ if o == "-d":
+ domain = a
+ elif o == "-w":
+ weight = int(a)
+ elif o == "-c":
+ cap = int(a);
+
+ if domain is None:
+ # place holder for system-wide scheduler parameters
+ print usage_msg
+ sys.exit(1)
+
+ if weight is None and cap is None:
+ print server.xend.domain.csched_get(domain)
+ else:
+ if weight is None:
+ weight = int(0)
+ if cap is None:
+ cap = int(~0)
+
+ err = server.xend.domain.csched_set(domain, weight, cap)
+ if err != 0:
+ print err

def xm_info(args):
arg_check(args, "info", 0)
@@ -1032,6 +1076,7 @@ commands = {
"sched-bvt": xm_sched_bvt,
"sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
"sched-sedf": xm_sched_sedf,
+ "csched": xm_csched,
# block
"block-attach": xm_block_attach,
"block-detach": xm_block_detach,
diff -r 9d52a66c7499 -r c073ebdbde8c tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/tests/test_x86_emulator.c Fri May 26 13:41:49 2006 -0600
@@ -17,7 +17,8 @@ static int read_any(
static int read_any(
unsigned long addr,
unsigned long *val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -32,7 +33,8 @@ static int write_any(
static int write_any(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -48,7 +50,8 @@ static int cmpxchg_any(
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
switch ( bytes )
{
@@ -65,34 +68,38 @@ static int cmpxchg8b_any(
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
- unsigned long new_hi)
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt)
{
((unsigned long *)addr)[0] = new_lo;
((unsigned long *)addr)[1] = new_hi;
return X86EMUL_CONTINUE;
}

-static struct x86_mem_emulator emulops = {
+static struct x86_emulate_ops emulops = {
read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
};

int main(int argc, char **argv)
{
+ struct x86_emulate_ctxt ctxt;
struct cpu_user_regs regs;
char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
unsigned int res = 0x7FFFFFFF;
u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
- unsigned long cr2;
int rc;
+
+ ctxt.regs = &regs;
+ ctxt.mode = X86EMUL_MODE_PROT32;

printf("%-40s", "Testing addl %%ecx,(%%eax)...");
instr[0] = 0x01; instr[1] = 0x08;
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x7FFFFFFF;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.eflags != 0xa94) ||
@@ -109,8 +116,8 @@ int main(int argc, char **argv)
#else
regs.ecx = 0x12345678UL;
#endif
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.ecx != 0x8000000FUL) ||
@@ -124,8 +131,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x92345677UL;
regs.ecx = 0xAA;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x923456AA) ||
(regs.eflags != 0x244) ||
@@ -140,8 +147,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0xAABBCC77UL;
regs.ecx = 0xFF;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x923456AA) ||
((regs.eflags&0x240) != 0x200) ||
@@ -156,8 +163,8 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x12345678) ||
(regs.eflags != 0x200) ||
@@ -173,8 +180,8 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x923456AAUL;
regs.ecx = 0xDDEEFF00L;
- cr2 = (unsigned long)&res;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = (unsigned long)&res;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0xDDEEFF00) ||
(regs.eflags != 0x244) ||
@@ -192,8 +199,8 @@ int main(int argc, char **argv)
regs.esi = (unsigned long)&res + 0;
regs.edi = (unsigned long)&res + 2;
regs.error_code = 0; /* read fault */
- cr2 = regs.esi;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.esi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x44554455) ||
(regs.eflags != 0x200) ||
@@ -210,8 +217,8 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)&res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x2233445D) ||
((regs.eflags&0x201) != 0x201) ||
@@ -228,8 +235,8 @@ int main(int argc, char **argv)
regs.ecx = 0xCCCCFFFF;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -242,8 +249,8 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
- cr2 = regs.edi;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ ctxt.cr2 = regs.edi;
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -258,9 +265,9 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x82;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x82) ||
(regs.ecx != 0xFFFFFF82) ||
@@ -273,9 +280,9 @@ int main(int argc, char **argv)
instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- cr2 = (unsigned long)&res;
+ ctxt.cr2 = (unsigned long)&res;
res = 0x1234aa82;
- rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
+ rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(res != 0x1234aa82) ||
(regs.ecx != 0xaa82) ||
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/Makefile
--- a/tools/xenstore/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/tools/xenstore/Makefile Fri May 26 13:41:49 2006 -0600
@@ -27,6 +27,12 @@ CLIENTS += xenstore-write
CLIENTS += xenstore-write
CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))

+XENSTORED_OBJS = xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o
+
+XENSTORED_Linux = xenstored_linux.o
+
+XENSTORED_OBJS += $(XENSTORED_$(OS))
+
.PHONY: all
all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-control xenstore-ls

@@ -36,7 +42,7 @@ test_interleaved_transactions: test_inte
.PHONY: testcode
testcode: xs_test xenstored_test xs_random

-xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o
+xenstored: $(XENSTORED_OBJS)
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@

$(CLIENTS): xenstore-%: xenstore_%.o libxenstore.so
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/xenstore/xenstored_core.c Fri May 26 13:41:49 2006 -0600
@@ -451,6 +451,11 @@ static struct node *read_node(struct con

static bool write_node(struct connection *conn, const struct node *node)
{
+ /*
+ * conn will be null when this is called from manual_node.
+ * tdb_context copes with this.
+ */
+
TDB_DATA key, data;
void *p;

@@ -478,7 +483,7 @@ static bool write_node(struct connection

/* TDB should set errno, but doesn't even set ecode AFAICT. */
if (tdb_store(tdb_context(conn), key, data, TDB_REPLACE) != 0) {
- corrupt(conn, "Write of %s = %s failed", key, data);
+ corrupt(conn, "Write of %s failed", key.dptr);
goto error;
}
return true;
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/xenstored_core.h
--- a/tools/xenstore/xenstored_core.h Thu May 25 15:59:18 2006 -0600
+++ b/tools/xenstore/xenstored_core.h Fri May 26 13:41:49 2006 -0600
@@ -19,6 +19,8 @@

#ifndef _XENSTORED_CORE_H
#define _XENSTORED_CORE_H
+
+#include <xenctrl.h>

#include <sys/types.h>
#include <dirent.h>
@@ -163,6 +165,12 @@ void trace(const char *fmt, ...);

extern int event_fd;

+/* Map the kernel's xenstore page. */
+void *xenbus_map(void);
+
+/* Return the event channel used by xenbus. */
+evtchn_port_t xenbus_evtchn(void);
+
#endif /* _XENSTORED_CORE_H */

/*
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu May 25 15:59:18 2006 -0600
+++ b/tools/xenstore/xenstored_domain.c Fri May 26 13:41:49 2006 -0600
@@ -33,12 +33,11 @@
#include "talloc.h"
#include "xenstored_core.h"
#include "xenstored_domain.h"
-#include "xenstored_proc.h"
#include "xenstored_watch.h"
#include "xenstored_test.h"

#include <xenctrl.h>
-#include <xen/linux/evtchn.h>
+#include <xen/sys/evtchn.h>

static int *xc_handle;
static evtchn_port_t virq_port;
@@ -476,44 +475,24 @@ void restore_existing_connections(void)

static int dom0_init(void)
{
- int rc, fd;
- evtchn_port_t port;
- char str[20];
- struct domain *dom0;
-
- fd = open(XENSTORED_PROC_PORT, O_RDONLY);
- if (fd == -1)
+ evtchn_port_t port;
+ struct domain *dom0;
+
+ port = xenbus_evtchn();
+ if (port == -1)
return -1;

- rc = read(fd, str, sizeof(str));
- if (rc == -1)
- goto outfd;
- str[rc] = '\0';
- port = strtoul(str, NULL, 0);
-
- close(fd);
-
dom0 = new_domain(NULL, 0, port);

- fd = open(XENSTORED_PROC_KVA, O_RDWR);
- if (fd == -1)
+ dom0->interface = xenbus_map();
+ if (dom0->interface == NULL)
return -1;

- dom0->interface = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (dom0->interface == MAP_FAILED)
- goto outfd;
-
- close(fd);
-
talloc_steal(dom0->conn, dom0);

evtchn_notify(dom0->port);

return 0;
-outfd:
- close(fd);
- return -1;
}


diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/domain_build.c Fri May 26 13:41:49 2006 -0600
@@ -367,7 +367,10 @@ int construct_dom0(struct domain *d,
if ( (1UL << order) > nr_pages )
panic("Domain 0 allocation is too small for kernel image.\n");

- /* Allocate from DMA pool: PAE L3 table must be below 4GB boundary. */
+ /*
+ * Allocate from DMA pool: on i386 this ensures that our low-memory 1:1
+ * mapping covers the allocation.
+ */
if ( (page = alloc_domheap_pages(d, order, ALLOC_DOM_DMA)) == NULL )
panic("Not enough RAM for domain 0 allocation.\n");
alloc_spfn = page_to_mfn(page);
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/hvm.c Fri May 26 13:41:49 2006 -0600
@@ -185,8 +185,9 @@ void hvm_setup_platform(struct domain* d
void hvm_setup_platform(struct domain* d)
{
struct hvm_domain *platform;
-
- if ( !hvm_guest(current) || (current->vcpu_id != 0) )
+ struct vcpu *v=current;
+
+ if ( !hvm_guest(v) || (v->vcpu_id != 0) )
return;

if ( shadow_direct_map_init(d) == 0 )
@@ -208,7 +209,8 @@ void hvm_setup_platform(struct domain* d
hvm_vioapic_init(d);
}

- pit_init(&platform->vpit, current);
+ init_timer(&platform->pl_time.periodic_tm.timer, pt_timer_fn, v, v->processor);
+ pit_init(v, cpu_khz);
}

void pic_irq_request(void *data, int level)
@@ -238,6 +240,14 @@ void hvm_pic_assist(struct vcpu *v)
} while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs );
do_pic_irqs(pic, irqs);
}
+}
+
+u64 hvm_get_guest_time(struct vcpu *v)
+{
+ u64 host_tsc;
+
+ rdtscll(host_tsc);
+ return host_tsc + v->arch.hvm_vcpu.cache_tsc_offset;
}

int cpu_get_interrupt(struct vcpu *v, int *type)
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/i8254.c Fri May 26 13:41:49 2006 -0600
@@ -22,11 +22,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-/* Edwin Zhai <edwin.zhai@intel.com>
+/* Edwin Zhai <edwin.zhai@intel.com>, Eddie Dong <eddie.dong@intel.com>
* Ported to xen:
- * use actimer for intr generation;
+ * Add a new layer of periodic time on top of PIT;
* move speaker io access to hypervisor;
- * use new method for counter/intrs calculation
*/

#include <xen/config.h>
@@ -42,184 +41,117 @@
#include <asm/hvm/vpit.h>
#include <asm/current.h>

-/*#define DEBUG_PIT*/
+/* Enable DEBUG_PIT may cause guest calibration inaccuracy */
+/* #define DEBUG_PIT */

#define RW_STATE_LSB 1
#define RW_STATE_MSB 2
#define RW_STATE_WORD0 3
#define RW_STATE_WORD1 4

-#ifndef NSEC_PER_SEC
-#define NSEC_PER_SEC (1000000000ULL)
-#endif
-
-#ifndef TIMER_SLOP
-#define TIMER_SLOP (50*1000) /* ns */
-#endif
-
-static void pit_irq_timer_update(PITChannelState *s, s64 current_time);
-
-s_time_t hvm_get_clock(void)
-{
- /* TODO: add pause/unpause support */
- return NOW();
+#define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency)
+static int handle_pit_io(ioreq_t *p);
+static int handle_speaker_io(ioreq_t *p);
+
+/* compute with 96 bit intermediate result: (a*b)/c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+ union {
+ uint64_t ll;
+ struct {
+#ifdef WORDS_BIGENDIAN
+ uint32_t high, low;
+#else
+ uint32_t low, high;
+#endif
+ } l;
+ } u, res;
+ uint64_t rl, rh;
+
+ u.ll = a;
+ rl = (uint64_t)u.l.low * (uint64_t)b;
+ rh = (uint64_t)u.l.high * (uint64_t)b;
+ rh += (rl >> 32);
+ res.l.high = rh / c;
+ res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+ return res.ll;
+}
+
+/*
+ * get processor time.
+ * unit: TSC
+ */
+int64_t hvm_get_clock(struct vcpu *v)
+{
+ uint64_t gtsc;
+ gtsc = hvm_get_guest_time(v);
+ return gtsc;
}

static int pit_get_count(PITChannelState *s)
{
- u64 d;
- u64 counter;
-
- d = hvm_get_clock() - s->count_load_time;
+ uint64_t d;
+ int counter;
+
+ d = muldiv64(hvm_get_clock(s->vcpu) - s->count_load_time, PIT_FREQ, ticks_per_sec(s->vcpu));
switch(s->mode) {
case 0:
case 1:
case 4:
case 5:
- counter = (s->period - d) & 0xffff;
+ counter = (s->count - d) & 0xffff;
break;
case 3:
/* XXX: may be incorrect for odd counts */
- counter = s->period - ((2 * d) % s->period);
+ counter = s->count - ((2 * d) % s->count);
break;
default:
- /* mod 2 counter handle */
- d = hvm_get_clock() - s->hvm_time->count_point;
- d += s->hvm_time->count_advance;
- counter = s->period - (d % s->period);
- break;
- }
- /* change from ns to pit counter */
- counter = DIV_ROUND( (counter * PIT_FREQ), NSEC_PER_SEC);
+ counter = s->count - (d % s->count);
+ break;
+ }
return counter;
}

/* get pit output bit */
-static int pit_get_out1(PITChannelState *s, s64 current_time)
-{
- u64 d;
+static int pit_get_out1(PITChannelState *s, int64_t current_time)
+{
+ uint64_t d;
int out;

- d = current_time - s->count_load_time;
+ d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec(s->vcpu));
switch(s->mode) {
default:
case 0:
- out = (d >= s->period);
+ out = (d >= s->count);
break;
case 1:
- out = (d < s->period);
+ out = (d < s->count);
break;
case 2:
- /* mod2 out is no meaning, since intr are generated in background */
- if ((d % s->period) == 0 && d != 0)
+ if ((d % s->count) == 0 && d != 0)
out = 1;
else
out = 0;
break;
case 3:
- out = (d % s->period) < ((s->period + 1) >> 1);
+ out = (d % s->count) < ((s->count + 1) >> 1);
break;
case 4:
case 5:
- out = (d == s->period);
+ out = (d == s->count);
break;
}
return out;
}

-int pit_get_out(hvm_virpit *pit, int channel, s64 current_time)
+int pit_get_out(PITState *pit, int channel, int64_t current_time)
{
PITChannelState *s = &pit->channels[channel];
return pit_get_out1(s, current_time);
}

-static __inline__ s64 missed_ticks(PITChannelState *s, s64 current_time)
-{
- struct hvm_time_info *hvm_time = s->hvm_time;
- struct domain *d = (void *) s -
- offsetof(struct domain, arch.hvm_domain.vpit.channels[0]);
-
- /* ticks from current time(expected time) to NOW */
- int missed_ticks;
- /* current_time is expected time for next intr, check if it's true
- * (actimer has a TIMER_SLOP in advance)
- */
- s64 missed_time = hvm_get_clock() + TIMER_SLOP - current_time;
-
- if (missed_time >= 0) {
- missed_ticks = missed_time/(s_time_t)s->period + 1;
- if (test_bit(_DOMF_debugging, &d->domain_flags)) {
- hvm_time->pending_intr_nr++;
- } else {
- hvm_time->pending_intr_nr += missed_ticks;
- }
- s->next_transition_time = current_time + (missed_ticks ) * s->period;
- }
-
- return s->next_transition_time;
-}
-
-/* only rearm the actimer when return value > 0
- * -2: init state
- * -1: the mode has expired
- * 0: current VCPU is not running
- * >0: the next fired time
- */
-s64 pit_get_next_transition_time(PITChannelState *s,
- s64 current_time)
-{
- s64 d, next_time, base;
- int period2;
- struct hvm_time_info *hvm_time = s->hvm_time;
-
- d = current_time - s->count_load_time;
- switch(s->mode) {
- default:
- case 0:
- case 1:
- if (d < s->period)
- next_time = s->period;
- else
- return -1;
- break;
- case 2:
- next_time = missed_ticks(s, current_time);
- if ( !test_bit(_VCPUF_running, &(hvm_time->vcpu->vcpu_flags)) )
- return 0;
- break;
- case 3:
- base = (d / s->period) * s->period;
- period2 = ((s->period + 1) >> 1);
- if ((d - base) < period2)
- next_time = base + period2;
- else
- next_time = base + s->period;
- break;
- case 4:
- case 5:
- if (d < s->period)
- next_time = s->period;
- else if (d == s->period)
- next_time = s->period + 1;
- else
- return -1;
- break;
- case 0xff:
- return -2; /* for init state */
- break;
- }
- /* XXX: better solution: use a clock at PIT_FREQ Hz */
- if (next_time <= current_time){
-#ifdef DEBUG_PIT
- printk("HVM_PIT:next_time <= current_time. next=0x%llx, current=0x%llx!\n",next_time, current_time);
-#endif
- next_time = current_time + 1;
- }
- return next_time;
-}
-
/* val must be 0 or 1 */
-void pit_set_gate(hvm_virpit *pit, int channel, int val)
+void pit_set_gate(PITState *pit, int channel, int val)
{
PITChannelState *s = &pit->channels[channel];

@@ -233,16 +165,16 @@ void pit_set_gate(hvm_virpit *pit, int c
case 5:
if (s->gate < val) {
/* restart counting on rising edge */
- s->count_load_time = hvm_get_clock();
- pit_irq_timer_update(s, s->count_load_time);
+ s->count_load_time = hvm_get_clock(s->vcpu);
+// pit_irq_timer_update(s, s->count_load_time);
}
break;
case 2:
case 3:
if (s->gate < val) {
/* restart counting on rising edge */
- s->count_load_time = hvm_get_clock();
- pit_irq_timer_update(s, s->count_load_time);
+ s->count_load_time = hvm_get_clock(s->vcpu);
+// pit_irq_timer_update(s, s->count_load_time);
}
/* XXX: disable/enable counting */
break;
@@ -250,7 +182,7 @@ void pit_set_gate(hvm_virpit *pit, int c
s->gate = val;
}

-int pit_get_gate(hvm_virpit *pit, int channel)
+int pit_get_gate(PITState *pit, int channel)
{
PITChannelState *s = &pit->channels[channel];
return s->gate;
@@ -258,37 +190,37 @@ int pit_get_gate(hvm_virpit *pit, int ch

static inline void pit_load_count(PITChannelState *s, int val)
{
+ u32 period;
if (val == 0)
val = 0x10000;
-
- s->count_load_time = hvm_get_clock();
+ s->count_load_time = hvm_get_clock(s->vcpu);
s->count = val;
- s->period = DIV_ROUND(((s->count) * NSEC_PER_SEC), PIT_FREQ);
+ period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);

#ifdef DEBUG_PIT
- printk("HVM_PIT: pit-load-counter, count=0x%x,period=0x%u us,mode=%d, load_time=%lld\n",
+ printk("HVM_PIT: pit-load-counter(%p), count=0x%x, period=%uns mode=%d, load_time=%lld\n",
+ s,
val,
- s->period / 1000,
+ period,
s->mode,
- s->count_load_time);
+ (long long)s->count_load_time);
#endif

- if (s->mode == HVM_PIT_ACCEL_MODE) {
- if (!s->hvm_time) {
- printk("HVM_PIT:guest should only set mod 2 on channel 0!\n");
- return;
- }
- s->hvm_time->period_cycles = (u64)s->period * cpu_khz / 1000000L;
- s->hvm_time->first_injected = 0;
-
- if (s->period < 900000) { /* < 0.9 ms */
- printk("HVM_PIT: guest programmed too small an count: %x\n",
- s->count);
- s->period = 1000000;
- }
- }
-
- pit_irq_timer_update(s, s->count_load_time);
+ switch (s->mode) {
+ case 2:
+ /* create periodic time */
+ s->pt = create_periodic_time (s->vcpu, period, 0, 0);
+ break;
+ case 1:
+ /* create one shot time */
+ s->pt = create_periodic_time (s->vcpu, period, 0, 1);
+#ifdef DEBUG_PIT
+ printk("HVM_PIT: create one shot time.\n");
+#endif
+ break;
+ default:
+ break;
+ }
}

/* if already latched, do not latch again */
@@ -300,9 +232,9 @@ static void pit_latch_count(PITChannelSt
}
}

-static void pit_ioport_write(void *opaque, u32 addr, u32 val)
-{
- hvm_virpit *pit = opaque;
+static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ PITState *pit = opaque;
int channel, access;
PITChannelState *s;
val &= 0xff;
@@ -321,7 +253,7 @@ static void pit_ioport_write(void *opaqu
if (!(val & 0x10) && !s->status_latched) {
/* status latch */
/* XXX: add BCD and null count */
- s->status = (pit_get_out1(s, hvm_get_clock()) << 7) |
+ s->status = (pit_get_out1(s, hvm_get_clock(s->vcpu)) << 7) |
(s->rw_mode << 4) |
(s->mode << 1) |
s->bcd;
@@ -366,9 +298,9 @@ static void pit_ioport_write(void *opaqu
}
}

-static u32 pit_ioport_read(void *opaque, u32 addr)
-{
- hvm_virpit *pit = opaque;
+static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
+{
+ PITState *pit = opaque;
int ret, count;
PITChannelState *s;

@@ -419,84 +351,51 @@ static u32 pit_ioport_read(void *opaque,
return ret;
}

-static void pit_irq_timer_update(PITChannelState *s, s64 current_time)
-{
- s64 expire_time;
- int irq_level;
- struct vcpu *v = current;
- struct hvm_virpic *pic= &v->domain->arch.hvm_domain.vpic;
-
- if (!s->hvm_time || s->mode == 0xff)
- return;
-
- expire_time = pit_get_next_transition_time(s, current_time);
- /* not generate intr by direct pic_set_irq in mod 2
- * XXX:mod 3 should be same as mod 2
- */
- if (s->mode != HVM_PIT_ACCEL_MODE) {
- irq_level = pit_get_out1(s, current_time);
- pic_set_irq(pic, s->irq, irq_level);
- s->next_transition_time = expire_time;
-#ifdef DEBUG_PIT
- printk("HVM_PIT:irq_level=%d next_delay=%l ns\n",
- irq_level,
- (expire_time - current_time));
-#endif
- }
-
- if (expire_time > 0)
- set_timer(&(s->hvm_time->pit_timer), s->next_transition_time);
-
-}
-
-static void pit_irq_timer(void *data)
-{
- PITChannelState *s = data;
-
- pit_irq_timer_update(s, s->next_transition_time);
-}
-
static void pit_reset(void *opaque)
{
- hvm_virpit *pit = opaque;
+ PITState *pit = opaque;
PITChannelState *s;
int i;

for(i = 0;i < 3; i++) {
s = &pit->channels[i];
+ if ( s -> pt ) {
+ destroy_periodic_time (s->pt);
+ s->pt = NULL;
+ }
s->mode = 0xff; /* the init mode */
s->gate = (i != 2);
pit_load_count(s, 0);
}
}

-/* hvm_io_assist light-weight version, specific to PIT DM */
-static void resume_pit_io(ioreq_t *p)
-{
- struct cpu_user_regs *regs = guest_cpu_user_regs();
- unsigned long old_eax = regs->eax;
- p->state = STATE_INVALID;
-
- switch(p->size) {
- case 1:
- regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
- break;
- case 2:
- regs->eax = (old_eax & 0xffff0000) | (p->u.data & 0xffff);
- break;
- case 4:
- regs->eax = (p->u.data & 0xffffffff);
- break;
- default:
- BUG();
- }
+void pit_init(struct vcpu *v, unsigned long cpu_khz)
+{
+ PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
+ PITChannelState *s;
+
+ s = &pit->channels[0];
+ /* the timer 0 is connected to an IRQ */
+ s->vcpu = v;
+ s++; s->vcpu = v;
+ s++; s->vcpu = v;
+
+ register_portio_handler(PIT_BASE, 4, handle_pit_io);
+ /* register the speaker port */
+ register_portio_handler(0x61, 1, handle_speaker_io);
+ ticks_per_sec(v) = cpu_khz * (int64_t)1000;
+#ifdef DEBUG_PIT
+ printk("HVM_PIT: guest frequency =%lld\n", (long long)ticks_per_sec(v));
+#endif
+ pit_reset(pit);
+ return;
}

/* the intercept action for PIT DM retval:0--not handled; 1--handled */
-int handle_pit_io(ioreq_t *p)
+static int handle_pit_io(ioreq_t *p)
{
struct vcpu *v = current;
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);

if (p->size != 1 ||
p->pdata_valid ||
@@ -508,18 +407,18 @@ int handle_pit_io(ioreq_t *p)
if (p->dir == 0) {/* write */
pit_ioport_write(vpit, p->addr, p->u.data);
} else if (p->dir == 1) { /* read */
- p->u.data = pit_ioport_read(vpit, p->addr);
- resume_pit_io(p);
- }
-
- /* always return 1, since PIT sit in HV now */
+ if ( (p->addr & 3) != 3 ) {
+ p->u.data = pit_ioport_read(vpit, p->addr);
+ } else {
+ printk("HVM_PIT: read A1:A0=3!\n");
+ }
+ }
return 1;
}

static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
- hvm_virpit *pit = opaque;
- val &= 0xff;
+ PITState *pit = opaque;
pit->speaker_data_on = (val >> 1) & 1;
pit_set_gate(pit, 2, val & 1);
}
@@ -527,18 +426,18 @@ static uint32_t speaker_ioport_read(void
static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
{
int out;
- hvm_virpit *pit = opaque;
- out = pit_get_out(pit, 2, hvm_get_clock());
+ PITState *pit = opaque;
+ out = pit_get_out(pit, 2, hvm_get_clock(pit->channels[2].vcpu));
pit->dummy_refresh_clock ^= 1;

return (pit->speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
(pit->dummy_refresh_clock << 4);
}

-int handle_speaker_io(ioreq_t *p)
+static int handle_speaker_io(ioreq_t *p)
{
struct vcpu *v = current;
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);

if (p->size != 1 ||
p->pdata_valid ||
@@ -551,45 +450,7 @@ int handle_speaker_io(ioreq_t *p)
speaker_ioport_write(vpit, p->addr, p->u.data);
} else if (p->dir == 1) {/* read */
p->u.data = speaker_ioport_read(vpit, p->addr);
- resume_pit_io(p);
}

return 1;
}
-
-/* pick up missed timer ticks at deactive time */
-void pickup_deactive_ticks(struct hvm_virpit *vpit)
-{
- s64 next_time;
- PITChannelState *s = &(vpit->channels[0]);
- if ( !active_timer(&(vpit->time_info.pit_timer)) ) {
- next_time = pit_get_next_transition_time(s, s->next_transition_time);
- if (next_time >= 0)
- set_timer(&(s->hvm_time->pit_timer), s->next_transition_time);
- }
-}
-
-void pit_init(struct hvm_virpit *pit, struct vcpu *v)
-{
- PITChannelState *s;
- struct hvm_time_info *hvm_time;
-
- s = &pit->channels[0];
- /* the timer 0 is connected to an IRQ */
- s->irq = 0;
- /* channel 0 need access the related time info for intr injection */
- hvm_time = s->hvm_time = &pit->time_info;
- hvm_time->vcpu = v;
-
- init_timer(&(hvm_time->pit_timer), pit_irq_timer, s, v->processor);
-
- register_portio_handler(PIT_BASE, 4, handle_pit_io);
-
- /* register the speaker port */
- register_portio_handler(0x61, 1, handle_speaker_io);
-
- pit_reset(pit);
-
- return;
-
-}
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/intercept.c Fri May 26 13:41:49 2006 -0600
@@ -214,6 +214,88 @@ void hlt_timer_fn(void *data)
evtchn_set_pending(v, iopacket_port(v));
}

+static __inline__ void missed_ticks(struct periodic_time *pt)
+{
+ int missed_ticks;
+
+ missed_ticks = (NOW() - pt->scheduled)/(s_time_t) pt->period;
+ if ( missed_ticks++ >= 0 ) {
+ if ( missed_ticks > 1000 ) {
+ /* TODO: Adjust guest time togther */
+ pt->pending_intr_nr ++;
+ }
+ else {
+ pt->pending_intr_nr += missed_ticks;
+ }
+ pt->scheduled += missed_ticks * pt->period;
+ }
+}
+
+/* hook function for the platform periodic time */
+void pt_timer_fn(void *data)
+{
+ struct vcpu *v = data;
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+
+ /* pick up missed timer tick */
+ missed_ticks(pt);
+ if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
+ set_timer(&pt->timer, pt->scheduled);
+ }
+}
+
+/* pick up missed timer ticks at deactive time */
+void pickup_deactive_ticks(struct periodic_time *pt)
+{
+ if ( !active_timer(&(pt->timer)) ) {
+ missed_ticks(pt);
+ set_timer(&pt->timer, pt->scheduled);
+ }
+}
+
+/*
+ * period: fire frequency in ns.
+ */
+struct periodic_time * create_periodic_time(
+ struct vcpu *v,
+ u32 period,
+ char irq,
+ char one_shot)
+{
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+ if ( pt->enabled ) {
+ if ( v->vcpu_id != 0 ) {
+ printk("HVM_PIT: start 2nd periodic time on non BSP!\n");
+ }
+ stop_timer (&pt->timer);
+ pt->enabled = 0;
+ }
+ pt->pending_intr_nr = 0;
+ pt->first_injected = 0;
+ if (period < 900000) { /* < 0.9 ms */
+ printk("HVM_PlatformTime: program too small period %u\n",period);
+ period = 900000; /* force to 0.9ms */
+ }
+ pt->period = period;
+ pt->irq = irq;
+ pt->period_cycles = (u64)period * cpu_khz / 1000000L;
+ pt->one_shot = one_shot;
+ if ( one_shot ) {
+ printk("HVM_PL: No support for one shot platform time yet\n");
+ }
+ pt->scheduled = NOW() + period;
+ set_timer (&pt->timer,pt->scheduled);
+ pt->enabled = 1;
+ return pt;
+}
+
+void destroy_periodic_time(struct periodic_time *pt)
+{
+ if ( pt->enabled ) {
+ stop_timer(&pt->timer);
+ pt->enabled = 0;
+ }
+}

/*
* Local variables:
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c Fri May 26 13:41:49 2006 -0600
@@ -44,45 +44,33 @@
*/
#define BSP_CPU(v) (!(v->vcpu_id))

-u64 svm_get_guest_time(struct vcpu *v)
-{
- struct hvm_time_info *time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
- u64 host_tsc;
-
- rdtscll(host_tsc);
- return host_tsc + time_info->cache_tsc_offset;
-}
-
void svm_set_guest_time(struct vcpu *v, u64 gtime)
{
- struct hvm_time_info *time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
u64 host_tsc;

rdtscll(host_tsc);

- time_info->cache_tsc_offset = gtime - host_tsc;
- v->arch.hvm_svm.vmcb->tsc_offset = time_info->cache_tsc_offset;
+ v->arch.hvm_vcpu.cache_tsc_offset = gtime - host_tsc;
+ v->arch.hvm_svm.vmcb->tsc_offset = v->arch.hvm_vcpu.cache_tsc_offset;
}

static inline void
interrupt_post_injection(struct vcpu * v, int vector, int type)
{
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
- struct hvm_time_info *time_info = &vpit->time_info;
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);

if ( is_pit_irq(v, vector, type) ) {
- if ( !time_info->first_injected ) {
- time_info->pending_intr_nr = 0;
- time_info->last_pit_gtime = svm_get_guest_time(v);
- time_info->first_injected = 1;
+ if ( !pt->first_injected ) {
+ pt->pending_intr_nr = 0;
+ pt->last_plt_gtime = hvm_get_guest_time(v);
+ pt->scheduled = NOW() + pt->period;
+ set_timer(&pt->timer, pt->scheduled);
+ pt->first_injected = 1;
} else {
- time_info->pending_intr_nr--;
+ pt->pending_intr_nr--;
+ pt->last_plt_gtime += pt->period_cycles;
+ svm_set_guest_time(v, pt->last_plt_gtime);
}
- time_info->count_advance = 0;
- time_info->count_point = NOW();
-
- time_info->last_pit_gtime += time_info->period_cycles;
- svm_set_guest_time(v, time_info->last_pit_gtime);
}

switch(type)
@@ -121,8 +109,7 @@ asmlinkage void svm_intr_assist(void)
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
- struct hvm_virpit *vpit = &plat->vpit;
- struct hvm_time_info *time_info = &vpit->time_info;
+ struct periodic_time *pt = &plat->pl_time.periodic_tm;
struct hvm_virpic *pic= &plat->vpic;
int intr_type = VLAPIC_DELIV_MODE_EXT;
int intr_vector = -1;
@@ -174,9 +161,9 @@ asmlinkage void svm_intr_assist(void)
if ( cpu_has_pending_irq(v) ) {
intr_vector = cpu_get_interrupt(v, &intr_type);
}
- else if ( (v->vcpu_id == 0) && time_info->pending_intr_nr ) {
- pic_set_irq(pic, 0, 0);
- pic_set_irq(pic, 0, 1);
+ else if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr ) {
+ pic_set_irq(pic, pt->irq, 0);
+ pic_set_irq(pic, pt->irq, 1);
intr_vector = cpu_get_interrupt(v, &intr_type);
}
}
@@ -190,7 +177,7 @@ asmlinkage void svm_intr_assist(void)
/* Re-injecting a PIT interruptt? */
if (re_injecting &&
is_pit_irq(v, intr_vector, intr_type)) {
- ++time_info->pending_intr_nr;
+ ++pt->pending_intr_nr;
}
/* let's inject this interrupt */
TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0);
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Fri May 26 13:41:49 2006 -0600
@@ -51,13 +51,6 @@

#define SVM_EXTRA_DEBUG

-#ifdef TRACE_BUFFER
-static unsigned long trace_values[NR_CPUS][4];
-#define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value
-#else
-#define TRACE_VMEXIT(index,value) ((void)0)
-#endif
-
/* Useful define */
#define MAX_INST_SIZE 15

@@ -672,12 +665,11 @@ static void arch_svm_do_launch(struct vc

static void svm_freeze_time(struct vcpu *v)
{
- struct hvm_time_info *time_info = &v->domain->arch.hvm_domain.vpit.time_info;
+ struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;

- if ( time_info->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
- v->domain->arch.hvm_domain.guest_time = svm_get_guest_time(v);
- time_info->count_advance += (NOW() - time_info->count_point);
- stop_timer(&(time_info->pit_timer));
+ if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
+ stop_timer(&(pt->timer));
}
}

@@ -754,7 +746,7 @@ static void svm_relinquish_guest_resourc
}
}

- kill_timer(&d->arch.hvm_domain.vpit.time_info.pit_timer);
+ kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);

if ( d->arch.hvm_domain.shared_page_va )
unmap_domain_page_global(
@@ -784,10 +776,12 @@ void arch_svm_do_resume(struct vcpu *v)

void svm_migrate_timers(struct vcpu *v)
{
- struct hvm_time_info *time_info = &v->domain->arch.hvm_domain.vpit.time_info;
-
- migrate_timer(&time_info->pit_timer, v->processor);
- migrate_timer(&v->arch.hvm_svm.hlt_timer, v->processor);
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+
+ if ( pt->enabled ) {
+ migrate_timer( &pt->timer, v->processor );
+ migrate_timer( &v->arch.hvm_svm.hlt_timer, v->processor );
+ }
if ( hvm_apic_support(v->domain) && VLAPIC( v ))
migrate_timer( &(VLAPIC(v)->vlapic_timer ), v->processor );
}
@@ -816,7 +810,6 @@ static int svm_do_page_fault(unsigned lo
return 1;

handle_mmio(va, va);
- TRACE_VMEXIT(2,2);
return 1;
}

@@ -842,7 +835,6 @@ static int svm_do_page_fault(unsigned lo
return 1;
}

- TRACE_VMEXIT (2,2);
handle_mmio(va, gpa);

return 1;
@@ -854,8 +846,6 @@ static int svm_do_page_fault(unsigned lo
/* Let's make sure that the Guest TLB is flushed */
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
}
-
- TRACE_VMEXIT (2,result);

return result;
}
@@ -1901,14 +1891,8 @@ static inline void svm_do_msr_access(str
regs->edx = 0;
switch (regs->ecx) {
case MSR_IA32_TIME_STAMP_COUNTER:
- {
- struct hvm_time_info *time_info;
-
- rdtscll(msr_content);
- time_info = &v->domain->arch.hvm_domain.vpit.time_info;
- msr_content += time_info->cache_tsc_offset;
+ msr_content = hvm_get_guest_time(v);
break;
- }
case MSR_IA32_SYSENTER_CS:
msr_content = vmcb->sysenter_cs;
break;
@@ -1975,7 +1959,7 @@ static inline void svm_vmexit_do_hlt(str
static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
{
struct vcpu *v = current;
- struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
+ struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
s_time_t next_pit = -1, next_wakeup;

__update_guest_eip(vmcb, 1);
@@ -1985,7 +1969,7 @@ static inline void svm_vmexit_do_hlt(str
return;

if ( !v->vcpu_id )
- next_pit = get_pit_scheduled(v, vpit);
+ next_pit = get_scheduled(v, pt->irq, pt);
next_wakeup = get_apictime_scheduled(v);
if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
next_wakeup = next_pit;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/svm/vmcb.c Fri May 26 13:41:49 2006 -0600
@@ -442,19 +442,17 @@ void svm_do_resume(struct vcpu *v)
void svm_do_resume(struct vcpu *v)
{
struct domain *d = v->domain;
- struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
- struct hvm_time_info *time_info = &vpit->time_info;
+ struct periodic_time *pt = &d->arch.hvm_domain.pl_time.periodic_tm;

svm_stts(v);

/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( time_info->first_injected ) {
- if ( v->domain->arch.hvm_domain.guest_time ) {
- svm_set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
- time_info->count_point = NOW();
- v->domain->arch.hvm_domain.guest_time = 0;
+ if ( pt->enabled && pt->first_injected ) {
+ if ( v->arch.hvm_vcpu.guest_time ) {
+ svm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
+ v->arch.hvm_vcpu.guest_time = 0;
}
- pickup_deactive_ticks(vpit);
+ pickup_deactive_ticks(pt);
}

if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/io.c Fri May 26 13:41:49 2006 -0600
@@ -49,45 +49,33 @@ void __set_tsc_offset(u64 offset)
#endif
}

-u64 get_guest_time(struct vcpu *v)
-{
- struct hvm_time_info *time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
- u64 host_tsc;
-
- rdtscll(host_tsc);
- return host_tsc + time_info->cache_tsc_offset;
-}
-
void set_guest_time(struct vcpu *v, u64 gtime)
{
- struct hvm_time_info *time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
u64 host_tsc;

rdtscll(host_tsc);

- time_info->cache_tsc_offset = gtime - host_tsc;
- __set_tsc_offset(time_info->cache_tsc_offset);
+ v->arch.hvm_vcpu.cache_tsc_offset = gtime - host_tsc;
+ __set_tsc_offset(v->arch.hvm_vcpu.cache_tsc_offset);
}

static inline void
interrupt_post_injection(struct vcpu * v, int vector, int type)
{
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
- struct hvm_time_info *time_info = &vpit->time_info;
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);

if ( is_pit_irq(v, vector, type) ) {
- if ( !time_info->first_injected ) {
- time_info->pending_intr_nr = 0;
- time_info->last_pit_gtime = get_guest_time(v);
- time_info->first_injected = 1;
+ if ( !pt->first_injected ) {
+ pt->pending_intr_nr = 0;
+ pt->last_plt_gtime = hvm_get_guest_time(v);
+ pt->scheduled = NOW() + pt->period;
+ set_timer(&pt->timer, pt->scheduled);
+ pt->first_injected = 1;
} else {
- time_info->pending_intr_nr--;
- }
- time_info->count_advance = 0;
- time_info->count_point = NOW();
-
- time_info->last_pit_gtime += time_info->period_cycles;
- set_guest_time(v, time_info->last_pit_gtime);
+ pt->pending_intr_nr--;
+ pt->last_plt_gtime += pt->period_cycles;
+ set_guest_time(v, pt->last_plt_gtime);
+ }
}

switch(type)
@@ -151,7 +139,7 @@ asmlinkage void vmx_intr_assist(void)
unsigned long eflags;
struct vcpu *v = current;
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
- struct hvm_time_info *time_info = &plat->vpit.time_info;
+ struct periodic_time *pt = &plat->pl_time.periodic_tm;
struct hvm_virpic *pic= &plat->vpic;
unsigned int idtv_info_field;
unsigned long inst_len;
@@ -160,9 +148,9 @@ asmlinkage void vmx_intr_assist(void)
if ( v->vcpu_id == 0 )
hvm_pic_assist(v);

- if ( (v->vcpu_id == 0) && time_info->pending_intr_nr ) {
- pic_set_irq(pic, 0, 0);
- pic_set_irq(pic, 0, 1);
+ if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr ) {
+ pic_set_irq(pic, pt->irq, 0);
+ pic_set_irq(pic, pt->irq, 1);
}

has_ext_irq = cpu_has_pending_irq(v);
@@ -232,19 +220,17 @@ void vmx_do_resume(struct vcpu *v)
void vmx_do_resume(struct vcpu *v)
{
struct domain *d = v->domain;
- struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
- struct hvm_time_info *time_info = &vpit->time_info;
+ struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;

vmx_stts();

/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( time_info->first_injected ) {
- if ( v->domain->arch.hvm_domain.guest_time ) {
- time_info->count_point = NOW();
- set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
- v->domain->arch.hvm_domain.guest_time = 0;
- }
- pickup_deactive_ticks(vpit);
+ if ( pt->enabled && pt->first_injected ) {
+ if ( v->arch.hvm_vcpu.guest_time ) {
+ set_guest_time(v, v->arch.hvm_vcpu.guest_time);
+ v->arch.hvm_vcpu.guest_time = 0;
+ }
+ pickup_deactive_ticks(pt);
}

if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri May 26 13:41:49 2006 -0600
@@ -47,7 +47,7 @@
#include <asm/hvm/vpic.h>
#include <asm/hvm/vlapic.h>

-static unsigned long trace_values[NR_CPUS][4];
+static unsigned long trace_values[NR_CPUS][5];
#define TRACE_VMEXIT(index,value) trace_values[smp_processor_id()][index]=value

static void vmx_ctxt_switch_from(struct vcpu *v);
@@ -102,7 +102,7 @@ static void vmx_relinquish_guest_resourc
}
}

- kill_timer(&d->arch.hvm_domain.vpit.time_info.pit_timer);
+ kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);

if ( d->arch.hvm_domain.shared_page_va )
unmap_domain_page_global(
@@ -358,12 +358,11 @@ static inline int long_mode_do_msr_write

static void vmx_freeze_time(struct vcpu *v)
{
- struct hvm_time_info *time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
+ struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;

- if ( time_info->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
- v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
- time_info->count_advance += (NOW() - time_info->count_point);
- stop_timer(&(time_info->pit_timer));
+ if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
+ stop_timer(&(pt->timer));
}
}

@@ -393,10 +392,12 @@ int vmx_initialize_guest_resources(struc

void vmx_migrate_timers(struct vcpu *v)
{
- struct hvm_time_info *time_info = &v->domain->arch.hvm_domain.vpit.time_info;
-
- migrate_timer(&time_info->pit_timer, v->processor);
- migrate_timer(&v->arch.hvm_vmx.hlt_timer, v->processor);
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+
+ if ( pt->enabled ) {
+ migrate_timer(&pt->timer, v->processor);
+ migrate_timer(&v->arch.hvm_vmx.hlt_timer, v->processor);
+ }
if ( hvm_apic_support(v->domain) && VLAPIC(v))
migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
}
@@ -1861,14 +1862,8 @@ static inline void vmx_do_msr_read(struc
(unsigned long)regs->edx);
switch (regs->ecx) {
case MSR_IA32_TIME_STAMP_COUNTER:
- {
- struct hvm_time_info *time_info;
-
- rdtscll(msr_content);
- time_info = &(v->domain->arch.hvm_domain.vpit.time_info);
- msr_content += time_info->cache_tsc_offset;
- break;
- }
+ msr_content = hvm_get_guest_time(v);
+ break;
case MSR_IA32_SYSENTER_CS:
__vmread(GUEST_SYSENTER_CS, (u32 *)&msr_content);
break;
@@ -1941,11 +1936,11 @@ void vmx_vmexit_do_hlt(void)
void vmx_vmexit_do_hlt(void)
{
struct vcpu *v=current;
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
s_time_t next_pit=-1,next_wakeup;

if ( !v->vcpu_id )
- next_pit = get_pit_scheduled(v,vpit);
+ next_pit = get_scheduled(v, pt->irq, pt);
next_wakeup = get_apictime_scheduled(v);
if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
next_wakeup = next_pit;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/mm.c Fri May 26 13:41:49 2006 -0600
@@ -260,9 +260,42 @@ void share_xen_page_with_privileged_gues
share_xen_page_with_guest(page, dom_xen, readonly);
}

+static void __write_ptbase(unsigned long mfn)
+{
+#ifdef CONFIG_X86_PAE
+ if ( mfn >= 0x100000 )
+ {
+ l3_pgentry_t *highmem_l3tab, *lowmem_l3tab;
+ struct vcpu *v = current;
+ unsigned long flags;
+
+ /* Protects against re-entry and against __pae_flush_pgd(). */
+ local_irq_save(flags);
+
+ /* Pick an unused low-memory L3 cache slot. */
+ v->arch.lowmem_l3tab_inuse ^= 1;
+ lowmem_l3tab = v->arch.lowmem_l3tab[v->arch.lowmem_l3tab_inuse];
+ v->arch.lowmem_l3tab_high_mfn[v->arch.lowmem_l3tab_inuse] = mfn;
+
+ /* Map the guest L3 table and copy to the chosen low-memory cache. */
+ highmem_l3tab = map_domain_page(mfn);
+ memcpy(lowmem_l3tab, highmem_l3tab, sizeof(v->arch.lowmem_l3tab));
+ unmap_domain_page(highmem_l3tab);
+
+ /* Install the low-memory L3 table in CR3. */
+ write_cr3(__pa(lowmem_l3tab));
+
+ local_irq_restore(flags);
+ return;
+ }
+#endif
+
+ write_cr3(mfn << PAGE_SHIFT);
+}
+
void write_ptbase(struct vcpu *v)
{
- write_cr3(pagetable_get_paddr(v->arch.monitor_table));
+ __write_ptbase(pagetable_get_pfn(v->arch.monitor_table));
}

void invalidate_shadow_ldt(struct vcpu *v)
@@ -401,6 +434,7 @@ static int get_page_and_type_from_pagenr
return 1;
}

+#ifndef CONFIG_X86_PAE /* We do not support guest linear mappings on PAE. */
/*
* We allow root tables to map each other (a.k.a. linear page tables). It
* needs some special care with reference counts and access permissions:
@@ -456,6 +490,7 @@ get_linear_pagetable(

return 1;
}
+#endif /* !CONFIG_X86_PAE */

int
get_page_from_l1e(
@@ -564,10 +599,6 @@ get_page_from_l3e(
rc = get_page_and_type_from_pagenr(
l3e_get_pfn(l3e),
PGT_l2_page_table | vaddr, d);
-#if CONFIG_PAGING_LEVELS == 3
- if ( unlikely(!rc) )
- rc = get_linear_pagetable(l3e, pfn, d);
-#endif
return rc;
}
#endif /* 3 level */
@@ -773,6 +804,50 @@ static int create_pae_xen_mappings(l3_pg
return 1;
}

+struct pae_flush_pgd {
+ unsigned long l3tab_mfn;
+ unsigned int l3tab_idx;
+ l3_pgentry_t nl3e;
+};
+
+static void __pae_flush_pgd(void *data)
+{
+ struct pae_flush_pgd *args = data;
+ struct vcpu *v = this_cpu(curr_vcpu);
+ int i = v->arch.lowmem_l3tab_inuse;
+ intpte_t _ol3e, _nl3e, _pl3e;
+ l3_pgentry_t *l3tab_ptr;
+
+ ASSERT(!local_irq_is_enabled());
+
+ if ( v->arch.lowmem_l3tab_high_mfn[i] != args->l3tab_mfn )
+ return;
+
+ l3tab_ptr = &v->arch.lowmem_l3tab[i][args->l3tab_idx];
+
+ _ol3e = l3e_get_intpte(*l3tab_ptr);
+ _nl3e = l3e_get_intpte(args->nl3e);
+ _pl3e = cmpxchg((intpte_t *)l3tab_ptr, _ol3e, _nl3e);
+ BUG_ON(_pl3e != _ol3e);
+}
+
+/* Flush a pgdir update into low-memory caches. */
+static void pae_flush_pgd(
+ unsigned long mfn, unsigned int idx, l3_pgentry_t nl3e)
+{
+ struct domain *d = page_get_owner(mfn_to_page(mfn));
+ struct pae_flush_pgd args = {
+ .l3tab_mfn = mfn,
+ .l3tab_idx = idx,
+ .nl3e = nl3e };
+
+ /* If below 4GB then the pgdir is not shadowed in low memory. */
+ if ( mfn < 0x100000 )
+ return;
+
+ on_selected_cpus(d->domain_dirty_cpumask, __pae_flush_pgd, &args, 1, 1);
+}
+
static inline int l1_backptr(
unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
{
@@ -787,6 +862,7 @@ static inline int l1_backptr(

#elif CONFIG_X86_64
# define create_pae_xen_mappings(pl3e) (1)
+# define pae_flush_pgd(mfn, idx, nl3e) ((void)0)

static inline int l1_backptr(
unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
@@ -886,14 +962,6 @@ static int alloc_l3_table(struct page_in

ASSERT(!shadow_mode_refcounts(d));

-#ifdef CONFIG_X86_PAE
- if ( pfn >= 0x100000 )
- {
- MEM_LOG("PAE pgd must be below 4GB (0x%lx >= 0x100000)", pfn);
- return 0;
- }
-#endif
-
pl3e = map_domain_page(pfn);
for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
{
@@ -1240,6 +1308,8 @@ static int mod_l3_entry(l3_pgentry_t *pl

okay = create_pae_xen_mappings(pl3e);
BUG_ON(!okay);
+
+ pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);

put_page_from_l3e(ol3e, pfn);
return 1;
@@ -3109,7 +3179,7 @@ void ptwr_flush(struct domain *d, const

if ( unlikely(d->arch.ptwr[which].vcpu != current) )
/* Don't use write_ptbase: it may switch to guest_user on x86/64! */
- write_cr3(pagetable_get_paddr(
+ __write_ptbase(pagetable_get_pfn(
d->arch.ptwr[which].vcpu->arch.guest_table));
else
TOGGLE_MODE();
@@ -3220,15 +3290,16 @@ static int ptwr_emulated_update(
/* Turn a sub-word access into a full-word access. */
if ( bytes != sizeof(paddr_t) )
{
- int rc;
- paddr_t full;
- unsigned int offset = addr & (sizeof(paddr_t)-1);
+ paddr_t full;
+ unsigned int offset = addr & (sizeof(paddr_t)-1);

/* Align address; read full word. */
addr &= ~(sizeof(paddr_t)-1);
- if ( (rc = x86_emulate_read_std(addr, (unsigned long *)&full,
- sizeof(paddr_t))) )
- return rc;
+ if ( copy_from_user(&full, (void *)addr, sizeof(paddr_t)) )
+ {
+ propagate_page_fault(addr, 4); /* user mode, read fault */
+ return X86EMUL_PROPAGATE_FAULT;
+ }
/* Mask out bits provided by caller. */
full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8));
/* Shift the caller value and OR in the missing bits. */
@@ -3306,7 +3377,8 @@ static int ptwr_emulated_write(
static int ptwr_emulated_write(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
return ptwr_emulated_update(addr, 0, val, bytes, 0);
}
@@ -3315,7 +3387,8 @@ static int ptwr_emulated_cmpxchg(
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
return ptwr_emulated_update(addr, old, new, bytes, 1);
}
@@ -3325,7 +3398,8 @@ static int ptwr_emulated_cmpxchg8b(
unsigned long old,
unsigned long old_hi,
unsigned long new,
- unsigned long new_hi)
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt)
{
if ( CONFIG_PAGING_LEVELS == 2 )
return X86EMUL_UNHANDLEABLE;
@@ -3334,7 +3408,7 @@ static int ptwr_emulated_cmpxchg8b(
addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
}

-static struct x86_mem_emulator ptwr_mem_emulator = {
+static struct x86_emulate_ops ptwr_emulate_ops = {
.read_std = x86_emulate_read_std,
.write_std = x86_emulate_write_std,
.read_emulated = x86_emulate_read_std,
@@ -3353,6 +3427,7 @@ int ptwr_do_page_fault(struct domain *d,
l2_pgentry_t *pl2e, l2e;
int which, flags;
unsigned long l2_idx;
+ struct x86_emulate_ctxt emul_ctxt;

if ( unlikely(shadow_mode_enabled(d)) )
return 0;
@@ -3507,8 +3582,10 @@ int ptwr_do_page_fault(struct domain *d,
return EXCRET_fault_fixed;

emulate:
- if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
- &ptwr_mem_emulator, X86EMUL_MODE_HOST) )
+ emul_ctxt.regs = guest_cpu_user_regs();
+ emul_ctxt.cr2 = addr;
+ emul_ctxt.mode = X86EMUL_MODE_HOST;
+ if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) )
return 0;
perfc_incrc(ptwr_emulations);
return EXCRET_fault_fixed;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/traps.c Fri May 26 13:41:49 2006 -0600
@@ -876,7 +876,7 @@ static int emulate_privileged_op(struct
PAGE_FAULT(regs->edi, USER_WRITE_FAULT);
break;
}
- regs->edi += (regs->eflags & EF_DF) ? -op_bytes : op_bytes;
+ regs->edi += (regs->eflags & EF_DF) ? -(int)op_bytes : op_bytes;
break;

case 0x6e: /* OUTSB */
@@ -902,7 +902,7 @@ static int emulate_privileged_op(struct
outl_user((u32)data, (u16)regs->edx, v, regs);
break;
}
- regs->esi += (regs->eflags & EF_DF) ? -op_bytes : op_bytes;
+ regs->esi += (regs->eflags & EF_DF) ? -(int)op_bytes : op_bytes;
break;
}

diff -r 9d52a66c7499 -r c073ebdbde8c xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c Fri May 26 13:41:49 2006 -0600
@@ -363,12 +363,13 @@ do{ __asm__ __volatile__ (
#endif /* __i386__ */

/* Fetch next part of the instruction being emulated. */
-#define insn_fetch(_type, _size, _eip) \
-({ unsigned long _x; \
- if ( (rc = ops->read_std((unsigned long)(_eip), &_x, (_size))) != 0 ) \
- goto done; \
- (_eip) += (_size); \
- (_type)_x; \
+#define insn_fetch(_type, _size, _eip) \
+({ unsigned long _x; \
+ rc = ops->read_std((unsigned long)(_eip), &_x, (_size), ctxt); \
+ if ( rc != 0 ) \
+ goto done; \
+ (_eip) += (_size); \
+ (_type)_x; \
})

/* Access/update address held in a register, based on addressing mode. */
@@ -426,12 +427,10 @@ decode_register(
return p;
}

-int
+int
x86_emulate_memop(
- struct cpu_user_regs *regs,
- unsigned long cr2,
- struct x86_mem_emulator *ops,
- int mode)
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
{
uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
@@ -439,9 +438,11 @@ x86_emulate_memop(
unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
int rc = 0;
struct operand src, dst;
+ unsigned long cr2 = ctxt->cr2;
+ int mode = ctxt->mode;

/* Shadow copy of register state. Committed on successful emulation. */
- struct cpu_user_regs _regs = *regs;
+ struct cpu_user_regs _regs = *ctxt->regs;

switch ( mode )
{
@@ -628,7 +629,7 @@ x86_emulate_memop(
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
((rc = ops->read_emulated((unsigned long)dst.ptr,
- &dst.val, dst.bytes)) != 0) )
+ &dst.val, dst.bytes, ctxt)) != 0) )
goto done;
break;
}
@@ -670,7 +671,7 @@ x86_emulate_memop(
src.type = OP_MEM;
src.ptr = (unsigned long *)cr2;
if ( (rc = ops->read_emulated((unsigned long)src.ptr,
- &src.val, src.bytes)) != 0 )
+ &src.val, src.bytes, ctxt)) != 0 )
goto done;
src.orig_val = src.val;
break;
@@ -776,7 +777,7 @@ x86_emulate_memop(
if ( mode == X86EMUL_MODE_PROT64 )
dst.bytes = 8;
if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp),
- &dst.val, dst.bytes)) != 0 )
+ &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
register_address_increment(_regs.esp, dst.bytes);
break;
@@ -854,12 +855,12 @@ x86_emulate_memop(
{
dst.bytes = 8;
if ( (rc = ops->read_std((unsigned long)dst.ptr,
- &dst.val, 8)) != 0 )
+ &dst.val, 8, ctxt)) != 0 )
goto done;
}
- register_address_increment(_regs.esp, -dst.bytes);
+ register_address_increment(_regs.esp, -(int)dst.bytes);
if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
- dst.val, dst.bytes)) != 0 )
+ dst.val, dst.bytes, ctxt)) != 0 )
goto done;
dst.val = dst.orig_val; /* skanky: disable writeback */
break;
@@ -887,10 +888,11 @@ x86_emulate_memop(
case OP_MEM:
if ( lock_prefix )
rc = ops->cmpxchg_emulated(
- (unsigned long)dst.ptr, dst.orig_val, dst.val, dst.bytes);
+ (unsigned long)dst.ptr, dst.orig_val,
+ dst.val, dst.bytes, ctxt);
else
rc = ops->write_emulated(
- (unsigned long)dst.ptr, dst.val, dst.bytes);
+ (unsigned long)dst.ptr, dst.val, dst.bytes, ctxt);
if ( rc != 0 )
goto done;
default:
@@ -899,7 +901,7 @@ x86_emulate_memop(
}

/* Commit shadow register state. */
- *regs = _regs;
+ *ctxt->regs = _regs;

done:
return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
@@ -911,11 +913,11 @@ x86_emulate_memop(
{
if ( _regs.ecx == 0 )
{
- regs->eip = _regs.eip;
+ ctxt->regs->eip = _regs.eip;
goto done;
}
_regs.ecx--;
- _regs.eip = regs->eip;
+ _regs.eip = ctxt->regs->eip;
}
switch ( b )
{
@@ -928,20 +930,21 @@ x86_emulate_memop(
dst.ptr = (unsigned long *)cr2;
if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds,
_regs.esi),
- &dst.val, dst.bytes)) != 0 )
+ &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
}
else
{
/* Read fault: source is special memory. */
dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi);
- if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
+ if ( (rc = ops->read_emulated(cr2, &dst.val,
+ dst.bytes, ctxt)) != 0 )
goto done;
}
register_address_increment(
- _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ _regs.esi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
register_address_increment(
- _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ _regs.edi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
break;
case 0xa6 ... 0xa7: /* cmps */
DPRINTF("Urk! I don't handle CMPS.\n");
@@ -952,16 +955,16 @@ x86_emulate_memop(
dst.ptr = (unsigned long *)cr2;
dst.val = _regs.eax;
register_address_increment(
- _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ _regs.edi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
break;
case 0xac ... 0xad: /* lods */
dst.type = OP_REG;
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
dst.ptr = (unsigned long *)&_regs.eax;
- if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
+ if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 )
goto done;
register_address_increment(
- _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ _regs.esi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
break;
case 0xae ... 0xaf: /* scas */
DPRINTF("Urk! I don't handle SCAS.\n");
@@ -1074,8 +1077,8 @@ x86_emulate_memop(
#if defined(__i386__)
{
unsigned long old_lo, old_hi;
- if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4)) != 0) ||
- ((rc = ops->read_emulated(cr2+4, &old_hi, 4)) != 0) )
+ if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4, ctxt)) != 0) ||
+ ((rc = ops->read_emulated(cr2+4, &old_hi, 4, ctxt)) != 0) )
goto done;
if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
{
@@ -1090,8 +1093,8 @@ x86_emulate_memop(
}
else
{
- if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi,
- _regs.ebx, _regs.ecx)) != 0 )
+ if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs.ebx,
+ _regs.ecx, ctxt)) != 0 )
goto done;
_regs.eflags |= EFLG_ZF;
}
@@ -1100,7 +1103,7 @@ x86_emulate_memop(
#elif defined(__x86_64__)
{
unsigned long old, new;
- if ( (rc = ops->read_emulated(cr2, &old, 8)) != 0 )
+ if ( (rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0 )
goto done;
if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
((uint32_t)(old>>32) != (uint32_t)_regs.edx) )
@@ -1112,7 +1115,7 @@ x86_emulate_memop(
else
{
new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
- if ( (rc = ops->cmpxchg_emulated(cr2, old, new, 8)) != 0 )
+ if ( (rc = ops->cmpxchg_emulated(cr2, old, new, 8, ctxt)) != 0 )
goto done;
_regs.eflags |= EFLG_ZF;
}
@@ -1136,7 +1139,8 @@ x86_emulate_read_std(
x86_emulate_read_std(
unsigned long addr,
unsigned long *val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
*val = 0;
if ( copy_from_user((void *)val, (void *)addr, bytes) )
@@ -1151,7 +1155,8 @@ x86_emulate_write_std(
x86_emulate_write_std(
unsigned long addr,
unsigned long val,
- unsigned int bytes)
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
{
if ( copy_to_user((void *)addr, (void *)&val, bytes) )
{
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/Makefile
--- a/xen/common/Makefile Thu May 25 15:59:18 2006 -0600
+++ b/xen/common/Makefile Fri May 26 13:41:49 2006 -0600
@@ -13,6 +13,7 @@ obj-y += page_alloc.o
obj-y += page_alloc.o
obj-y += rangeset.o
obj-y += sched_bvt.o
+obj-y += sched_credit.o
obj-y += sched_sedf.o
obj-y += schedule.o
obj-y += softirq.o
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/grant_table.c
--- a/xen/common/grant_table.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/common/grant_table.c Fri May 26 13:41:49 2006 -0600
@@ -505,15 +505,12 @@ gnttab_setup_table(
goto out;
}

- if ( op.nr_frames <= NR_GRANT_FRAMES )
- {
- ASSERT(d->grant_table != NULL);
- op.status = GNTST_okay;
- for ( i = 0; i < op.nr_frames; i++ )
- {
- gmfn = gnttab_shared_gmfn(d, d->grant_table, i);
- (void)copy_to_guest_offset(op.frame_list, i, &gmfn, 1);
- }
+ ASSERT(d->grant_table != NULL);
+ op.status = GNTST_okay;
+ for ( i = 0; i < op.nr_frames; i++ )
+ {
+ gmfn = gnttab_shared_gmfn(d, d->grant_table, i);
+ (void)copy_to_guest_offset(op.frame_list, i, &gmfn, 1);
}

put_domain(d);
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/kernel.c
--- a/xen/common/kernel.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/common/kernel.c Fri May 26 13:41:49 2006 -0600
@@ -191,12 +191,11 @@ long do_xen_version(int cmd, XEN_GUEST_H
switch ( fi.submap_idx )
{
case 0:
- fi.submap = 0;
+ fi.submap = (1U << XENFEAT_pae_pgdir_above_4gb);
if ( shadow_mode_translate(current->domain) )
fi.submap |=
(1U << XENFEAT_writable_page_tables) |
- (1U << XENFEAT_auto_translated_physmap) |
- (1U << XENFEAT_pae_pgdir_above_4gb);
+ (1U << XENFEAT_auto_translated_physmap);
if ( supervisor_mode_kernel )
fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
break;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/schedule.c
--- a/xen/common/schedule.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/common/schedule.c Fri May 26 13:41:49 2006 -0600
@@ -50,9 +50,11 @@ struct schedule_data schedule_data[.NR_CP

extern struct scheduler sched_bvt_def;
extern struct scheduler sched_sedf_def;
+extern struct scheduler sched_credit_def;
static struct scheduler *schedulers[] = {
&sched_bvt_def,
&sched_sedf_def,
+ &sched_credit_def,
NULL
};

@@ -639,6 +641,8 @@ static void t_timer_fn(void *unused)

page_scrub_schedule_work();

+ SCHED_OP(tick, cpu);
+
set_timer(&t_timer[cpu], NOW() + MILLISECS(10));
}

@@ -681,6 +685,7 @@ void __init scheduler_init(void)
printk("Could not find scheduler: %s\n", opt_sched);

printk("Using scheduler: %s (%s)\n", ops.name, ops.opt_name);
+ SCHED_OP(init);

if ( idle_vcpu[0] != NULL )
{
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/trace.c
--- a/xen/common/trace.c Thu May 25 15:59:18 2006 -0600
+++ b/xen/common/trace.c Fri May 26 13:41:49 2006 -0600
@@ -91,6 +91,7 @@ static int alloc_trace_bufs(void)
if ( (rawbuf = alloc_xenheap_pages(order)) == NULL )
{
printk("Xen trace buffers: memory allocation failed\n");
+ opt_tbuf_size = 0;
return -EINVAL;
}

@@ -135,10 +136,7 @@ static int tb_set_size(int size)

opt_tbuf_size = size;
if ( alloc_trace_bufs() != 0 )
- {
- opt_tbuf_size = 0;
- return -EINVAL;
- }
+ return -EINVAL;

printk("Xen trace buffers: initialized\n");
return 0;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/domain.h Fri May 26 13:41:49 2006 -0600
@@ -120,6 +120,18 @@ struct arch_vcpu
struct vcpu_guest_context guest_context
__attribute__((__aligned__(16)));

+#ifdef CONFIG_X86_PAE
+ /*
+ * Two low-memory (<4GB) PAE L3 tables, used as fallback when the guest
+ * supplies a >=4GB PAE L3 table. We need two because we cannot set up
+ * an L3 table while we are currently running on it (without using
+ * expensive atomic 64-bit operations).
+ */
+ l3_pgentry_t lowmem_l3tab[2][4] __attribute__((__aligned__(32)));
+ unsigned long lowmem_l3tab_high_mfn[2]; /* The >=4GB MFN being shadowed. */
+ unsigned int lowmem_l3tab_inuse; /* Which lowmem_l3tab is in use? */
+#endif
+
unsigned long flags; /* TF_ */

void (*schedule_tail) (struct vcpu *);
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/domain.h Fri May 26 13:41:49 2006 -0600
@@ -35,9 +35,9 @@ struct hvm_domain {
unsigned int nr_vcpus;
unsigned int apic_enabled;
unsigned int pae_enabled;
-
- struct hvm_virpit vpit;
- u64 guest_time;
+ s64 tsc_frequency;
+ struct pl_time pl_time;
+
struct hvm_virpic vpic;
struct hvm_vioapic vioapic;
struct hvm_io_handler io_handler;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/svm/intr.h
--- a/xen/include/asm-x86/hvm/svm/intr.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/svm/intr.h Fri May 26 13:41:49 2006 -0600
@@ -21,7 +21,6 @@
#ifndef __ASM_X86_HVM_SVM_INTR_H__
#define __ASM_X86_HVM_SVM_INTR_H__

-extern void svm_set_tsc_shift(struct vcpu *v, struct hvm_virpit *vpit);
extern void svm_intr_assist(void);
extern void svm_intr_assist_update(struct vcpu *v, int highest_vector);
extern void svm_intr_assist_test_valid(struct vcpu *v,
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/svm/svm.h Fri May 26 13:41:49 2006 -0600
@@ -48,7 +48,6 @@ extern void svm_do_launch(struct vcpu *v
extern void svm_do_launch(struct vcpu *v);
extern void svm_do_resume(struct vcpu *v);
extern void svm_set_guest_time(struct vcpu *v, u64 gtime);
-extern u64 svm_get_guest_time(struct vcpu *v);
extern void arch_svm_do_resume(struct vcpu *v);
extern int load_vmcb(struct arch_svm_struct *arch_svm, u64 phys_hsa);
/* For debugging. Remove when no longer needed. */
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/vcpu.h Fri May 26 13:41:49 2006 -0600
@@ -32,6 +32,9 @@ struct hvm_vcpu {
unsigned long ioflags;
struct mmio_op mmio_op;
struct vlapic *vlapic;
+ s64 cache_tsc_offset;
+ u64 guest_time;
+
/* For AP startup */
unsigned long init_sipi_sipi_state;

diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri May 26 13:41:49 2006 -0600
@@ -34,7 +34,6 @@ extern void arch_vmx_do_launch(struct vc
extern void arch_vmx_do_launch(struct vcpu *);
extern void arch_vmx_do_resume(struct vcpu *);
extern void set_guest_time(struct vcpu *v, u64 gtime);
-extern u64 get_guest_time(struct vcpu *v);

extern unsigned int cpu_rev;

diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/hvm/vpit.h
--- a/xen/include/asm-x86/hvm/vpit.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/hvm/vpit.h Fri May 26 13:41:49 2006 -0600
@@ -29,9 +29,7 @@
#include <asm/hvm/vpic.h>

#define PIT_FREQ 1193181
-
-#define PIT_BASE 0x40
-#define HVM_PIT_ACCEL_MODE 2
+#define PIT_BASE 0x40

typedef struct PITChannelState {
int count; /* can be 65536 */
@@ -48,47 +46,56 @@ typedef struct PITChannelState {
u8 gate; /* timer start */
s64 count_load_time;
/* irq handling */
- s64 next_transition_time;
- int irq;
- struct hvm_time_info *hvm_time;
- u32 period; /* period(ns) based on count */
+ struct vcpu *vcpu;
+ struct periodic_time *pt;
} PITChannelState;
-
-struct hvm_time_info {
- /* extra info for the mode 2 channel */
- struct timer pit_timer;
- struct vcpu *vcpu; /* which vcpu the ac_timer bound to */
- u64 period_cycles; /* pit frequency in cpu cycles */
- s_time_t count_advance; /* accumulated count advance since last fire */
- s_time_t count_point; /* last point accumulating count advance */
- unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
- int first_injected; /* flag to prevent shadow window */
- s64 cache_tsc_offset; /* cache of VMCS TSC_OFFSET offset */
- u64 last_pit_gtime; /* guest time when last pit is injected */
+
+/*
+ * Abstract layer of periodic time, one short time.
+ */
+struct periodic_time {
+ char enabled; /* enabled */
+ char one_shot; /* one shot time */
+ char irq;
+ char first_injected; /* flag to prevent shadow window */
+ u32 pending_intr_nr; /* the couner for pending timer interrupts */
+ u32 period; /* frequency in ns */
+ u64 period_cycles; /* frequency in cpu cycles */
+ s_time_t scheduled; /* scheduled timer interrupt */
+ u64 last_plt_gtime; /* platform time when last IRQ is injected */
+ struct timer timer; /* ac_timer */
};

-typedef struct hvm_virpit {
+typedef struct PITState {
PITChannelState channels[3];
- struct hvm_time_info time_info;
int speaker_data_on;
int dummy_refresh_clock;
-}hvm_virpit;
+} PITState;

+struct pl_time { /* platform time */
+ struct periodic_time periodic_tm;
+ struct PITState vpit;
+ /* TODO: RTC/ACPI time */
+};

-static __inline__ s_time_t get_pit_scheduled(
- struct vcpu *v,
- struct hvm_virpit *vpit)
+static __inline__ s_time_t get_scheduled(
+ struct vcpu *v, int irq,
+ struct periodic_time *pt)
{
- struct PITChannelState *s = &(vpit->channels[0]);
- if ( is_irq_enabled(v, 0) ) {
- return s->next_transition_time;
+ if ( is_irq_enabled(v, irq) ) {
+ return pt->scheduled;
}
else
return -1;
}

/* to hook the ioreq packet to get the PIT initialization info */
-extern void pit_init(struct hvm_virpit *pit, struct vcpu *v);
-extern void pickup_deactive_ticks(struct hvm_virpit *vpit);
+extern void hvm_hooks_assist(struct vcpu *v);
+extern void pickup_deactive_ticks(struct periodic_time *vpit);
+extern u64 hvm_get_guest_time(struct vcpu *v);
+extern struct periodic_time *create_periodic_time(struct vcpu *v, u32 period, char irq, char one_shot);
+extern void destroy_periodic_time(struct periodic_time *pt);
+void pit_init(struct vcpu *v, unsigned long cpu_khz);
+void pt_timer_fn(void *data);

#endif /* __ASM_X86_HVM_VPIT_H__ */
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/string.h
--- a/xen/include/asm-x86/string.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/string.h Fri May 26 13:41:49 2006 -0600
@@ -2,152 +2,6 @@
#define __X86_STRING_H__

#include <xen/config.h>
-
-#define __HAVE_ARCH_STRCPY
-static inline char *strcpy(char *dest, const char *src)
-{
- long d0, d1, d2;
- __asm__ __volatile__ (
- "1: lodsb \n"
- " stosb \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2)
- : "0" (src), "1" (dest) : "memory" );
- return dest;
-}
-
-#define __HAVE_ARCH_STRNCPY
-static inline char *strncpy(char *dest, const char *src, size_t count)
-{
- long d0, d1, d2, d3;
- __asm__ __volatile__ (
- "1: dec %2 \n"
- " js 2f \n"
- " lodsb \n"
- " stosb \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- " rep ; stosb \n"
- "2: \n"
- : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
- : "0" (src), "1" (dest), "2" (count) : "memory" );
- return dest;
-}
-
-#define __HAVE_ARCH_STRCAT
-static inline char *strcat(char *dest, const char *src)
-{
- long d0, d1, d2, d3;
- __asm__ __volatile__ (
- " repne ; scasb \n"
- " dec %1 \n"
- "1: lodsb \n"
- " stosb \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
- : "0" (src), "1" (dest), "2" (0UL), "3" (0xffffffffUL) : "memory" );
- return dest;
-}
-
-#define __HAVE_ARCH_STRNCAT
-static inline char *strncat(char *dest, const char *src, size_t count)
-{
- long d0, d1, d2, d3;
- __asm__ __volatile__ (
- " repne ; scasb \n"
- " dec %1 \n"
- " mov %8,%3 \n"
- "1: dec %3 \n"
- " js 2f \n"
- " lodsb \n"
- " stosb \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- "2: xor %%eax,%%eax\n"
- " stosb"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
- : "0" (src), "1" (dest), "2" (0UL), "3" (0xffffffffUL), "g" (count)
- : "memory" );
- return dest;
-}
-
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char *cs, const char *ct)
-{
- long d0, d1;
- register int __res;
- __asm__ __volatile__ (
- "1: lodsb \n"
- " scasb \n"
- " jne 2f \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- " xor %%eax,%%eax\n"
- " jmp 3f \n"
- "2: sbb %%eax,%%eax\n"
- " or $1,%%al \n"
- "3: \n"
- : "=a" (__res), "=&S" (d0), "=&D" (d1)
- : "1" (cs), "2" (ct) );
- return __res;
-}
-
-#define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char *cs, const char *ct, size_t count)
-{
- long d0, d1, d2;
- register int __res;
- __asm__ __volatile__ (
- "1: dec %3 \n"
- " js 2f \n"
- " lodsb \n"
- " scasb \n"
- " jne 3f \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- "2: xor %%eax,%%eax\n"
- " jmp 4f \n"
- "3: sbb %%eax,%%eax\n"
- " or $1,%%al \n"
- "4: \n"
- : "=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
- : "1" (cs), "2" (ct), "3" (count) );
- return __res;
-}
-
-#define __HAVE_ARCH_STRCHR
-static inline char *strchr(const char *s, int c)
-{
- long d0;
- register char *__res;
- __asm__ __volatile__ (
- " mov %%al,%%ah \n"
- "1: lodsb \n"
- " cmp %%ah,%%al \n"
- " je 2f \n"
- " test %%al,%%al \n"
- " jne 1b \n"
- " mov $1,%1 \n"
- "2: mov %1,%0 \n"
- " dec %0 \n"
- : "=a" (__res), "=&S" (d0) : "1" (s), "0" (c) );
- return __res;
-}
-
-#define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char *s)
-{
- long d0;
- register int __res;
- __asm__ __volatile__ (
- " repne ; scasb \n"
- " notl %0 \n"
- " decl %0 \n"
- : "=c" (__res), "=&D" (d0) : "1" (s), "a" (0), "0" (0xffffffffUL) );
- return __res;
-}

static inline void *__variable_memcpy(void *to, const void *from, size_t n)
{
@@ -258,22 +112,6 @@ extern void *memmove(void *dest, const v
#define __HAVE_ARCH_MEMCMP
#define memcmp __builtin_memcmp

-#define __HAVE_ARCH_MEMCHR
-static inline void *memchr(const void *cs, int c, size_t count)
-{
- long d0;
- register void *__res;
- if ( count == 0 )
- return NULL;
- __asm__ __volatile__ (
- " repne ; scasb\n"
- " je 1f \n"
- " mov $1,%0 \n"
- "1: dec %0 \n"
- : "=D" (__res), "=&c" (d0) : "a" (c), "0" (cs), "1" (count) );
- return __res;
-}
-
static inline void *__memset_generic(void *s, char c, size_t count)
{
long d0, d1;
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/asm-x86/x86_emulate.h Fri May 26 13:41:49 2006 -0600
@@ -9,8 +9,10 @@
#ifndef __X86_EMULATE_H__
#define __X86_EMULATE_H__

-/*
- * x86_mem_emulator:
+struct x86_emulate_ctxt;
+
+/*
+ * x86_emulate_ops:
*
* These operations represent the instruction emulator's interface to memory.
* There are two categories of operation: those that act on ordinary memory
@@ -47,7 +49,7 @@
#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
#define X86EMUL_RETRY_INSTR 2 /* retry the instruction for some reason */
#define X86EMUL_CMPXCHG_FAILED 2 /* cmpxchg did not see expected value */
-struct x86_mem_emulator
+struct x86_emulate_ops
{
/*
* read_std: Read bytes of standard (non-emulated/special) memory.
@@ -59,7 +61,8 @@ struct x86_mem_emulator
int (*read_std)(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);

/*
* write_std: Write bytes of standard (non-emulated/special) memory.
@@ -71,7 +74,8 @@ struct x86_mem_emulator
int (*write_std)(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);

/*
* read_emulated: Read bytes from emulated/special memory area.
@@ -82,7 +86,8 @@ struct x86_mem_emulator
int (*read_emulated)(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);

/*
* write_emulated: Read bytes from emulated/special memory area.
@@ -93,7 +98,8 @@ struct x86_mem_emulator
int (*write_emulated)(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);

/*
* cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
@@ -107,11 +113,12 @@ struct x86_mem_emulator
unsigned long addr,
unsigned long old,
unsigned long new,
- unsigned int bytes);
-
- /*
- * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
- * emulated/special memory area.
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
+
+ /*
+ * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
+ * emulated/special memory area.
* @addr: [IN ] Linear address to access.
* @old: [IN ] Value expected to be current at @addr.
* @new: [IN ] Value to write to @addr.
@@ -126,7 +133,8 @@ struct x86_mem_emulator
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
- unsigned long new_hi);
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt);
};

/* Standard reader/writer functions that callers may wish to use. */
@@ -134,14 +142,28 @@ x86_emulate_read_std(
x86_emulate_read_std(
unsigned long addr,
unsigned long *val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);
extern int
x86_emulate_write_std(
unsigned long addr,
unsigned long val,
- unsigned int bytes);
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt);

struct cpu_user_regs;
+
+struct x86_emulate_ctxt
+{
+ /* Register state before/after emulation. */
+ struct cpu_user_regs *regs;
+
+ /* Linear faulting address (if emulating a page-faulting instruction). */
+ unsigned long cr2;
+
+ /* Emulated execution mode, represented by an X86EMUL_MODE value. */
+ int mode;
+};

/* Execution mode, passed to the emulator. */
#define X86EMUL_MODE_REAL 0 /* Real mode. */
@@ -159,25 +181,19 @@ struct cpu_user_regs;
/*
* x86_emulate_memop: Emulate an instruction that faulted attempting to
* read/write a 'special' memory area.
- * @regs: Register state at time of fault.
- * @cr2: Linear faulting address within an emulated/special memory area.
- * @ops: Interface to access special memory.
- * @mode: Emulated execution mode, represented by an X86EMUL_MODE value.
* Returns -1 on failure, 0 on success.
*/
-extern int
+int
x86_emulate_memop(
- struct cpu_user_regs *regs,
- unsigned long cr2,
- struct x86_mem_emulator *ops,
- int mode);
+ struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops);

/*
* Given the 'reg' portion of a ModRM byte, and a register block, return a
* pointer into the block that addresses the relevant register.
* @highbyte_regs specifies whether to decode AH,CH,DH,BH.
*/
-extern void *
+void *
decode_register(
uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs);

diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/public/io/xenbus.h
--- a/xen/include/public/io/xenbus.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/public/io/xenbus.h Fri May 26 13:41:49 2006 -0600
@@ -9,34 +9,37 @@
#ifndef _XEN_PUBLIC_IO_XENBUS_H
#define _XEN_PUBLIC_IO_XENBUS_H

-/* The state of either end of the Xenbus, i.e. the current communication
- status of initialisation across the bus. States here imply nothing about
- the state of the connection between the driver and the kernel's device
- layers. */
-typedef enum
-{
- XenbusStateUnknown = 0,
- XenbusStateInitialising = 1,
- XenbusStateInitWait = 2, /* Finished early initialisation, but waiting
- for information from the peer or hotplug
- scripts. */
- XenbusStateInitialised = 3, /* Initialised and waiting for a connection
- from the peer. */
- XenbusStateConnected = 4,
- XenbusStateClosing = 5, /* The device is being closed due to an error
- or an unplug event. */
- XenbusStateClosed = 6
+/*
+ * The state of either end of the Xenbus, i.e. the current communication
+ * status of initialisation across the bus. States here imply nothing about
+ * the state of the connection between the driver and the kernel's device
+ * layers.
+ */
+enum xenbus_state {
+ XenbusStateUnknown = 0,

-} XenbusState;
+ XenbusStateInitialising = 1,
+
+ /*
+ * InitWait: Finished early initialisation but waiting for information
+ * from the peer or hotplug scripts.
+ */
+ XenbusStateInitWait = 2,
+
+ /*
+ * Initialised: Waiting for a connection from the peer.
+ */
+ XenbusStateInitialised = 3,
+
+ XenbusStateConnected = 4,
+
+ /*
+ * Closing: The device is being closed due to an error or an unplug event.
+ */
+ XenbusStateClosing = 5,
+
+ XenbusStateClosed = 6
+};
+typedef enum xenbus_state XenbusState;

#endif /* _XEN_PUBLIC_IO_XENBUS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/public/sched_ctl.h
--- a/xen/include/public/sched_ctl.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/public/sched_ctl.h Fri May 26 13:41:49 2006 -0600
@@ -10,6 +10,7 @@
/* Scheduler types. */
#define SCHED_BVT 0
#define SCHED_SEDF 4
+#define SCHED_CREDIT 5

/* Set or get info? */
#define SCHED_INFO_PUT 0
@@ -48,6 +49,10 @@ struct sched_adjdom_cmd {
uint32_t extratime;
uint32_t weight;
} sedf;
+ struct csched_domain {
+ uint16_t weight;
+ uint16_t cap;
+ } credit;
} u;
};

diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/xen/sched-if.h
--- a/xen/include/xen/sched-if.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/xen/sched-if.h Fri May 26 13:41:49 2006 -0600
@@ -58,6 +58,8 @@ struct scheduler {
char *opt_name; /* option name for this scheduler */
unsigned int sched_id; /* ID for this scheduler */

+ void (*init) (void);
+ void (*tick) (unsigned int cpu);
int (*alloc_task) (struct vcpu *);
void (*add_task) (struct vcpu *);
void (*free_task) (struct domain *);
diff -r 9d52a66c7499 -r c073ebdbde8c xen/include/xen/softirq.h
--- a/xen/include/xen/softirq.h Thu May 25 15:59:18 2006 -0600
+++ b/xen/include/xen/softirq.h Fri May 26 13:41:49 2006 -0600
@@ -26,6 +26,19 @@ asmlinkage void do_softirq(void);
asmlinkage void do_softirq(void);
extern void open_softirq(int nr, softirq_handler handler);

+static inline void cpumask_raise_softirq(cpumask_t mask, unsigned int nr)
+{
+ int cpu;
+
+ for_each_cpu_mask(cpu, mask)
+ {
+ if ( test_and_set_bit(nr, &softirq_pending(cpu)) )
+ cpu_clear(cpu, mask);
+ }
+
+ smp_send_event_check_mask(mask);
+}
+
static inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
{
if ( !test_and_set_bit(nr, &softirq_pending(cpu)) )
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,185 @@
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <xen/cpu_hotplug.h>
+#include <xen/xenbus.h>
+
+/*
+ * Set of CPUs that remote admin software will allow us to bring online.
+ * Notified to us via xenbus.
+ */
+static cpumask_t xenbus_allowed_cpumask;
+
+/* Set of CPUs that local admin will allow us to bring online. */
+static cpumask_t local_allowed_cpumask = CPU_MASK_ALL;
+
+static int local_cpu_hotplug_request(void)
+{
+ /*
+ * We assume a CPU hotplug request comes from local admin if it is made
+ * via a userspace process (i.e., one with a real mm_struct).
+ */
+ return (current->mm != NULL);
+}
+
+static void vcpu_hotplug(unsigned int cpu)
+{
+ int err;
+ char dir[32], state[32];
+
+ if ((cpu >= NR_CPUS) || !cpu_possible(cpu))
+ return;
+
+ sprintf(dir, "cpu/%d", cpu);
+ err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state);
+ if (err != 1) {
+ printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
+ return;
+ }
+
+ if (strcmp(state, "online") == 0) {
+ cpu_set(cpu, xenbus_allowed_cpumask);
+ (void)cpu_up(cpu);
+ } else if (strcmp(state, "offline") == 0) {
+ cpu_clear(cpu, xenbus_allowed_cpumask);
+ (void)cpu_down(cpu);
+ } else {
+ printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
+ state, cpu);
+ }
+}
+
+static void handle_vcpu_hotplug_event(
+ struct xenbus_watch *watch, const char **vec, unsigned int len)
+{
+ int cpu;
+ char *cpustr;
+ const char *node = vec[XS_WATCH_PATH];
+
+ if ((cpustr = strstr(node, "cpu/")) != NULL) {
+ sscanf(cpustr, "cpu/%d", &cpu);
+ vcpu_hotplug(cpu);
+ }
+}
+
+static int smpboot_cpu_notify(struct notifier_block *notifier,
+ unsigned long action, void *hcpu)
+{
+ int cpu = (long)hcpu;
+
+ /*
+ * We do this in a callback notifier rather than __cpu_disable()
+ * because local_cpu_hotplug_request() does not work in the latter
+ * as it's always executed from within a stopmachine kthread.
+ */
+ if ((action == CPU_DOWN_PREPARE) && local_cpu_hotplug_request())
+ cpu_clear(cpu, local_allowed_cpumask);
+
+ return NOTIFY_OK;
+}
+
+static int setup_cpu_watcher(struct notifier_block *notifier,
+ unsigned long event, void *data)
+{
+ int i;
+
+ static struct xenbus_watch cpu_watch = {
+ .node = "cpu",
+ .callback = handle_vcpu_hotplug_event,
+ .flags = XBWF_new_thread };
+ (void)register_xenbus_watch(&cpu_watch);
+
+ if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
+ for_each_cpu(i)
+ vcpu_hotplug(i);
+ printk(KERN_INFO "Brought up %ld CPUs\n",
+ (long)num_online_cpus());
+ }
+
+ return NOTIFY_DONE;
+}
+
+static int __init setup_vcpu_hotplug_event(void)
+{
+ static struct notifier_block hotplug_cpu = {
+ .notifier_call = smpboot_cpu_notify };
+ static struct notifier_block xsn_cpu = {
+ .notifier_call = setup_cpu_watcher };
+
+ register_cpu_notifier(&hotplug_cpu);
+ register_xenstore_notifier(&xsn_cpu);
+
+ return 0;
+}
+
+arch_initcall(setup_vcpu_hotplug_event);
+
+int smp_suspend(void)
+{
+ int i, err;
+
+ lock_cpu_hotplug();
+
+ /*
+ * Take all other CPUs offline. We hold the hotplug mutex to
+ * avoid other processes bringing up CPUs under our feet.
+ */
+ while (num_online_cpus() > 1) {
+ unlock_cpu_hotplug();
+ for_each_online_cpu(i) {
+ if (i == 0)
+ continue;
+ err = cpu_down(i);
+ if (err) {
+ printk(KERN_CRIT "Failed to take all CPUs "
+ "down: %d.\n", err);
+ for_each_cpu(i)
+ vcpu_hotplug(i);
+ return err;
+ }
+ }
+ lock_cpu_hotplug();
+ }
+
+ return 0;
+}
+
+void smp_resume(void)
+{
+ int cpu;
+
+ for_each_cpu(cpu)
+ cpu_initialize_context(cpu);
+
+ unlock_cpu_hotplug();
+
+ for_each_cpu(cpu)
+ vcpu_hotplug(cpu);
+}
+
+int cpu_up_is_allowed(unsigned int cpu)
+{
+ int rc = 0;
+
+ if (local_cpu_hotplug_request()) {
+ cpu_set(cpu, local_allowed_cpumask);
+ if (!cpu_isset(cpu, xenbus_allowed_cpumask)) {
+ printk("%s: attempt to bring up CPU %u disallowed by "
+ "remote admin.\n", __FUNCTION__, cpu);
+ rc = -EBUSY;
+ }
+ } else if (!cpu_isset(cpu, local_allowed_cpumask) ||
+ !cpu_isset(cpu, xenbus_allowed_cpumask)) {
+ rc = -EBUSY;
+ }
+
+ return rc;
+}
+
+void init_xenbus_allowed_cpumask(void)
+{
+ xenbus_allowed_cpumask = cpu_present_map;
+}
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/e820.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/e820.h Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,63 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, setup.S populates a scratch table in the
+ * empty_zero_block that contains a list of usable address/size
+ * duples. setup.c, this information is transferred into the e820map,
+ * and in init.c/numa.c, that new information is used to mark pages
+ * reserved or not.
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#include <linux/mmzone.h>
+
+#define E820MAP 0x2d0 /* our map */
+#define E820MAX 128 /* number of entries in E820MAP */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
+#define E820_NVS 4
+
+#define HIGH_MEMORY (1024*1024)
+
+#define LOWMEMSIZE() (0x9f000)
+
+#ifndef __ASSEMBLY__
+struct e820entry {
+ u64 addr; /* start of memory segment */
+ u64 size; /* size of memory segment */
+ u32 type; /* type of memory segment */
+} __attribute__((packed));
+
+struct e820map {
+ int nr_map;
+ struct e820entry map[E820MAX];
+};
+
+extern unsigned long find_e820_area(unsigned long start, unsigned long end,
+ unsigned size);
+extern void add_memory_region(unsigned long start, unsigned long size,
+ int type);
+extern void setup_memory_region(void);
+extern void contig_e820_setup(void);
+extern unsigned long e820_end_of_ram(void);
+extern void e820_reserve_resources(struct e820entry *e820, int nr_map);
+extern void e820_print_map(char *who);
+extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
+
+extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
+extern void e820_setup_gap(struct e820entry *e820, int nr_map);
+extern unsigned long e820_hole_size(unsigned long start_pfn,
+ unsigned long end_pfn);
+
+extern void __init parse_memopt(char *p, char **end);
+extern void __init parse_memmapopt(char *p, char **end);
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/include/xen/cpu_hotplug.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,42 @@
+#ifndef __XEN_CPU_HOTPLUG_H__
+#define __XEN_CPU_HOTPLUG_H__
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/cpumask.h>
+
+#if defined(CONFIG_HOTPLUG_CPU)
+
+#if defined(CONFIG_X86)
+void cpu_initialize_context(unsigned int cpu);
+#else
+#define cpu_initialize_context(cpu) ((void)0)
+#endif
+
+int cpu_up_is_allowed(unsigned int cpu);
+void init_xenbus_allowed_cpumask(void);
+int smp_suspend(void);
+void smp_resume(void);
+
+#else /* !defined(CONFIG_HOTPLUG_CPU) */
+
+#define cpu_up_is_allowed(cpu) (1)
+#define init_xenbus_allowed_cpumask() ((void)0)
+
+static inline int smp_suspend(void)
+{
+ if (num_online_cpus() > 1) {
+ printk(KERN_WARNING "Can't suspend SMP guests "
+ "without CONFIG_HOTPLUG_CPU\n");
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static inline void smp_resume(void)
+{
+}
+
+#endif /* !defined(CONFIG_HOTPLUG_CPU) */
+
+#endif /* __XEN_CPU_HOTPLUG_H__ */
diff -r 9d52a66c7499 -r c073ebdbde8c patches/linux-2.6.16.13/fix-ide-cd-pio-mode.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/fix-ide-cd-pio-mode.patch Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,18 @@
+diff -ru ../pristine-linux-2.6.16.13/drivers/ide/ide-lib.c ./drivers/ide/ide-lib.c
+--- ../pristine-linux-2.6.16.13/drivers/ide/ide-lib.c 2006-05-02 22:38:44.000000000 +0100
++++ ./drivers/ide/ide-lib.c 2006-05-24 18:37:05.000000000 +0100
+@@ -410,10 +410,10 @@
+ {
+ u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
+
+- if (!PCI_DMA_BUS_IS_PHYS) {
+- addr = BLK_BOUNCE_ANY;
+- } else if (on && drive->media == ide_disk) {
+- if (HWIF(drive)->pci_dev)
++ if (on && drive->media == ide_disk) {
++ if (!PCI_DMA_BUS_IS_PHYS)
++ addr = BLK_BOUNCE_ANY;
++ else if (HWIF(drive)->pci_dev)
+ addr = HWIF(drive)->pci_dev->dma_mask;
+ }
+
diff -r 9d52a66c7499 -r c073ebdbde8c tools/libxc/xc_csched.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_csched.c Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * (C) 2006 - Emmanuel Ackaouy - XenSource Inc.
+ ****************************************************************************
+ *
+ * File: xc_csched.c
+ * Author: Emmanuel Ackaouy
+ *
+ * Description: XC Interface to the credit scheduler
+ *
+ */
+#include "xc_private.h"
+
+
+int
+xc_csched_domain_set(
+ int xc_handle,
+ uint32_t domid,
+ struct csched_domain *sdom)
+{
+ DECLARE_DOM0_OP;
+
+ op.cmd = DOM0_ADJUSTDOM;
+ op.u.adjustdom.domain = (domid_t) domid;
+ op.u.adjustdom.sched_id = SCHED_CREDIT;
+ op.u.adjustdom.direction = SCHED_INFO_PUT;
+ op.u.adjustdom.u.credit = *sdom;
+
+ return do_dom0_op(xc_handle, &op);
+}
+
+int
+xc_csched_domain_get(
+ int xc_handle,
+ uint32_t domid,
+ struct csched_domain *sdom)
+{
+ DECLARE_DOM0_OP;
+ int err;
+
+ op.cmd = DOM0_ADJUSTDOM;
+ op.u.adjustdom.domain = (domid_t) domid;
+ op.u.adjustdom.sched_id = SCHED_CREDIT;
+ op.u.adjustdom.direction = SCHED_INFO_GET;
+
+ err = do_dom0_op(xc_handle, &op);
+ if ( err == 0 )
+ *sdom = op.u.adjustdom.u.credit;
+
+ return err;
+}
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/xenstored_linux.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenstore/xenstored_linux.c Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "xenstored_core.h"
+
+#define XENSTORED_PROC_KVA "/proc/xen/xsd_kva"
+#define XENSTORED_PROC_PORT "/proc/xen/xsd_port"
+
+evtchn_port_t xenbus_evtchn(void)
+{
+ int fd;
+ int rc;
+ evtchn_port_t port;
+ char str[20];
+
+ fd = open(XENSTORED_PROC_PORT, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rc = read(fd, str, sizeof(str));
+ if (rc == -1)
+ {
+ int err = errno;
+ close(fd);
+ errno = err;
+ return -1;
+ }
+
+ str[rc] = '\0';
+ port = strtoul(str, NULL, 0);
+
+ close(fd);
+ return port;
+}
+
+void *xenbus_map(void)
+{
+ int fd;
+ void *addr;
+
+ fd = open(XENSTORED_PROC_KVA, O_RDWR);
+ if (fd == -1)
+ return NULL;
+
+ addr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, 0);
+
+ if (addr == MAP_FAILED)
+ addr = NULL;
+
+ close(fd);
+
+ return addr;
+}
diff -r 9d52a66c7499 -r c073ebdbde8c xen/common/sched_credit.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/sched_credit.c Fri May 26 13:41:49 2006 -0600
@@ -0,0 +1,1233 @@
+/****************************************************************************
+ * (C) 2005-2006 - Emmanuel Ackaouy - XenSource Inc.
+ ****************************************************************************
+ *
+ * File: common/csched_credit.c
+ * Author: Emmanuel Ackaouy
+ *
+ * Description: Credit-based SMP CPU scheduler
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include <xen/domain.h>
+#include <xen/delay.h>
+#include <xen/event.h>
+#include <xen/time.h>
+#include <xen/perfc.h>
+#include <xen/sched-if.h>
+#include <xen/softirq.h>
+#include <asm/atomic.h>
+
+
+/*
+ * CSCHED_STATS
+ *
+ * Manage very basic counters and stats.
+ *
+ * Useful for debugging live systems. The stats are displayed
+ * with runq dumps ('r' on the Xen console).
+ */
+#define CSCHED_STATS
+
+
+/*
+ * Basic constants
+ */
+#define CSCHED_TICK 10 /* milliseconds */
+#define CSCHED_TSLICE 30 /* milliseconds */
+#define CSCHED_ACCT_NTICKS 3
+#define CSCHED_ACCT_PERIOD (CSCHED_ACCT_NTICKS * CSCHED_TICK)
+#define CSCHED_DEFAULT_WEIGHT 256
+
+
+/*
+ * Priorities
+ */
+#define CSCHED_PRI_TS_UNDER -1 /* time-share w/ credits */
+#define CSCHED_PRI_TS_OVER -2 /* time-share w/o credits */
+#define CSCHED_PRI_IDLE -64 /* idle */
+#define CSCHED_PRI_TS_PARKED -65 /* time-share w/ capped credits */
+
+
+/*
+ * Useful macros
+ */
+#define CSCHED_PCPU(_c) ((struct csched_pcpu *)schedule_data[_c].sched_priv)
+#define CSCHED_VCPU(_vcpu) ((struct csched_vcpu *) (_vcpu)->sched_priv)
+#define CSCHED_DOM(_dom) ((struct csched_dom *) (_dom)->sched_priv)
+#define RUNQ(_cpu) (&(CSCHED_PCPU(_cpu)->runq))
+
+
+/*
+ * Stats
+ */
+#ifdef CSCHED_STATS
+
+#define CSCHED_STAT(_X) (csched_priv.stats._X)
+#define CSCHED_STAT_DEFINE(_X) uint32_t _X;
+#define CSCHED_STAT_PRINTK(_X) \
+ do \
+ { \
+ printk("\t%-30s = %u\n", #_X, CSCHED_STAT(_X)); \
+ } while ( 0 );
+
+#define CSCHED_STATS_EXPAND_SCHED(_MACRO) \
+ _MACRO(vcpu_alloc) \
+ _MACRO(vcpu_add) \
+ _MACRO(vcpu_sleep) \
+ _MACRO(vcpu_wake_running) \
+ _MACRO(vcpu_wake_onrunq) \
+ _MACRO(vcpu_wake_runnable) \
+ _MACRO(vcpu_wake_not_runnable) \
+ _MACRO(dom_free) \
+ _MACRO(schedule) \
+ _MACRO(tickle_local_idler) \
+ _MACRO(tickle_local_over) \
+ _MACRO(tickle_local_under) \
+ _MACRO(tickle_local_other) \
+ _MACRO(acct_run) \
+ _MACRO(acct_no_work) \
+ _MACRO(acct_balance) \
+ _MACRO(acct_reorder) \
+ _MACRO(acct_min_credit) \
+ _MACRO(acct_vcpu_active) \
+ _MACRO(acct_vcpu_idle) \
+ _MACRO(acct_vcpu_credit_min)
+
+#define CSCHED_STATS_EXPAND_SMP_LOAD_BALANCE(_MACRO) \
+ _MACRO(vcpu_migrate) \
+ _MACRO(load_balance_idle) \
+ _MACRO(load_balance_over) \
+ _MACRO(load_balance_other) \
+ _MACRO(steal_trylock_failed) \
+ _MACRO(steal_peer_down) \
+ _MACRO(steal_peer_idle) \
+ _MACRO(steal_peer_running) \
+ _MACRO(steal_peer_pinned) \
+ _MACRO(tickle_idlers_none) \
+ _MACRO(tickle_idlers_some)
+
+#ifndef NDEBUG
+#define CSCHED_STATS_EXPAND_CHECKS(_MACRO) \
+ _MACRO(vcpu_check)
+#else
+#define CSCHED_STATS_EXPAND_CHECKS(_MACRO)
+#endif
+
+#define CSCHED_STATS_EXPAND(_MACRO) \
+ CSCHED_STATS_EXPAND_SCHED(_MACRO) \
+ CSCHED_STATS_EXPAND_SMP_LOAD_BALANCE(_MACRO) \
+ CSCHED_STATS_EXPAND_CHECKS(_MACRO)
+
+#define CSCHED_STATS_RESET() \
+ do \
+ { \
+ memset(&csched_priv.stats, 0, sizeof(csched_priv.stats)); \
+ } while ( 0 )
+
+#define CSCHED_STATS_DEFINE() \
+ struct \
+ { \
+ CSCHED_STATS_EXPAND(CSCHED_STAT_DEFINE) \
+ } stats
+
+#define CSCHED_STATS_PRINTK() \
+ do \
+ { \
+ printk("stats:\n"); \
+ CSCHED_STATS_EXPAND(CSCHED_STAT_PRINTK) \
+ } while ( 0 )
+
+#define CSCHED_STAT_CRANK(_X) (CSCHED_STAT(_X)++)
+
+#else /* CSCHED_STATS */
+
+#define CSCHED_STATS_RESET() do {} while ( 0 )
+#define CSCHED_STATS_DEFINE() do {} while ( 0 )
+#define CSCHED_STATS_PRINTK() do {} while ( 0 )
+#define CSCHED_STAT_CRANK(_X) do {} while ( 0 )
+
+#endif /* CSCHED_STATS */
+
+
+/*
+ * Physical CPU
+ */
+struct csched_pcpu {
+ struct list_head runq;
+ uint32_t runq_sort_last;
+};
+
+/*
+ * Virtual CPU
+ */
+struct csched_vcpu {
+ struct list_head runq_elem;
+ struct list_head active_vcpu_elem;
+ struct csched_dom *sdom;
+ struct vcpu *vcpu;
+ atomic_t credit;
+ int credit_last;
+ uint32_t credit_incr;
+ uint32_t state_active;
+ uint32_t state_idle;
+ int16_t pri;
+};
+
+/*
+ * Domain
+ */
+struct csched_dom {
+ struct list_head active_vcpu;
+ struct list_head active_sdom_elem;
+ struct domain *dom;
+ uint16_t active_vcpu_count;
+ uint16_t weight;
+ uint16_t cap;
+};
+
+/*
+ * System-wide private data
+ */
+struct csched_private {
+ spinlock_t lock;
+ struct list_head active_sdom;
+ uint32_t ncpus;
+ unsigned int master;
+ cpumask_t idlers;
+ uint32_t weight;
+ uint32_t credit;
+ int credit_balance;
+ uint32_t runq_sort;
+ CSCHED_STATS_DEFINE();
+};
+
+
+/*
+ * Global variables
+ */
+static struct csched_private csched_priv;
+
+
+
+static inline int
+__vcpu_on_runq(struct csched_vcpu *svc)
+{
+ return !list_empty(&svc->runq_elem);
+}
+
+static inline struct csched_vcpu *
+__runq_elem(struct list_head *elem)
+{
+ return list_entry(elem, struct csched_vcpu, runq_elem);
+}
+
+static inline void
+__runq_insert(unsigned int cpu, struct csched_vcpu *svc)
+{
+ const struct list_head * const runq = RUNQ(cpu);
+ struct list_head *iter;
+
+ BUG_ON( __vcpu_on_runq(svc) );
+ BUG_ON( cpu != svc->vcpu->processor );
+
+ list_for_each( iter, runq )
+ {
+ const struct csched_vcpu * const iter_svc = __runq_elem(iter);
+ if ( svc->pri > iter_svc->pri )
+ break;
+ }
+
+ list_add_tail(&svc->runq_elem, iter);
+}
+
+static inline void
+__runq_remove(struct csched_vcpu *svc)
+{
+ BUG_ON( !__vcpu_on_runq(svc) );
+ list_del_init(&svc->runq_elem);
+}
+
+static inline void
+__runq_tickle(unsigned int cpu, struct csched_vcpu *new)
+{
+ struct csched_vcpu * const cur = CSCHED_VCPU(schedule_data[cpu].curr);
+ cpumask_t mask;
+
+ ASSERT(cur);
+ cpus_clear(mask);
+
+ /* If strictly higher priority than current VCPU, signal the CPU */
+ if ( new->pri > cur->pri )
+ {
+ if ( cur->pri == CSCHED_PRI_IDLE )
+ CSCHED_STAT_CRANK(tickle_local_idler);
+ else if ( cur->pri == CSCHED_PRI_TS_OVER )
+ CSCHED_STAT_CRANK(tickle_local_over);
+ else if ( cur->pri == CSCHED_PRI_TS_UNDER )
+ CSCHED_STAT_CRANK(tickle_local_under);
+ else
+ CSCHED_STAT_CRANK(tickle_local_other);
+
+ cpu_set(cpu, mask);
+ }
+
+ /*
+ * If this CPU has at least two runnable VCPUs, we tickle any idlers to
+ * let them know there is runnable work in the system...
+ */
+ if ( cur->pri > CSCHED_PRI_IDLE )
+ {
+ if ( cpus_empty(csched_priv.idlers) )
+ {
+ CSCHED_STAT_CRANK(tickle_idlers_none);
+ }
+ else
+ {
+ CSCHED_STAT_CRANK(tickle_idlers_some);
+ cpus_or(mask, mask, csched_priv.idlers);
+ }
+ }
+
+ /* Send scheduler interrupts to designated CPUs */
+ if ( !cpus_empty(mask) )
+ cpumask_raise_softirq(mask, SCHEDULE_SOFTIRQ);
+}
+
+static void
+csched_pcpu_init(int cpu)
+{
+ struct csched_pcpu *spc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&csched_priv.lock, flags);
+
+ /* Initialize/update system-wide config */
+ csched_priv.credit += CSCHED_ACCT_PERIOD;
+ if ( csched_priv.ncpus <= cpu )
+ csched_priv.ncpus = cpu + 1;
+ if ( csched_priv.master >= csched_priv.ncpus )
+ csched_priv.master = cpu;
+
+ /* Allocate per-PCPU info */
+ spc = xmalloc(struct csched_pcpu);
+ BUG_ON( spc == NULL );
+ INIT_LIST_HEAD(&spc->runq);
+ spc->runq_sort_last = csched_priv.runq_sort;
+ schedule_data[cpu].sched_priv = spc;
+
+ /* Start off idling... */
+ BUG_ON( !is_idle_vcpu(schedule_data[cpu].curr) );
+ cpu_set(cpu, csched_priv.idlers);
+
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+}
+
+#ifndef NDEBUG
+static inline void
+__csched_vcpu_check(struct vcpu *vc)
+{
+ struct csched_vcpu * const svc = CSCHED_VCPU(vc);
+ struct csched_dom * const sdom = svc->sdom;
+
+ BUG_ON( svc->vcpu != vc );
+ BUG_ON( sdom != CSCHED_DOM(vc->domain) );
+ if ( sdom )
+ {
+ BUG_ON( is_idle_vcpu(vc) );
+ BUG_ON( sdom->dom != vc->domain );
+ }
+ else
+ {
+ BUG_ON( !is_idle_vcpu(vc) );
+ }
+
+ CSCHED_STAT_CRANK(vcpu_check);
+}
+#define CSCHED_VCPU_CHECK(_vc) (__csched_vcpu_check(_vc))
+#else
+#define CSCHED_VCPU_CHECK(_vc)
+#endif
+
+static inline int
+__csched_vcpu_is_stealable(int local_cpu, struct vcpu *vc)
+{
+ /*
+ * Don't pick up work that's in the peer's scheduling tail. Also only pick
+ * up work that's allowed to run on our CPU.
+ */
+ if ( unlikely(test_bit(_VCPUF_running, &vc->vcpu_flags)) )
+ {
+ CSCHED_STAT_CRANK(steal_peer_running);
+ return 0;
+ }
+
+ if ( unlikely(!cpu_isset(local_cpu, vc->cpu_affinity)) )
+ {
+ CSCHED_STAT_CRANK(steal_peer_pinned);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+csched_vcpu_acct(struct csched_vcpu *svc, int credit_dec)
+{
+ struct csched_dom * const sdom = svc->sdom;
+ unsigned long flags;
+
+ /* Update credits */
+ atomic_sub(credit_dec, &svc->credit);
+
+ /* Put this VCPU and domain back on the active list if it was idling */
+ if ( list_empty(&svc->active_vcpu_elem) )
+ {
+ spin_lock_irqsave(&csched_priv.lock, flags);
+
+ if ( list_empty(&svc->active_vcpu_elem) )
+ {
+ CSCHED_STAT_CRANK(acct_vcpu_active);
+ svc->state_active++;
+
+ sdom->active_vcpu_count++;
+ list_add(&svc->active_vcpu_elem, &sdom->active_vcpu);
+ if ( list_empty(&sdom->active_sdom_elem) )
+ {
+ list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom);
+ csched_priv.weight += sdom->weight;
+ }
+ }
+
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+ }
+}
+
+static inline void
+__csched_vcpu_acct_idle_locked(struct csched_vcpu *svc)
+{
+ struct csched_dom * const sdom = svc->sdom;
+
+ BUG_ON( list_empty(&svc->active_vcpu_elem) );
+
+ CSCHED_STAT_CRANK(acct_vcpu_idle);
+ svc->state_idle++;
+
+ sdom->active_vcpu_count--;
+ list_del_init(&svc->active_vcpu_elem);
+ if ( list_empty(&sdom->active_vcpu) )
+ {
+ BUG_ON( csched_priv.weight < sdom->weight );
+ list_del_init(&sdom->active_sdom_elem);
+ csched_priv.weight -= sdom->weight;
+ }
+
+ atomic_set(&svc->credit, 0);
+}
+
+static int
+csched_vcpu_alloc(struct vcpu *vc)
+{
+ struct domain * const dom = vc->domain;
+ struct csched_dom *sdom;
+ struct csched_vcpu *svc;
+ int16_t pri;
+
+ CSCHED_STAT_CRANK(vcpu_alloc);
+
+ /* Allocate, if appropriate, per-domain info */
+ if ( is_idle_vcpu(vc) )
+ {
+ sdom = NULL;
+ pri = CSCHED_PRI_IDLE;
+ }
+ else if ( CSCHED_DOM(dom) )
+ {
+ sdom = CSCHED_DOM(dom);
+ pri = CSCHED_PRI_TS_UNDER;
+ }
+ else
+ {
+ sdom = xmalloc(struct csched_dom);
+ if ( !sdom )
+ return -1;
+
+ /* Initialize credit and weight */
+ INIT_LIST_HEAD(&sdom->active_vcpu);
+ sdom->active_vcpu_count = 0;
+ INIT_LIST_HEAD(&sdom->active_sdom_elem);
+ sdom->dom = dom;
+ sdom->weight = CSCHED_DEFAULT_WEIGHT;
+ sdom->cap = 0U;
+ dom->sched_priv = sdom;
+ pri = CSCHED_PRI_TS_UNDER;
+ }
+
+ /* Allocate per-VCPU info */
+ svc = xmalloc(struct csched_vcpu);
+ if ( !svc )
+ return -1;
+
+ INIT_LIST_HEAD(&svc->runq_elem);
+ INIT_LIST_HEAD(&svc->active_vcpu_elem);
+ svc->sdom = sdom;
+ svc->vcpu = vc;
+ atomic_set(&svc->credit, 0);
+ svc->credit_last = 0;
+ svc->credit_incr = 0U;
+ svc->state_active = 0U;
+ svc->state_idle = 0U;
+ svc->pri = pri;
+ vc->sched_priv = svc;
+
+ CSCHED_VCPU_CHECK(vc);
+
+ /* Attach fair-share VCPUs to the accounting list */
+ if ( likely(sdom != NULL) )
+ csched_vcpu_acct(svc, 0);
+
+ return 0;
+}
+
+static void
+csched_vcpu_add(struct vcpu *vc)
+{
+ CSCHED_STAT_CRANK(vcpu_add);
+
+ /* Allocate per-PCPU info */
+ if ( unlikely(!CSCHED_PCPU(vc->processor)) )
+ csched_pcpu_init(vc->processor);
+
+ CSCHED_VCPU_CHECK(vc);
+}
+
+static void
+csched_vcpu_free(struct vcpu *vc)
+{
+ struct csched_vcpu * const svc = CSCHED_VCPU(vc);
+ struct csched_dom * const sdom = svc->sdom;
+ unsigned long flags;
+
+ BUG_ON( sdom == NULL );
+ BUG_ON( !list_empty(&svc->runq_elem) );
+
+ spin_lock_irqsave(&csched_priv.lock, flags);
+
+ if ( !list_empty(&svc->active_vcpu_elem) )
+ __csched_vcpu_acct_idle_locked(svc);
+
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+
+ xfree(svc);
+}
+
+static void
+csched_vcpu_sleep(struct vcpu *vc)
+{
+ struct csched_vcpu * const svc = CSCHED_VCPU(vc);
+
+ CSCHED_STAT_CRANK(vcpu_sleep);
+
+ BUG_ON( is_idle_vcpu(vc) );
+
+ if ( schedule_data[vc->processor].curr == vc )
+ cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);
+ else if ( __vcpu_on_runq(svc) )
+ __runq_remove(svc);
+}
+
+static void
+csched_vcpu_wake(struct vcpu *vc)
+{
+ struct csched_vcpu * const svc = CSCHED_VCPU(vc);
+ const unsigned int cpu = vc->processor;
+
+ BUG_ON( is_idle_vcpu(vc) );
+
+ if ( unlikely(schedule_data[cpu].curr == vc) )
+ {
+ CSCHED_STAT_CRANK(vcpu_wake_running);
+ return;
+ }
+ if ( unlikely(__vcpu_on_runq(svc)) )
+ {
+ CSCHED_STAT_CRANK(vcpu_wake_onrunq);
+ return;
+ }
+
+ if ( likely(vcpu_runnable(vc)) )
+ CSCHED_STAT_CRANK(vcpu_wake_runnable);
+ else
+ CSCHED_STAT_CRANK(vcpu_wake_not_runnable);
+
+ /* Put the VCPU on the runq and tickle CPUs */
+ __runq_insert(cpu, svc);
+ __runq_tickle(cpu, svc);
+}
+
+static int
+csched_vcpu_set_affinity(struct vcpu *vc, cpumask_t *affinity)
+{
+ unsigned long flags;
+ int lcpu;
+
+ if ( vc == current )
+ {
+ /* No locking needed but also can't move on the spot... */
+ if ( !cpu_isset(vc->processor, *affinity) )
+ return -EBUSY;
+
+ vc->cpu_affinity = *affinity;
+ }
+ else
+ {
+ /* Pause, modify, and unpause. */
+ vcpu_pause(vc);
+
+ vc->cpu_affinity = *affinity;
+ if ( !cpu_isset(vc->processor, vc->cpu_affinity) )
+ {
+ /*
+ * We must grab the scheduler lock for the CPU currently owning
+ * this VCPU before changing its ownership.
+ */
+ vcpu_schedule_lock_irqsave(vc, flags);
+ lcpu = vc->processor;
+
+ vc->processor = first_cpu(vc->cpu_affinity);
+
+ spin_unlock_irqrestore(&schedule_data[lcpu].schedule_lock, flags);
+ }
+
+ vcpu_unpause(vc);
+ }
+
+ return 0;
+}
+
+static int
+csched_dom_cntl(
+ struct domain *d,
+ struct sched_adjdom_cmd *cmd)
+{
+ struct csched_dom * const sdom = CSCHED_DOM(d);
+ unsigned long flags;
+
+ if ( cmd->direction == SCHED_INFO_GET )
+ {
+ cmd->u.credit.weight = sdom->weight;
+ cmd->u.credit.cap = sdom->cap;
+ }
+ else
+ {
+ ASSERT( cmd->direction == SCHED_INFO_PUT );
+
+ spin_lock_irqsave(&csched_priv.lock, flags);
+
+ if ( cmd->u.credit.weight != 0 )
+ {
+ csched_priv.weight -= sdom->weight;
+ sdom->weight = cmd->u.credit.weight;
+ csched_priv.weight += sdom->weight;
+ }
+
+ if ( cmd->u.credit.cap != (uint16_t)~0U )
+ sdom->cap = cmd->u.credit.cap;
+
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+ }
+
+ return 0;
+}
+
+static void
+csched_dom_free(struct domain *dom)
+{
+ struct csched_dom * const sdom = CSCHED_DOM(dom);
+ int i;
+
+ CSCHED_STAT_CRANK(dom_free);
+
+ for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+ {
+ if ( dom->vcpu[i] )
+ csched_vcpu_free(dom->vcpu[i]);
+ }
+
+ xfree(sdom);
+}
+
+/*
+ * This is a O(n) optimized sort of the runq.
+ *
+ * Time-share VCPUs can only be one of two priorities, UNDER or OVER. We walk
+ * through the runq and move up any UNDERs that are preceded by OVERS. We
+ * remember the last UNDER to make the move up operation O(1).
+ */
+static void
+csched_runq_sort(unsigned int cpu)
+{
+ struct csched_pcpu * const spc = CSCHED_PCPU(cpu);
+ struct list_head *runq, *elem, *next, *last_under;
+ struct csched_vcpu *svc_elem;
+ unsigned long flags;
+ int sort_epoch;
+
+ sort_epoch = csched_priv.runq_sort;
+ if ( sort_epoch == spc->runq_sort_last )
+ return;
+
+ spc->runq_sort_last = sort_epoch;
+
+ spin_lock_irqsave(&schedule_data[cpu].schedule_lock, flags);
+
+ runq = &spc->runq;
+ elem = runq->next;
+ last_under = runq;
+
+ while ( elem != runq )
+ {
+ next = elem->next;
+ svc_elem = __runq_elem(elem);
+
+ if ( svc_elem->pri == CSCHED_PRI_TS_UNDER )
+ {
+ /* does elem need to move up the runq? */
+ if ( elem->prev != last_under )
+ {
+ list_del(elem);
+ list_add(elem, last_under);
+ }
+ last_under = elem;
+ }
+
+ elem = next;
+ }
+
+ spin_unlock_irqrestore(&schedule_data[cpu].schedule_lock, flags);
+}
+
+static void
+csched_acct(void)
+{
+ unsigned long flags;
+ struct list_head *iter_vcpu, *next_vcpu;
+ struct list_head *iter_sdom, *next_sdom;
+ struct csched_vcpu *svc;
+ struct csched_dom *sdom;
+ uint32_t credit_total;
+ uint32_t weight_total;
+ uint32_t weight_left;
+ uint32_t credit_fair;
+ uint32_t credit_peak;
+ int credit_balance;
+ int credit_xtra;
+ int credit;
+
+
+ spin_lock_irqsave(&csched_priv.lock, flags);
+
+ weight_total = csched_priv.weight;
+ credit_total = csched_priv.credit;
+
+ /* Converge balance towards 0 when it drops negative */
+ if ( csched_priv.credit_balance < 0 )
+ {
+ credit_total -= csched_priv.credit_balance;
+ CSCHED_STAT_CRANK(acct_balance);
+ }
+
+ if ( unlikely(weight_total == 0) )
+ {
+ csched_priv.credit_balance = 0;
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+ CSCHED_STAT_CRANK(acct_no_work);
+ return;
+ }
+
+ CSCHED_STAT_CRANK(acct_run);
+
+ weight_left = weight_total;
+ credit_balance = 0;
+ credit_xtra = 0;
+
+ list_for_each_safe( iter_sdom, next_sdom, &csched_priv.active_sdom )
+ {
+ sdom = list_entry(iter_sdom, struct csched_dom, active_sdom_elem);
+
+ BUG_ON( is_idle_domain(sdom->dom) );
+ BUG_ON( sdom->active_vcpu_count == 0 );
+ BUG_ON( sdom->weight == 0 );
+ BUG_ON( sdom->weight > weight_left );
+
+ weight_left -= sdom->weight;
+
+ /*
+ * A domain's fair share is computed using its weight in competition
+ * with that of all other active domains.
+ *
+ * At most, a domain can use credits to run all its active VCPUs
+ * for one full accounting period. We allow a domain to earn more
+ * only when the system-wide credit balance is negative.
+ */
+ credit_peak = sdom->active_vcpu_count * CSCHED_ACCT_PERIOD;
+ if ( csched_priv.credit_balance < 0 )
+ {
+ credit_peak += ( ( -csched_priv.credit_balance * sdom->weight) +
+ (weight_total - 1)
+ ) / weight_total;
+ }
+ if ( sdom->cap != 0U )
+ {
+ uint32_t credit_cap = ((sdom->cap * CSCHED_ACCT_PERIOD) + 99) / 100;
+ if ( credit_cap < credit_peak )
+ credit_peak = credit_cap;
+ }
+
+ credit_fair = ( ( credit_total * sdom->weight) + (weight_total - 1)
+ ) / weight_total;
+
+ if ( credit_fair < credit_peak )
+ {
+ credit_xtra = 1;
+ }
+ else
+ {
+ if ( weight_left != 0U )
+ {
+ /* Give other domains a chance at unused credits */
+ credit_total += ( ( ( credit_fair - credit_peak
+ ) * weight_total
+ ) + ( weight_left - 1 )
+ ) / weight_left;
+ }
+
+ if ( credit_xtra )
+ {
+ /*
+ * Lazily keep domains with extra credits at the head of
+ * the queue to give others a chance at them in future
+ * accounting periods.
+ */
+ CSCHED_STAT_CRANK(acct_reorder);
+ list_del(&sdom->active_sdom_elem);
+ list_add(&sdom->active_sdom_elem, &csched_priv.active_sdom);
+ }
+
+ credit_fair = credit_peak;
+ }
+
+ /* Compute fair share per VCPU */
+ credit_fair = ( credit_fair + ( sdom->active_vcpu_count - 1 )
+ ) / sdom->active_vcpu_count;
+
+
+ list_for_each_safe( iter_vcpu, next_vcpu, &sdom->active_vcpu )
+ {
+ svc = list_entry(iter_vcpu, struct csched_vcpu, active_vcpu_elem);
+ BUG_ON( sdom != svc->sdom );
+
+ /* Increment credit */
+ atomic_add(credit_fair, &svc->credit);
+ credit = atomic_read(&svc->credit);
+
+ /*
+ * Recompute priority or, if VCPU is idling, remove it from
+ * the active list.
+ */
+ if ( credit < 0 )
+ {
+ if ( sdom->cap == 0U )
+ svc->pri = CSCHED_PRI_TS_OVER;
+ else
+ svc->pri = CSCHED_PRI_TS_PARKED;
+
+ if ( credit < -CSCHED_TSLICE )
+ {
+ CSCHED_STAT_CRANK(acct_min_credit);
+ credit = -CSCHED_TSLICE;
+ atomic_set(&svc->credit, credit);
+ }
+ }
+ else
+ {
+ svc->pri = CSCHED_PRI_TS_UNDER;
+
+ if ( credit > CSCHED_TSLICE )
+ __csched_vcpu_acct_idle_locked(svc);
+ }
+
+ svc->credit_last = credit;
+ svc->credit_incr = credit_fair;
+ credit_balance += credit;
+ }
+ }
+
+ csched_priv.credit_balance = credit_balance;
+
+ spin_unlock_irqrestore(&csched_priv.lock, flags);
+
+ /* Inform each CPU that its runq needs to be sorted */
+ csched_priv.runq_sort++;
+}
+
+static void
+csched_tick(unsigned int cpu)
+{
+ struct csched_vcpu * const svc = CSCHED_VCPU(current);
+ struct csched_dom * const sdom = svc->sdom;
+
+ /*
+ * Accounting for running VCPU
+ *
+ * Note: Some VCPUs, such as the idle tasks, are not credit scheduled.
+ */
+ if ( likely(sdom != NULL) )
+ {
+ csched_vcpu_acct(svc, CSCHED_TICK);
+ }
+
+ /*
+ * Accounting duty
+ *
+ * Note: Currently, this is always done by the master boot CPU. Eventually,
+ * we could distribute or at the very least cycle the duty.
+ */
+ if ( (csched_priv.master == cpu) &&
+ (schedule_data[cpu].tick % CSCHED_ACCT_NTICKS) == 0 )
+ {
+ csched_acct();
+ }
+
+ /*
+ * Check if runq needs to be sorted
+ *
+ * Every physical CPU resorts the runq after the accounting master has
+ * modified priorities. This is a special O(n) sort and runs at most
+ * once per accounting period (currently 30 milliseconds).
+ */
+ csched_runq_sort(cpu);
+}
+
+static struct csched_vcpu *
+csched_runq_steal(struct csched_pcpu *spc, int cpu, int pri)
+{
+ struct list_head *iter;
+ struct csched_vcpu *speer;
+ struct vcpu *vc;
+
+ list_for_each( iter, &spc->runq )
+ {
+ speer = __runq_elem(iter);
+
+ /*
+ * If next available VCPU here is not of higher priority than ours,
+ * this PCPU is useless to us.
+ */
+ if ( speer->pri <= CSCHED_PRI_IDLE || speer->pri <= pri )
+ {
+ CSCHED_STAT_CRANK(steal_peer_idle);
+ break;
+ }
+
+ /* Is this VCPU is runnable on our PCPU? */
+ vc = speer->vcpu;
+ BUG_ON( is_idle_vcpu(vc) );
+
+ if ( __csched_vcpu_is_stealable(cpu, vc) )
+ {
+ /* We got a candidate. Grab it! */
+ __runq_remove(speer);
+ vc->processor = cpu;
+
+ return speer;
+ }
+ }
+
+ return NULL;
+}
+
+static struct csched_vcpu *
+csched_load_balance(int cpu, struct csched_vcpu *snext)
+{
+ struct csched_pcpu *spc;
+ struct csched_vcpu *speer;
+ int peer_cpu;
+
+ if ( snext->pri == CSCHED_PRI_IDLE )
+ CSCHED_STAT_CRANK(load_balance_idle);
+ else if ( snext->pri == CSCHED_PRI_TS_OVER )
+ CSCHED_STAT_CRANK(load_balance_over);
+ else
+ CSCHED_STAT_CRANK(load_balance_other);
+
+ peer_cpu = cpu;
+ BUG_ON( peer_cpu != snext->vcpu->processor );
+
+ while ( 1 )
+ {
+ /* For each PCPU in the system starting with our neighbour... */
+ peer_cpu = (peer_cpu + 1) % csched_priv.ncpus;
+ if ( peer_cpu == cpu )
+ break;
+
+ BUG_ON( peer_cpu >= csched_priv.ncpus );
+ BUG_ON( peer_cpu == cpu );
+
+ /*
+ * Get ahold of the scheduler lock for this peer CPU.
+ *
+ * Note: We don't spin on this lock but simply try it. Spinning could
+ * cause a deadlock if the peer CPU is also load balancing and trying
+ * to lock this CPU.
+ */
+ if ( spin_trylock(&schedule_data[peer_cpu].schedule_lock) )
+ {
+
+ spc = CSCHED_PCPU(peer_cpu);
+ if ( unlikely(spc == NULL) )
+ {
+ CSCHED_STAT_CRANK(steal_peer_down);
+ speer = NULL;
+ }
+ else
+ {
+ speer = csched_runq_steal(spc, cpu, snext->pri);
+ }
+
+ spin_unlock(&schedule_data[peer_cpu].schedule_lock);
+
+ /* Got one! */
+ if ( speer )
+ {
+ CSCHED_STAT_CRANK(vcpu_migrate);
+ return speer;
+ }
+ }
+ else
+ {
+ CSCHED_STAT_CRANK(steal_trylock_failed);
+ }
+ }
+
+
+ /* Failed to find more important work */
+ __runq_remove(snext);
+ return snext;
+}
+
+/*
+ * This function is in the critical path. It is designed to be simple and
+ * fast for the common case.
+ */
+static struct task_slice
+csched_schedule(s_time_t now)
+{
+ const int cpu = smp_processor_id();
+ struct list_head * const runq = RUNQ(cpu);
+ struct csched_vcpu * const scurr = CSCHED_VCPU(current);
+ struct csched_vcpu *snext;
+ struct task_slice ret;
+
+ CSCHED_STAT_CRANK(schedule);
+ CSCHED_VCPU_CHECK(current);
+
+ /*
+ * Select next runnable local VCPU (ie top of local runq)
+ */
+ if ( vcpu_runnable(current) )
+ __runq_insert(cpu, scurr);
+ else
+ BUG_ON( is_idle_vcpu(current) || list_empty(runq) );
+
+ snext = __runq_elem(runq->next);
+
+ /*
+ * SMP Load balance:
+ *
+ * If the next highest priority local runnable VCPU has already eaten
+ * through its credits, look on other PCPUs to see if we have more
+ * urgent work... If not, csched_load_balance() will return snext, but
+ * already removed from the runq.
+ */
+ if ( snext->pri > CSCHED_PRI_TS_OVER )
+ __runq_remove(snext);
+ else
+ snext = csched_load_balance(cpu, snext);
+
+ /*
+ * Update idlers mask if necessary. When we're idling, other CPUs
+ * will tickle us when they get extra work.
+ */
+ if ( snext->pri == CSCHED_PRI_IDLE )
+ {
+ if ( !cpu_isset(cpu, csched_priv.idlers) )
+ cpu_set(cpu, csched_priv.idlers);
+ }
+ else if ( cpu_isset(cpu, csched_priv.idlers) )
+ {
+ cpu_clear(cpu, csched_priv.idlers);
+ }
+
+ /*
+ * Return task to run next...
+ */
+ ret.time = MILLISECS(CSCHED_TSLICE);
+ ret.task = snext->vcpu;
+
+ CSCHED_VCPU_CHECK(ret.task);
+ BUG_ON( !vcpu_runnable(ret.task) );
+
+ return ret;
+}
+
+static void
+csched_dump_vcpu(struct csched_vcpu *svc)
+{
+ struct csched_dom * const sdom = svc->sdom;
+
+ printk("[%i.%i] pri=%i cpu=%i",
+ svc->vcpu->domain->domain_id,
+ svc->vcpu->vcpu_id,
+ svc->pri,
+ svc->vcpu->processor);
+
+ if ( sdom )
+ {
+ printk(" credit=%i (%d+%u) {a=%u i=%u w=%u}",
+ atomic_read(&svc->credit),
+ svc->credit_last,
+ svc->credit_incr,
+ svc->state_active,
+ svc->state_idle,
+ sdom->weight);
+ }
+
+ printk("\n");
+}
+
+static void
+csched_dump_pcpu(int cpu)
+{
+ struct list_head *runq, *iter;
+ struct csched_pcpu *spc;
+ struct csched_vcpu *svc;
+ int loop;
+
+ spc = CSCHED_PCPU(cpu);
+ runq = &spc->runq;
+
+ printk(" tick=%lu, sort=%d\n",
+ schedule_data[cpu].tick,
+ spc->runq_sort_last);
+
+ /* current VCPU */
+ svc = CSCHED_VCPU(schedule_data[cpu].curr);
+ if ( svc )
+ {
+ printk("\trun: ");
+ csched_dump_vcpu(svc);
+ }
+
+ loop = 0;
+ list_for_each( iter, runq )
+ {
+ svc = __runq_elem(iter);
+ if ( svc )
+ {
+ printk("\t%3d: ", ++loop);
+ csched_dump_vcpu(svc);
+ }
+ }
+}
+
+static void
+csched_dump(void)
+{
+ struct list_head *iter_sdom, *iter_svc;
+ int loop;
+
+ printk("info:\n"
+ "\tncpus = %u\n"
+ "\tmaster = %u\n"
+ "\tcredit = %u\n"
+ "\tcredit balance = %d\n"
+ "\tweight = %u\n"
+ "\trunq_sort = %u\n"
+ "\ttick = %dms\n"
+ "\ttslice = %dms\n"
+ "\taccounting period = %dms\n"
+ "\tdefault-weight = %d\n",
+ csched_priv.ncpus,
+ csched_priv.master,
+ csched_priv.credit,
+ csched_priv.credit_balance,
+ csched_priv.weight,
+ csched_priv.runq_sort,
+ CSCHED_TICK,
+ CSCHED_TSLICE,
+ CSCHED_ACCT_PERIOD,
+ CSCHED_DEFAULT_WEIGHT);
+
+ printk("idlers: 0x%lx\n", csched_priv.idlers.bits[0]);
+
+ CSCHED_STATS_PRINTK();
+
+ printk("active vcpus:\n");
+ loop = 0;
+ list_for_each( iter_sdom, &csched_priv.active_sdom )
+ {
+ struct csched_dom *sdom;
+ sdom = list_entry(iter_sdom, struct csched_dom, active_sdom_elem);
+
+ list_for_each( iter_svc, &sdom->active_vcpu )
+ {
+ struct csched_vcpu *svc;
+ svc = list_entry(iter_svc, struct csched_vcpu, active_vcpu_elem);
+
+ printk("\t%3d: ", ++loop);
+ csched_dump_vcpu(svc);
+ }
+ }
+}
+
+static void
+csched_init(void)
+{
+ spin_lock_init(&csched_priv.lock);
+ INIT_LIST_HEAD(&csched_priv.active_sdom);
+ csched_priv.ncpus = 0;
+ csched_priv.master = UINT_MAX;
+ cpus_clear(csched_priv.idlers);
+ csched_priv.weight = 0U;
+ csched_priv.credit = 0U;
+ csched_priv.credit_balance = 0;
+ csched_priv.runq_sort = 0U;
+ CSCHED_STATS_RESET();
+}
+
+
+struct scheduler sched_credit_def = {
+ .name = "SMP Credit Scheduler",
+ .opt_name = "credit",
+ .sched_id = SCHED_CREDIT,
+
+ .alloc_task = csched_vcpu_alloc,
+ .add_task = csched_vcpu_add,
+ .sleep = csched_vcpu_sleep,
+ .wake = csched_vcpu_wake,
+ .set_affinity = csched_vcpu_set_affinity,
+
+ .adjdom = csched_dom_cntl,
+ .free_task = csched_dom_free,
+
+ .tick = csched_tick,
+ .do_schedule = csched_schedule,
+
+ .dump_cpu_state = csched_dump_pcpu,
+ .dump_settings = csched_dump,
+ .init = csched_init,
+};
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/drivers/xen/net_driver_util.c
--- a/linux-2.6-xen-sparse/drivers/xen/net_driver_util.c Thu May 25 15:59:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*****************************************************************************
- *
- * Utility functions for Xen network devices.
- *
- * Copyright (c) 2005 XenSource Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/if_ether.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <xen/net_driver_util.h>
-
-
-int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
-{
- char *s;
- int i;
- char *e;
- char *macstr = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
- if (IS_ERR(macstr))
- return PTR_ERR(macstr);
- s = macstr;
- for (i = 0; i < ETH_ALEN; i++) {
- mac[i] = simple_strtoul(s, &e, 16);
- if (s == e || (e[0] != ':' && e[0] != 0)) {
- kfree(macstr);
- return -ENOENT;
- }
- s = &e[1];
- }
- kfree(macstr);
- return 0;
-}
-EXPORT_SYMBOL_GPL(xen_net_read_mac);
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/include/asm-x86_64/e820.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/e820.h Thu May 25 15:59:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * structures and definitions for the int 15, ax=e820 memory map
- * scheme.
- *
- * In a nutshell, setup.S populates a scratch table in the
- * empty_zero_block that contains a list of usable address/size
- * duples. setup.c, this information is transferred into the e820map,
- * and in init.c/numa.c, that new information is used to mark pages
- * reserved or not.
- */
-#ifndef __E820_HEADER
-#define __E820_HEADER
-
-#include <linux/mmzone.h>
-
-#define E820MAP 0x2d0 /* our map */
-#define E820MAX 128 /* number of entries in E820MAP */
-#define E820NR 0x1e8 /* # entries in E820MAP */
-
-#define E820_RAM 1
-#define E820_RESERVED 2
-#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
-#define E820_NVS 4
-
-#define HIGH_MEMORY (1024*1024)
-
-#define LOWMEMSIZE() (0x9f000)
-
-#ifndef __ASSEMBLY__
-struct e820entry {
- u64 addr; /* start of memory segment */
- u64 size; /* size of memory segment */
- u32 type; /* type of memory segment */
-} __attribute__((packed));
-
-struct e820map {
- int nr_map;
- struct e820entry map[E820MAX];
-};
-
-extern unsigned long find_e820_area(unsigned long start, unsigned long end,
- unsigned size);
-extern void add_memory_region(unsigned long start, unsigned long size,
- int type);
-extern void setup_memory_region(void);
-extern void contig_e820_setup(void);
-extern unsigned long e820_end_of_ram(void);
-extern void e820_reserve_resources(struct e820entry *e820, int nr_map);
-extern void e820_print_map(char *who);
-extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
-
-extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
-extern void e820_setup_gap(struct e820entry *e820, int nr_map);
-extern unsigned long e820_hole_size(unsigned long start_pfn,
- unsigned long end_pfn);
-
-extern void __init parse_memopt(char *p, char **end);
-extern void __init parse_memmapopt(char *p, char **end);
-
-extern struct e820map e820;
-#endif/*!__ASSEMBLY__*/
-
-#endif/*__E820_HEADER*/
diff -r 9d52a66c7499 -r c073ebdbde8c linux-2.6-xen-sparse/include/xen/net_driver_util.h
--- a/linux-2.6-xen-sparse/include/xen/net_driver_util.h Thu May 25 15:59:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*****************************************************************************
- *
- * Utility functions for Xen network devices.
- *
- * Copyright (c) 2005 XenSource Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _ASM_XEN_NET_DRIVER_UTIL_H
-#define _ASM_XEN_NET_DRIVER_UTIL_H
-
-
-#include <xen/xenbus.h>
-
-
-/**
- * Read the 'mac' node at the given device's node in the store, and parse that
- * as colon-separated octets, placing result the given mac array. mac must be
- * a preallocated array of length ETH_ALEN (as declared in linux/if_ether.h).
- * Return 0 on success, or -errno on error.
- */
-int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]);
-
-
-#endif /* _ASM_XEN_NET_DRIVER_UTIL_H */
diff -r 9d52a66c7499 -r c073ebdbde8c tools/xenstore/xenstored_proc.h
--- a/tools/xenstore/xenstored_proc.h Thu May 25 15:59:18 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- Copyright (C) 2005 XenSource Ltd
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-#ifndef _XENSTORED_PROC_H
-#define _XENSTORED_PROC_H
-
-#define XENSTORED_PROC_KVA "/proc/xen/xsd_kva"
-#define XENSTORED_PROC_PORT "/proc/xen/xsd_port"
-
-
-#endif /* _XENSTORED_PROC_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog
merge with xen-unstable.hg [ In reply to ]
# HG changeset patch
# User awilliam@xenbuild.aw
# Node ID acabf4bdec4fb4cca056f4c80deaab32e9f1b767
# Parent 3be4c828873766eb580541b2f977f01a72431991
# Parent 0ec4b9dfd5b441fef5422c98077b30a7f29f10d9
merge with xen-unstable.hg
---
tools/vtpm/tpm_emulator-0.2b-x86_64.patch | 431 ----------
.hgignore | 6
Config.mk | 14
Makefile | 2
config/ia64.mk | 4
config/x86_32.mk | 9
config/x86_64.mk | 9
docs/src/interface.tex | 29
docs/src/user.tex | 32
extras/mini-os/Makefile | 3
extras/mini-os/include/mm.h | 21
extras/mini-os/minios-x86_32.lds | 2
extras/mini-os/minios-x86_64.lds | 2
extras/mini-os/mm.c | 90 +-
extras/mini-os/x86_32.S | 4
extras/mini-os/x86_64.S | 4
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c | 14
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 20
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 15
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 6
linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c | 2
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 11
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h | 2
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h | 7
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h | 4
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h | 7
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h | 7
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h | 4
linux-2.6-xen-sparse/include/xen/cpu_hotplug.h | 6
tools/Makefile | 47 -
tools/Rules.mk | 2
tools/firmware/hvmloader/Makefile | 12
tools/firmware/rombios/Makefile | 4
tools/ioemu/hw/ne2000.c | 36
tools/libxc/Makefile | 75 -
tools/libxc/xc_core.c | 2
tools/libxc/xc_csched.c | 8
tools/libxc/xc_hvm_build.c | 2
tools/libxc/xc_linux_build.c | 8
tools/libxc/xc_load_elf.c | 8
tools/libxc/xenctrl.h | 14
tools/libxc/xg_private.c | 15
tools/libxc/xg_private.h | 8
tools/misc/Makefile | 2
tools/python/xen/lowlevel/xc/xc.c | 36
tools/python/xen/xend/XendDomain.py | 8
tools/python/xen/xend/server/SrvDomain.py | 8
tools/python/xen/xm/main.py | 18
tools/vtpm/Makefile | 14
tools/vtpm/Rules.mk | 1
tools/vtpm/tpm_emulator-0.3-x86_64.patch | 381 ++++++++
tools/vtpm/vtpm.patch | 407 +++++++--
xen/arch/x86/domain.c | 2
xen/arch/x86/hvm/io.c | 10
xen/arch/x86/hvm/platform.c | 24
xen/arch/x86/hvm/svm/svm.c | 160 +++
xen/arch/x86/mm.c | 175 ++--
xen/arch/x86/shadow.c | 3
xen/arch/x86/shadow32.c | 3
xen/include/asm-x86/domain.h | 29
xen/include/asm-x86/fixmap.h | 10
xen/include/asm-x86/shadow.h | 12
xen/include/public/sched_ctl.h | 2
xen/include/xen/perfc.h | 6
xen/tools/Makefile | 3
xen/tools/figlet/Makefile | 3
66 files changed, 1407 insertions(+), 918 deletions(-)

diff -r 3be4c8288737 -r acabf4bdec4f .hgignore
--- a/.hgignore Wed May 31 11:30:07 2006 -0600
+++ b/.hgignore Wed May 31 13:05:21 2006 -0600
@@ -113,9 +113,9 @@
^tools/firmware/acpi/acpigen$
^tools/firmware/hvmloader/hvmloader$
^tools/firmware/hvmloader/roms\.h$
-^tools/firmware/rombios/BIOS-bochs-latest$
-^tools/firmware/rombios/_rombios_\.c$
-^tools/firmware/rombios/rombios\.s$
+^tools/firmware/rombios/BIOS-bochs-[^/]*$
+^tools/firmware/rombios/_rombios[^/]*_\.c$
+^tools/firmware/rombios/rombios[^/]*\.s$
^tools/firmware/vmxassist/acpi\.h$
^tools/firmware/vmxassist/gen$
^tools/firmware/vmxassist/offsets\.h$
diff -r 3be4c8288737 -r acabf4bdec4f Config.mk
--- a/Config.mk Wed May 31 11:30:07 2006 -0600
+++ b/Config.mk Wed May 31 13:05:21 2006 -0600
@@ -39,19 +39,7 @@ CFLAGS += -g
CFLAGS += -g
endif

-ifeq ($(XEN_TARGET_ARCH),x86_32)
-CFLAGS += -m32 -march=i686
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
-CFLAGS += -m64
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
-LIBDIR = lib64
-else
-LIBDIR = lib
-endif
+include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk

ifneq ($(EXTRA_PREFIX),)
EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
diff -r 3be4c8288737 -r acabf4bdec4f Makefile
--- a/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/Makefile Wed May 31 13:05:21 2006 -0600
@@ -17,7 +17,7 @@ endif
.PHONY: all
all: dist

-XEN_ROOT=$(CURDIR)
+export XEN_ROOT=$(CURDIR)
include Config.mk
include buildconfigs/Rules.mk

diff -r 3be4c8288737 -r acabf4bdec4f docs/src/interface.tex
--- a/docs/src/interface.tex Wed May 31 11:30:07 2006 -0600
+++ b/docs/src/interface.tex Wed May 31 13:05:21 2006 -0600
@@ -205,30 +205,23 @@ implement timeout values when they block
implement timeout values when they block.


-
-%% % akw: demoting this to a section -- not sure if there is any point
-%% % though, maybe just remove it.
-
-% KAF: Remove these random sections!
-\begin{comment}
\section{Xen CPU Scheduling}

Xen offers a uniform API for CPU schedulers. It is possible to choose
from a number of schedulers at boot and it should be easy to add more.
-The BVT, Atropos and Round Robin schedulers are part of the normal Xen
-distribution. BVT provides proportional fair shares of the CPU to the
-running domains. Atropos can be used to reserve absolute shares of
-the CPU for each domain. Round-robin is provided as an example of
-Xen's internal scheduler API.
+The SEDF, BVT, and Credit schedulers are part of the normal Xen
+distribution. BVT and SEDF will be going away and their use should be
+avoided once the credit scheduler has stabilized and become the default.
+The Credit scheduler provides proportional fair shares of the
+host's CPUs to the running domains. It does this while transparently
+load balancing runnable VCPUs across the whole system.

\paragraph*{Note: SMP host support}
-Xen has always supported SMP host systems. Domains are statically
-assigned to CPUs, either at creation time or when manually pinning to
-a particular CPU. The current schedulers then run locally on each CPU
-to decide which of the assigned domains should be run there. The
-user-level control software can be used to perform coarse-grain
-load-balancing between CPUs.
-\end{comment}
+Xen has always supported SMP host systems. When using the credit scheduler,
+a domain's VCPUs will be dynamically moved across physical CPUs to maximise
+domain and system throughput. VCPUs can also be manually restricted to be
+mapped only on a subset of the host's physical CPUs, using the pinning
+mechanism.


%% More information on the characteristics and use of these schedulers
diff -r 3be4c8288737 -r acabf4bdec4f docs/src/user.tex
--- a/docs/src/user.tex Wed May 31 11:30:07 2006 -0600
+++ b/docs/src/user.tex Wed May 31 13:05:21 2006 -0600
@@ -1093,6 +1093,36 @@ running domains in \xend's SXP configura

You can get access to the console of a particular domain using
the \verb_# xm console_ command (e.g.\ \verb_# xm console myVM_).
+
+\subsection{Domain Scheduling Management Commands}
+
+The credit CPU scheduler automatically load balances guest VCPUs
+across all available physical CPUs on an SMP host. The user need
+not manually pin VCPUs to load balance the system. However, she
+can restrict which CPUs a particular VCPU may run on using
+the \path{xm vcpu-pin} command.
+
+Each guest domain is assigned a \path{weight} and a \path{cap}.
+
+A domain with a weight of 512 will get twice as much CPU as a
+domain with a weight of 256 on a contended host. Legal weights
+range from 1 to 65535 and the default is 256.
+
+The cap optionally fixes the maximum amount of CPU a guest will
+be able to consume, even if the host system has idle CPU cycles.
+The cap is expressed in percentage of one physical CPU: 100 is
+1 physical CPU, 50 is half a CPU, 400 is 4 CPUs, etc... The
+default, 0, means there is no upper cap.
+
+When you are running with the credit scheduler, you can check and
+modify your domains' weights and caps using the \path{xm sched-credit}
+command:
+
+\begin{tabular}{ll}
+\verb!xm sched-credit -d <domain>! & lists weight and cap \\
+\verb!xm sched-credit -d <domain> -w <weight>! & sets the weight \\
+\verb!xm sched-credit -d <domain> -c <cap>! & sets the cap
+\end{tabular}



@@ -1985,7 +2015,7 @@ editing \path{grub.conf}.
\item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
pages (default 0).
\item [ sched=xxx ] Select the CPU scheduler Xen should use. The
- current possibilities are `sedf' (default) and `bvt'.
+ current possibilities are `sedf' (default), `credit', and `bvt'.
\item [ apic\_verbosity=debug,verbose ] Print more detailed
information about local APIC and IOAPIC configuration.
\item [ lapic ] Force use of local APIC even when left disabled by
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/Makefile Wed May 31 13:05:21 2006 -0600
@@ -1,7 +1,8 @@ debug ?= y
debug ?= y
pae ?= n

-include $(CURDIR)/../../Config.mk
+XEN_ROOT = ../..
+include $(XEN_ROOT)/Config.mk

# Set TARGET_ARCH
override TARGET_ARCH := $(XEN_TARGET_ARCH)
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/include/mm.h Wed May 31 13:05:21 2006 -0600
@@ -53,7 +53,7 @@
#define PADDR_BITS 32
#define PADDR_MASK (~0UL)

-#define UNMAPPED_PT_FRAMES 1
+#define NOT_L1_FRAMES 1
#define PRIpte "08lx"
typedef unsigned long pgentry_t;

@@ -71,7 +71,12 @@ typedef unsigned long pgentry_t;

#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)

-#define UNMAPPED_PT_FRAMES 2
+/*
+ * If starting from virtual address greater than 0xc0000000,
+ * this value will be 2 to account for final mid-level page
+ * directory which is always mapped in at this location.
+ */
+#define NOT_L1_FRAMES 3
#define PRIpte "016llx"
typedef uint64_t pgentry_t;

@@ -94,20 +99,10 @@ typedef uint64_t pgentry_t;
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
#define VADDR_MASK ((1UL << VADDR_BITS)-1)

-/* Get physical address of page mapped by pte (paddr_t). */
-#define l1e_get_paddr(x) \
- ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l2e_get_paddr(x) \
- ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l3e_get_paddr(x) \
- ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l4e_get_paddr(x) \
- ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)

-#define UNMAPPED_PT_FRAMES 3
+#define NOT_L1_FRAMES 3
#define PRIpte "016lx"
typedef unsigned long pgentry_t;

diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/minios-x86_32.lds
--- a/extras/mini-os/minios-x86_32.lds Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/minios-x86_32.lds Wed May 31 13:05:21 2006 -0600
@@ -3,7 +3,7 @@ ENTRY(_start)
ENTRY(_start)
SECTIONS
{
- . = 0xC0000000;
+ . = 0x0;
_text = .; /* Text and read-only data */
.text : {
*(.text)
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/minios-x86_64.lds Wed May 31 13:05:21 2006 -0600
@@ -3,7 +3,7 @@ ENTRY(_start)
ENTRY(_start)
SECTIONS
{
- . = 0xFFFFFFFF80000000;
+ . = 0x0;
_text = .; /* Text and read-only data */
.text : {
*(.text)
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/mm.c
--- a/extras/mini-os/mm.c Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/mm.c Wed May 31 13:05:21 2006 -0600
@@ -375,7 +375,7 @@ void new_pt_frame(unsigned long *pt_pfn,
struct mmuext_op pin_request;

DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
- "prev_l_mfn=%lx, offset=%lx\n",
+ "prev_l_mfn=%lx, offset=%lx",
level, *pt_pfn, prev_l_mfn, offset);

/* We need to clear the page, otherwise we might fail to map it
@@ -442,12 +442,64 @@ void new_pt_frame(unsigned long *pt_pfn,
mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
- {
+ {
printk("ERROR: mmu_update failed\n");
do_exit();
}

*pt_pfn += 1;
+}
+
+/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
+static int need_pt_frame(unsigned long virt_address, int level)
+{
+ unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
+#if defined(__x86_64__)
+ unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
+#else
+ unsigned long hyp_virt_end = 0xffffffff;
+#endif
+
+ /* In general frames will _not_ be needed if they were already
+ allocated to map the hypervisor into our VA space */
+#if defined(__x86_64__)
+ if(level == L3_FRAME)
+ {
+ if(l4_table_offset(virt_address) >=
+ l4_table_offset(hyp_virt_start) &&
+ l4_table_offset(virt_address) <=
+ l4_table_offset(hyp_virt_end))
+ return 0;
+ return 1;
+ } else
+#endif
+
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
+ if(level == L2_FRAME)
+ {
+#if defined(__x86_64__)
+ if(l4_table_offset(virt_address) >=
+ l4_table_offset(hyp_virt_start) &&
+ l4_table_offset(virt_address) <=
+ l4_table_offset(hyp_virt_end))
+#endif
+ if(l3_table_offset(virt_address) >=
+ l3_table_offset(hyp_virt_start) &&
+ l3_table_offset(virt_address) <=
+ l3_table_offset(hyp_virt_end))
+ return 0;
+
+ return 1;
+ } else
+#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
+
+ /* Always need l1 frames */
+ if(level == L1_FRAME)
+ return 1;
+
+ printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n",
+ level, hyp_virt_start, hyp_virt_end);
+ return -1;
}

void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
@@ -460,11 +512,21 @@ void build_pagetable(unsigned long *star
unsigned long offset;
int count = 0;

- pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * L1_PAGETABLE_ENTRIES;
+ pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
+
+ if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
+ {
+ printk("WARNING: Mini-OS trying to use Xen virtual space. "
+ "Truncating memory from %dMB to ",
+ ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
+ *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
+ printk("%dMB\n",
+ ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
+ }

start_address = (unsigned long)pfn_to_virt(pfn_to_map);
end_address = (unsigned long)pfn_to_virt(*max_pfn);
-
+
/* We worked out the virtual memory range to map, now mapping loop */
printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);

@@ -477,8 +539,9 @@ void build_pagetable(unsigned long *star
offset = l4_table_offset(start_address);
/* Need new L3 pt frame */
if(!(start_address & L3_MASK))
- new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
-
+ if(need_pt_frame(start_address, L3_FRAME))
+ new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
+
page = tab[offset];
mfn = pte_to_mfn(page);
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
@@ -486,8 +549,9 @@ void build_pagetable(unsigned long *star
#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
offset = l3_table_offset(start_address);
/* Need new L2 pt frame */
- if(!(start_address & L2_MASK))
- new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
+ if(!(start_address & L2_MASK))
+ if(need_pt_frame(start_address, L2_FRAME))
+ new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);

page = tab[offset];
mfn = pte_to_mfn(page);
@@ -495,16 +559,16 @@ void build_pagetable(unsigned long *star
#endif
offset = l2_table_offset(start_address);
/* Need new L1 pt frame */
- if(!(start_address & L1_MASK))
- new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
-
+ if(!(start_address & L1_MASK))
+ if(need_pt_frame(start_address, L1_FRAME))
+ new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
+
page = tab[offset];
mfn = pte_to_mfn(page);
offset = l1_table_offset(start_address);

mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
- mmu_updates[count].val =
- (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
+ mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
count++;
if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
{
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/x86_32.S Wed May 31 13:05:21 2006 -0600
@@ -4,8 +4,8 @@
.section __xen_guest
.ascii "GUEST_OS=Mini-OS"
.ascii ",XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */
- .ascii ",ELF_PADDR_OFFSET=0xc0000000"
+ .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
+ .ascii ",ELF_PADDR_OFFSET=0x0"
.ascii ",HYPERCALL_PAGE=0x2"
#ifdef CONFIG_X86_PAE
.ascii ",PAE=yes"
diff -r 3be4c8288737 -r acabf4bdec4f extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S Wed May 31 11:30:07 2006 -0600
+++ b/extras/mini-os/x86_64.S Wed May 31 13:05:21 2006 -0600
@@ -4,8 +4,8 @@
.section __xen_guest
.ascii "GUEST_OS=Mini-OS"
.ascii ",XEN_VER=xen-3.0"
- .ascii ",VIRT_BASE=0xffffffff80000000" /* &_text from minios_x86_64.lds */
- .ascii ",ELF_PADDR_OFFSET=0xffffffff80000000"
+ .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
+ .ascii ",ELF_PADDR_OFFSET=0x0"
.ascii ",HYPERCALL_PAGE=0x2"
.ascii ",LOADER=generic"
.byte 0
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Wed May 31 13:05:21 2006 -0600
@@ -55,6 +55,7 @@

#include <xen/interface/physdev.h>
#include <xen/interface/vcpu.h>
+#include <xen/cpu_hotplug.h>

#include <linux/err.h>

@@ -101,8 +102,6 @@ EXPORT_SYMBOL(enable_hlt);
EXPORT_SYMBOL(enable_hlt);

/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
void xen_idle(void)
{
local_irq_disable();
@@ -112,10 +111,7 @@ void xen_idle(void)
else {
clear_thread_flag(TIF_POLLING_NRFLAG);
smp_mb__after_clear_bit();
- stop_hz_timer();
- /* Blocking includes an implicit local_irq_enable(). */
- HYPERVISOR_block();
- start_hz_timer();
+ safe_halt();
set_thread_flag(TIF_POLLING_NRFLAG);
}
}
@@ -132,11 +128,7 @@ static inline void play_dead(void)
cpu_clear(smp_processor_id(), cpu_initialized);
preempt_enable_no_resched();
HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
- /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
- cpu_init();
- touch_softlockup_watchdog();
- preempt_disable();
- local_irq_enable();
+ cpu_bringup();
}
#else
static inline void play_dead(void)
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Wed May 31 13:05:21 2006 -0600
@@ -973,7 +973,7 @@ EXPORT_SYMBOL(jiffies_to_st);
* stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
* These functions are based on implementations from arch/s390/kernel/time.c
*/
-void stop_hz_timer(void)
+static void stop_hz_timer(void)
{
unsigned int cpu = smp_processor_id();
unsigned long j;
@@ -993,10 +993,26 @@ void stop_hz_timer(void)
BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
}

-void start_hz_timer(void)
+static void start_hz_timer(void)
{
cpu_clear(smp_processor_id(), nohz_cpu_mask);
}
+
+void safe_halt(void)
+{
+ stop_hz_timer();
+ /* Blocking includes an implicit local_irq_enable(). */
+ HYPERVISOR_block();
+ start_hz_timer();
+}
+EXPORT_SYMBOL(safe_halt);
+
+void halt(void)
+{
+ if (irqs_disabled())
+ HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
+}
+EXPORT_SYMBOL(halt);

/* No locking required. We are only CPU running, and interrupts are off. */
void time_resume(void)
diff -r 3be4c8288737 -r acabf4bdec4f 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 May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed May 31 13:05:21 2006 -0600
@@ -60,6 +60,8 @@
#include <asm/ia32.h>
#include <asm/idle.h>

+#include <xen/cpu_hotplug.h>
+
asmlinkage extern void ret_from_fork(void);

unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
@@ -118,8 +120,6 @@ void exit_idle(void)
}

/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
void xen_idle(void)
{
local_irq_disable();
@@ -129,10 +129,7 @@ void xen_idle(void)
else {
clear_thread_flag(TIF_POLLING_NRFLAG);
smp_mb__after_clear_bit();
- stop_hz_timer();
- /* Blocking includes an implicit local_irq_enable(). */
- HYPERVISOR_block();
- start_hz_timer();
+ safe_halt();
set_thread_flag(TIF_POLLING_NRFLAG);
}
}
@@ -145,11 +142,7 @@ static inline void play_dead(void)
cpu_clear(smp_processor_id(), cpu_initialized);
preempt_enable_no_resched();
HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
- /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
- cpu_init();
- touch_softlockup_watchdog();
- preempt_disable();
- local_irq_enable();
+ cpu_bringup();
}
#else
static inline void play_dead(void)
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed May 31 13:05:21 2006 -0600
@@ -360,12 +360,6 @@ static void balloon_process(void *unused
/* Resets the Xen limit, sets new target, and kicks off processing. */
static void set_new_target(unsigned long target)
{
- unsigned long min_target;
-
- /* Do not allow target to reduce below 2% of maximum memory size. */
- min_target = max_pfn / 50;
- target = max(target, min_target);
-
/* No need for lock. Not read-modify-write updates. */
hard_limit = ~0UL;
target_pages = target;
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Wed May 31 13:05:21 2006 -0600
@@ -160,7 +160,7 @@ void smp_resume(void)
vcpu_hotplug(cpu);
}

-int cpu_up_is_allowed(unsigned int cpu)
+int cpu_up_check(unsigned int cpu)
{
int rc = 0;

diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Wed May 31 13:05:21 2006 -0600
@@ -150,12 +150,17 @@ static void xen_smp_intr_exit(unsigned i
}
#endif

-static void cpu_bringup(void)
+void cpu_bringup(void)
{
cpu_init();
touch_softlockup_watchdog();
preempt_disable();
local_irq_enable();
+}
+
+static void cpu_bringup_and_idle(void)
+{
+ cpu_bringup();
cpu_idle();
}

@@ -180,7 +185,7 @@ void cpu_initialize_context(unsigned int
ctxt.user_regs.fs = 0;
ctxt.user_regs.gs = 0;
ctxt.user_regs.ss = __KERNEL_DS;
- ctxt.user_regs.eip = (unsigned long)cpu_bringup;
+ ctxt.user_regs.eip = (unsigned long)cpu_bringup_and_idle;
ctxt.user_regs.eflags = X86_EFLAGS_IF | 0x1000; /* IOPL_RING1 */

memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
@@ -400,7 +405,7 @@ int __devinit __cpu_up(unsigned int cpu)
{
int rc;

- rc = cpu_up_is_allowed(cpu);
+ rc = cpu_up_check(cpu);
if (rc)
return rc;

diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Wed May 31 13:05:21 2006 -0600
@@ -128,8 +128,6 @@ dma_get_cache_alignment(void)
* maximum possible, to be safe */
return (1 << INTERNODE_CACHE_SHIFT);
}
-#else
-extern int dma_get_cache_alignment(void);
#endif

#define dma_is_consistent(d) (1)
diff -r 3be4c8288737 -r acabf4bdec4f 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 May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Wed May 31 13:05:21 2006 -0600
@@ -260,6 +260,13 @@ HYPERVISOR_event_channel_op(
}

static inline int
+HYPERVISOR_acm_op(
+ int cmd, void *arg)
+{
+ return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
HYPERVISOR_xen_version(
int cmd, void *arg)
{
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Wed May 31 13:05:21 2006 -0600
@@ -625,8 +625,8 @@ do { \
preempt_enable_no_resched(); \
} while (0)

-#define safe_halt() ((void)0)
-#define halt() ((void)0)
+void safe_halt(void);
+void halt(void);

#define __save_and_cli(x) \
do { \
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed May 31 13:05:21 2006 -0600
@@ -247,6 +247,13 @@ HYPERVISOR_event_channel_op(
}

static inline int
+HYPERVISOR_acm_op(
+ unsigned int cmd, void *arg)
+{
+ return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
HYPERVISOR_xen_version(
int cmd, void *arg)
{
diff -r 3be4c8288737 -r acabf4bdec4f 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 May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Wed May 31 13:05:21 2006 -0600
@@ -258,6 +258,13 @@ HYPERVISOR_event_channel_op(
}

static inline int
+HYPERVISOR_acm_op(
+ int cmd, void *arg)
+{
+ return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
HYPERVISOR_xen_version(
int cmd, void *arg)
{
diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h Wed May 31 13:05:21 2006 -0600
@@ -424,8 +424,8 @@ do { \
preempt_enable_no_resched(); \
___x; })

-#define safe_halt() ((void)0)
-#define halt() ((void)0)
+void safe_halt(void);
+void halt(void);

void cpu_idle_wait(void);

diff -r 3be4c8288737 -r acabf4bdec4f linux-2.6-xen-sparse/include/xen/cpu_hotplug.h
--- a/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h Wed May 31 11:30:07 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h Wed May 31 13:05:21 2006 -0600
@@ -13,14 +13,16 @@ void cpu_initialize_context(unsigned int
#define cpu_initialize_context(cpu) ((void)0)
#endif

-int cpu_up_is_allowed(unsigned int cpu);
+int cpu_up_check(unsigned int cpu);
void init_xenbus_allowed_cpumask(void);
int smp_suspend(void);
void smp_resume(void);

+void cpu_bringup(void);
+
#else /* !defined(CONFIG_HOTPLUG_CPU) */

-#define cpu_up_is_allowed(cpu) (1)
+#define cpu_up_check(cpu) (0)
#define init_xenbus_allowed_cpumask() ((void)0)

static inline int smp_suspend(void)
diff -r 3be4c8288737 -r acabf4bdec4f tools/Makefile
--- a/tools/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/Makefile Wed May 31 13:05:21 2006 -0600
@@ -1,39 +1,38 @@ XEN_ROOT = ../
XEN_ROOT = ../
include $(XEN_ROOT)/tools/Rules.mk

-SUBDIRS :=
-SUBDIRS += libxc
-SUBDIRS += xenstore
-SUBDIRS += misc
-SUBDIRS += examples
-SUBDIRS += xentrace
-SUBDIRS += xcutils
-SUBDIRS += firmware
-SUBDIRS += security
-SUBDIRS += console
-SUBDIRS += xenmon
-SUBDIRS += guest-headers
-ifeq ($(VTPM_TOOLS),y)
-SUBDIRS += vtpm_manager
-SUBDIRS += vtpm
-endif
-SUBDIRS += xenstat
+SUBDIRS-y :=
+SUBDIRS-y += libxc
+SUBDIRS-y += xenstore
+SUBDIRS-y += misc
+SUBDIRS-y += examples
+SUBDIRS-y += xentrace
+SUBDIRS-$(CONFIG_X86) += xcutils
+SUBDIRS-y += firmware
+SUBDIRS-y += security
+SUBDIRS-y += console
+SUBDIRS-y += xenmon
+SUBDIRS-y += guest-headers
+SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
+SUBDIRS-$(VTPM_TOOLS) += vtpm
+SUBDIRS-y += xenstat
+
# These don't cross-compile
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
-SUBDIRS += python
-SUBDIRS += pygrub
+SUBDIRS-y += python
+SUBDIRS-y += pygrub
endif

.PHONY: all
all: check
- @set -e; for subdir in $(SUBDIRS); do \
+ @set -e; for subdir in $(SUBDIRS-y); do \
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemu

.PHONY: install
install: check
- @set -e; for subdir in $(SUBDIRS); do \
+ @set -e; for subdir in $(SUBDIRS-y); do \
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemuinstall
@@ -41,7 +40,7 @@ install: check

.PHONY: clean
clean: check_clean
- @set -e; for subdir in $(SUBDIRS); do \
+ @set -e; for subdir in $(SUBDIRS-y); do \
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemuclean
@@ -55,10 +54,10 @@ check_clean:
$(MAKE) -C check clean

.PHONY: ioemu ioemuinstall ioemuclean
-ifndef XEN_NO_IOEMU
+ifdef CONFIG_IOEMU
ioemu ioemuinstall ioemuclean:
[ -f ioemu/config-host.h ] || \
- (cd ioemu; ./configure --prefix=usr)
+ (cd ioemu; sh ./configure --prefix=usr)
$(MAKE) -C ioemu $(patsubst ioemu%,%,$@)
else
ioemu ioemuinstall ioemuclean:
diff -r 3be4c8288737 -r acabf4bdec4f tools/Rules.mk
--- a/tools/Rules.mk Wed May 31 11:30:07 2006 -0600
+++ b/tools/Rules.mk Wed May 31 13:05:21 2006 -0600
@@ -4,6 +4,8 @@ all:
all:

include $(XEN_ROOT)/Config.mk
+
+CONFIG_$(shell uname -s) := y

XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc
XEN_LIBXC = $(XEN_ROOT)/tools/libxc
diff -r 3be4c8288737 -r acabf4bdec4f tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/firmware/hvmloader/Makefile Wed May 31 13:05:21 2006 -0600
@@ -51,12 +51,12 @@ hvmloader: roms.h hvmloader.c acpi_madt.
$(OBJCOPY) hvmloader.tmp hvmloader
rm -f hvmloader.tmp

-roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
- ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
- ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
- ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
- ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
- ./mkhex acpi ../acpi/acpi.bin >> roms.h
+roms.h: ../rombios/BIOS-bochs-8-processors ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
+ sh ./mkhex rombios ../rombios/BIOS-bochs-8-processors > roms.h
+ sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
+ sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
+ sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
+ sh ./mkhex acpi ../acpi/acpi.bin >> roms.h

.PHONY: clean
clean:
diff -r 3be4c8288737 -r acabf4bdec4f tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/firmware/rombios/Makefile Wed May 31 13:05:21 2006 -0600
@@ -1,7 +1,7 @@ BIOS_BUILDS = BIOS-bochs-latest
-BIOS_BUILDS = BIOS-bochs-latest
+#BIOS_BUILDS = BIOS-bochs-latest
#BIOS_BUILDS += BIOS-bochs-2-processors
#BIOS_BUILDS += BIOS-bochs-4-processors
-#BIOS_BUILDS += BIOS-bochs-8-processors
+BIOS_BUILDS += BIOS-bochs-8-processors

.PHONY: all
all: bios
diff -r 3be4c8288737 -r acabf4bdec4f tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/ioemu/hw/ne2000.c Wed May 31 13:05:21 2006 -0600
@@ -147,9 +147,33 @@ static void ne2000_reset(NE2000State *s)
}
}

+static int ne2000_buffer_full(NE2000State *s)
+{
+ int avail, index, boundary;
+
+ index = s->curpag << 8;
+ boundary = s->boundary << 8;
+ if (index <= boundary)
+ /* when index == boundary, we should assume the
+ * buffer is full instead of empty!
+ */
+ avail = boundary - index;
+ else
+ avail = (s->stop - s->start) - (index - boundary);
+
+ return (avail < (MAX_ETH_FRAME_SIZE + 4));
+}
+
static void ne2000_update_irq(NE2000State *s)
{
int isr;
+
+ if (ne2000_buffer_full(s)) {
+ /* The freeing space is not enough, tell the ne2k driver
+ * to fetch these packets!
+ */
+ s->isr |= ENISR_RX;
+ }
isr = s->isr & s->imr;
#if defined(DEBUG_NE2000)
printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
@@ -168,19 +192,11 @@ static int ne2000_can_receive(void *opaq
static int ne2000_can_receive(void *opaque)
{
NE2000State *s = opaque;
- int avail, index, boundary;

if (s->cmd & E8390_STOP)
return 0;
- index = s->curpag << 8;
- boundary = s->boundary << 8;
- if (index < boundary)
- avail = boundary - index;
- else
- avail = (s->stop - s->start) - (index - boundary);
- if (avail < (MAX_ETH_FRAME_SIZE + 4))
- return 0;
- return MAX_ETH_FRAME_SIZE;
+
+ return (ne2000_buffer_full(s) ? 0 : MAX_ETH_FRAME_SIZE);
}

#define MIN_BUF_SIZE 60
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/Makefile
--- a/tools/libxc/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/Makefile Wed May 31 13:05:21 2006 -0600
@@ -10,43 +10,30 @@ XEN_ROOT = ../..
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk

-SRCS :=
-SRCS += xc_bvtsched.c
-SRCS += xc_core.c
-SRCS += xc_domain.c
-SRCS += xc_evtchn.c
-SRCS += xc_misc.c
-SRCS += xc_acm.c
-SRCS += xc_physdev.c
-SRCS += xc_private.c
-SRCS += xc_sedf.c
-SRCS += xc_csched.c
-SRCS += xc_tbuf.c
+CTRL_SRCS-y :=
+CTRL_SRCS-y += xc_bvtsched.c
+CTRL_SRCS-y += xc_core.c
+CTRL_SRCS-y += xc_domain.c
+CTRL_SRCS-y += xc_evtchn.c
+CTRL_SRCS-y += xc_misc.c
+CTRL_SRCS-y += xc_acm.c
+CTRL_SRCS-y += xc_physdev.c
+CTRL_SRCS-y += xc_private.c
+CTRL_SRCS-y += xc_sedf.c
+CTRL_SRCS-y += xc_csched.c
+CTRL_SRCS-y += xc_tbuf.c
+CTRL_SRCS-$(CONFIG_X86) += xc_ptrace.c xc_ptrace_core.c xc_pagetab.c
+CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c

-ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
-SRCS += xc_ptrace.c
-SRCS += xc_ptrace_core.c
-SRCS += xc_pagetab.c
-endif
-
-SRCS_Linux += xc_linux.c
-
-SRCS += $(SRCS_Linux)
-
-BUILD_SRCS :=
-BUILD_SRCS += xc_linux_build.c
-BUILD_SRCS += xc_load_bin.c
-BUILD_SRCS += xc_load_elf.c
-BUILD_SRCS += xg_private.c
-
-ifeq ($(XEN_TARGET_ARCH),ia64)
-BUILD_SRCS += xc_ia64_stubs.c
-else
-BUILD_SRCS += xc_load_aout9.c
-BUILD_SRCS += xc_linux_restore.c
-BUILD_SRCS += xc_linux_save.c
-BUILD_SRCS += xc_hvm_build.c
-endif
+GUEST_SRCS-y :=
+GUEST_SRCS-y += xc_linux_build.c
+GUEST_SRCS-y += xc_load_bin.c
+GUEST_SRCS-y += xc_load_elf.c
+GUEST_SRCS-y += xg_private.c
+GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
+GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
+GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
+GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c

CFLAGS += -Werror
CFLAGS += -fno-strict-aliasing
@@ -61,11 +48,11 @@ LDFLAGS += -L.
LDFLAGS += -L.
DEPS = .*.d

-LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
-PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
+CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
+CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))

-LIB_BUILD_OBJS := $(patsubst %.c,%.o,$(BUILD_SRCS))
-PIC_BUILD_OBJS := $(patsubst %.c,%.opic,$(BUILD_SRCS))
+GUEST_LIB_OBJS := $(patsubst %.c,%.o,$(GUEST_SRCS-y))
+GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y))

LIB := libxenctrl.a
LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR)
@@ -125,7 +112,7 @@ rpm: build

# libxenctrl

-libxenctrl.a: $(LIB_OBJS)
+libxenctrl.a: $(CTRL_LIB_OBJS)
$(AR) rc $@ $^

libxenctrl.so: libxenctrl.so.$(MAJOR)
@@ -133,12 +120,12 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(
libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
ln -sf $< $@

-libxenctrl.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
+libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenctrl.so.$(MAJOR) -shared -o $@ $^

# libxenguest

-libxenguest.a: $(LIB_BUILD_OBJS)
+libxenguest.a: $(GUEST_LIB_OBJS)
$(AR) rc $@ $^

libxenguest.so: libxenguest.so.$(MAJOR)
@@ -146,7 +133,7 @@ libxenguest.so.$(MAJOR): libxenguest.so.
libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR)
ln -sf $< $@

-libxenguest.so.$(MAJOR).$(MINOR): $(PIC_BUILD_OBJS) libxenctrl.so
+libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) -shared -o $@ $^ -lz -lxenctrl

-include $(DEPS)
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xc_core.c Wed May 31 13:05:21 2006 -0600
@@ -1,6 +1,4 @@
#include "xg_private.h"
-#define ELFSIZE 32
-#include "xc_elf.h"
#include <stdlib.h>
#include <unistd.h>

diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xc_csched.c
--- a/tools/libxc/xc_csched.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xc_csched.c Wed May 31 13:05:21 2006 -0600
@@ -12,10 +12,10 @@


int
-xc_csched_domain_set(
+xc_sched_credit_domain_set(
int xc_handle,
uint32_t domid,
- struct csched_domain *sdom)
+ struct sched_credit_adjdom *sdom)
{
DECLARE_DOM0_OP;

@@ -29,10 +29,10 @@ xc_csched_domain_set(
}

int
-xc_csched_domain_get(
+xc_sched_credit_domain_get(
int xc_handle,
uint32_t domid,
- struct csched_domain *sdom)
+ struct sched_credit_adjdom *sdom)
{
DECLARE_DOM0_OP;
int err;
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xc_hvm_build.c Wed May 31 13:05:21 2006 -0600
@@ -2,9 +2,9 @@
* xc_hvm_build.c
*/

+#define ELFSIZE 32
#include <stddef.h>
#include "xg_private.h"
-#define ELFSIZE 32
#include "xc_elf.h"
#include <stdlib.h>
#include <unistd.h>
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xc_linux_build.c Wed May 31 13:05:21 2006 -0600
@@ -5,14 +5,6 @@
#include "xg_private.h"
#include "xc_private.h"
#include <xenctrl.h>
-
-#if defined(__i386__)
-#define ELFSIZE 32
-#endif
-
-#if defined(__x86_64__) || defined(__ia64__)
-#define ELFSIZE 64
-#endif

#include "xc_elf.h"
#include "xc_aout9.h"
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xc_load_elf.c Wed May 31 13:05:21 2006 -0600
@@ -3,14 +3,6 @@
*/

#include "xg_private.h"
-
-#if defined(__i386__)
-#define ELFSIZE 32
-#endif
-#if defined(__x86_64__) || defined(__ia64__)
-#define ELFSIZE 64
-#endif
-
#include "xc_elf.h"
#include <stdlib.h>

diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xenctrl.h Wed May 31 13:05:21 2006 -0600
@@ -354,13 +354,13 @@ int xc_sedf_domain_get(int xc_handle,
uint64_t *latency, uint16_t *extratime,
uint16_t *weight);

-int xc_csched_domain_set(int xc_handle,
- uint32_t domid,
- struct csched_domain *sdom);
-
-int xc_csched_domain_get(int xc_handle,
- uint32_t domid,
- struct csched_domain *sdom);
+int xc_sched_credit_domain_set(int xc_handle,
+ uint32_t domid,
+ struct sched_credit_adjdom *sdom);
+
+int xc_sched_credit_domain_get(int xc_handle,
+ uint32_t domid,
+ struct sched_credit_adjdom *sdom);

typedef evtchn_status_t xc_evtchn_status_t;

diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xg_private.c Wed May 31 13:05:21 2006 -0600
@@ -145,3 +145,18 @@ unsigned long csum_page(void *page)

return sum ^ (sum>>32);
}
+
+__attribute__((weak)) int xc_hvm_build(
+ int xc_handle,
+ uint32_t domid,
+ int memsize,
+ const char *image_name,
+ unsigned int vcpus,
+ unsigned int pae,
+ unsigned int acpi,
+ unsigned int apic,
+ unsigned int store_evtchn,
+ unsigned long *store_mfn)
+{
+ return -ENOSYS;
+}
diff -r 3be4c8288737 -r acabf4bdec4f tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Wed May 31 11:30:07 2006 -0600
+++ b/tools/libxc/xg_private.h Wed May 31 13:05:21 2006 -0600
@@ -25,6 +25,14 @@
#define DECLARE_DOM0_OP dom0_op_t op
#endif

+#ifndef ELFSIZE
+#include <limits.h>
+#if UINT_MAX == ULONG_MAX
+#define ELFSIZE 32
+#else
+#define ELFSIZE 64
+#endif
+#endif

char *xc_read_image(const char *filename, unsigned long *size);
char *xc_inflate_buffer(const char *in_buf,
diff -r 3be4c8288737 -r acabf4bdec4f tools/misc/Makefile
--- a/tools/misc/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/misc/Makefile Wed May 31 13:05:21 2006 -0600
@@ -25,7 +25,7 @@ build: $(TARGETS)
build: $(TARGETS)
$(MAKE) -C miniterm
$(MAKE) -C cpuperf
-ifneq ($(XEN_TARGET_ARCH),ia64)
+ifeq ($(CONFIG_MBOOTPACK),y)
$(MAKE) -C mbootpack
endif
$(MAKE) -C lomount
diff -r 3be4c8288737 -r acabf4bdec4f tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed May 31 11:30:07 2006 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed May 31 13:05:21 2006 -0600
@@ -716,16 +716,16 @@ static PyObject *pyxc_sedf_domain_get(Xc
"weight", weight);
}

-static PyObject *pyxc_csched_domain_set(XcObject *self,
- PyObject *args,
- PyObject *kwds)
+static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
{
uint32_t domid;
uint16_t weight;
uint16_t cap;
static char *kwd_list[] = { "dom", "weight", "cap", NULL };
static char kwd_type[] = "I|HH";
- struct csched_domain sdom;
+ struct sched_credit_adjdom sdom;

weight = 0;
cap = (uint16_t)~0U;
@@ -736,22 +736,22 @@ static PyObject *pyxc_csched_domain_set(
sdom.weight = weight;
sdom.cap = cap;

- if ( xc_csched_domain_set(self->xc_handle, domid, &sdom) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
- Py_INCREF(zero);
- return zero;
-}
-
-static PyObject *pyxc_csched_domain_get(XcObject *self, PyObject *args)
+ if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
+static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
{
uint32_t domid;
- struct csched_domain sdom;
+ struct sched_credit_adjdom sdom;

if( !PyArg_ParseTuple(args, "I", &domid) )
return NULL;

- if ( xc_csched_domain_get(self->xc_handle, domid, &sdom) != 0 )
+ if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
return PyErr_SetFromErrno(xc_error);

return Py_BuildValue("{s:H,s:H}",
@@ -1084,8 +1084,8 @@ static PyMethodDef pyxc_methods[] = {
" latency [long]: domain's wakeup latency hint\n"
" extratime [int]: domain aware of extratime?\n"},

- { "csched_domain_set",
- (PyCFunction)pyxc_csched_domain_set,
+ { "sched_credit_domain_set",
+ (PyCFunction)pyxc_sched_credit_domain_set,
METH_KEYWORDS, "\n"
"Set the scheduling parameters for a domain when running with the\n"
"SMP credit scheduler.\n"
@@ -1093,8 +1093,8 @@ static PyMethodDef pyxc_methods[] = {
" weight [short]: domain's scheduling weight\n"
"Returns: [int] 0 on success; -1 on error.\n" },

- { "csched_domain_get",
- (PyCFunction)pyxc_csched_domain_get,
+ { "sched_credit_domain_get",
+ (PyCFunction)pyxc_sched_credit_domain_get,
METH_VARARGS, "\n"
"Get the scheduling parameters for a domain when running with the\n"
"SMP credit scheduler.\n"
diff -r 3be4c8288737 -r acabf4bdec4f tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Wed May 31 11:30:07 2006 -0600
+++ b/tools/python/xen/xend/XendDomain.py Wed May 31 13:05:21 2006 -0600
@@ -522,25 +522,25 @@ class XendDomain:
except Exception, ex:
raise XendError(str(ex))

- def domain_csched_get(self, domid):
+ def domain_sched_credit_get(self, domid):
"""Get credit scheduler parameters for a domain.
"""
dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
- return xc.csched_domain_get(dominfo.getDomid())
+ return xc.sched_credit_domain_get(dominfo.getDomid())
except Exception, ex:
raise XendError(str(ex))

- def domain_csched_set(self, domid, weight, cap):
+ def domain_sched_credit_set(self, domid, weight, cap):
"""Set credit scheduler parameters for a domain.
"""
dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
try:
- return xc.csched_domain_set(dominfo.getDomid(), weight, cap)
+ return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
except Exception, ex:
raise XendError(str(ex))

diff -r 3be4c8288737 -r acabf4bdec4f tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Wed May 31 11:30:07 2006 -0600
+++ b/tools/python/xen/xend/server/SrvDomain.py Wed May 31 13:05:21 2006 -0600
@@ -132,15 +132,15 @@ class SrvDomain(SrvDir):
val = fn(req.args, {'dom': self.dom.domid})
return val

- def op_domain_csched_get(self, _, req):
- fn = FormFn(self.xd.domain_csched_get,
+ def op_domain_sched_credit_get(self, _, req):
+ fn = FormFn(self.xd.domain_sched_credit_get,
[['dom', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val


- def op_domain_csched_set(self, _, req):
- fn = FormFn(self.xd.domain_csched_set,
+ def op_domain_sched_credit_set(self, _, req):
+ fn = FormFn(self.xd.domain_sched_credit_set,
[['dom', 'int'],
['weight', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
diff -r 3be4c8288737 -r acabf4bdec4f tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Wed May 31 11:30:07 2006 -0600
+++ b/tools/python/xen/xm/main.py Wed May 31 13:05:21 2006 -0600
@@ -99,7 +99,7 @@ sched_sedf_help = "sched-sedf [DOM] [.OPT
specifies another way of setting a domain's\n\
cpu period/slice."

-csched_help = "csched Set or get credit scheduler parameters"
+sched_credit_help = "sched-credit Set or get credit scheduler parameters"
block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
[BackDomId] Create a new virtual block device"""
block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device,
@@ -175,7 +175,7 @@ host_commands = [
]

scheduler_commands = [.
- "csched",
+ "sched-credit",
"sched-bvt",
"sched-bvt-ctxallow",
"sched-sedf",
@@ -737,11 +737,11 @@ def xm_sched_sedf(args):
else:
print_sedf(sedf_info)

-def xm_csched(args):
- usage_msg = """Csched: Set or get credit scheduler parameters
+def xm_sched_credit(args):
+ usage_msg = """sched-credit: Set or get credit scheduler parameters
Usage:

- csched -d domain [-w weight] [-c cap]
+ sched-credit -d domain [-w weight] [-c cap]
"""
try:
opts, args = getopt.getopt(args[0:], "d:w:c:",
@@ -769,14 +769,14 @@ def xm_csched(args):
sys.exit(1)

if weight is None and cap is None:
- print server.xend.domain.csched_get(domain)
+ print server.xend.domain.sched_credit_get(domain)
else:
if weight is None:
weight = int(0)
if cap is None:
cap = int(~0)

- err = server.xend.domain.csched_set(domain, weight, cap)
+ err = server.xend.domain.sched_credit_set(domain, weight, cap)
if err != 0:
print err

@@ -806,7 +806,7 @@ def xm_top(args):
os.execvp('xentop', ['xentop'])

def xm_dmesg(args):
- arg_check(args, "dmesg", 0)
+ arg_check(args, "dmesg", 0, 1)

gopts = Opts(use="""[-c|--clear]

@@ -1076,7 +1076,7 @@ commands = {
"sched-bvt": xm_sched_bvt,
"sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
"sched-sedf": xm_sched_sedf,
- "csched": xm_csched,
+ "sched-credit": xm_sched_credit,
# block
"block-attach": xm_block_attach,
"block-detach": xm_block_detach,
diff -r 3be4c8288737 -r acabf4bdec4f tools/vtpm/Makefile
--- a/tools/vtpm/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/tools/vtpm/Makefile Wed May 31 13:05:21 2006 -0600
@@ -9,7 +9,7 @@ VTPM_DIR = vtpm
VTPM_DIR = vtpm

# Emulator tarball name
-TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
+TPM_EMULATOR_TARFILE = tpm_emulator-0.3.tar.gz

GMP_HEADER = /usr/include/gmp.h

@@ -47,23 +47,23 @@ mrproper:

# Create vtpm and TPM emulator dirs
# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
-$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch tpm_emulator-0.2b-x86_64.patch
+$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch tpm_emulator-0.3-x86_64.patch
if [ "$(BUILD_EMULATOR)" = "y" ]; then \
tar -xzf $(TPM_EMULATOR_TARFILE); \
rm -rf $(TPM_EMULATOR_DIR); \
- mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); \
+ mv tpm_emulator-0.3 $(TPM_EMULATOR_DIR); \
cd $(TPM_EMULATOR_DIR); \
- patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
+ patch -p1 < ../tpm_emulator-0.3-x86_64.patch; \
patch -p1 <../tpm_emulator.patch; \
fi

-$(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.2b-x86_64.patch vtpm.patch
+$(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.3-x86_64.patch vtpm.patch
tar -xzf $(TPM_EMULATOR_TARFILE);
rm -rf $(VTPM_DIR)
- mv tpm_emulator-0.2 $(VTPM_DIR);
+ mv tpm_emulator-0.3 $(VTPM_DIR);

cd $(VTPM_DIR); \
- patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
+ patch -p1 < ../tpm_emulator-0.3-x86_64.patch; \
patch -p1 <../vtpm.patch

.PHONY: build_sub
diff -r 3be4c8288737 -r acabf4bdec4f tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk Wed May 31 11:30:07 2006 -0600
+++ b/tools/vtpm/Rules.mk Wed May 31 13:05:21 2006 -0600
@@ -33,6 +33,7 @@ OBJS = $(patsubst %.c,%.o,$(SRCS))

-include $(DEP_FILES)

+# Emulator does not work on 64-bit systems, and may be broken on 32 right now
BUILD_EMULATOR = n

# Make sure these are just rules
diff -r 3be4c8288737 -r acabf4bdec4f tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch Wed May 31 11:30:07 2006 -0600
+++ b/tools/vtpm/vtpm.patch Wed May 31 13:05:21 2006 -0600
@@ -1,23 +1,24 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS vtpm/AUTHORS
---- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/AUTHORS 2006-05-17 09:31:11.000000000 -0700
-@@ -1 +1,2 @@
+diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
+--- orig/tpm_emulator-0.3-x86_64/AUTHORS 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/AUTHORS 2006-05-30 12:23:26.000000000 -0700
+@@ -1,2 +1,3 @@
Mario Strasser <mast@gmx.net>
-+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog vtpm/ChangeLog
---- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/ChangeLog 2006-05-17 09:31:11.000000000 -0700
+ Heiko Stamer <stamer@gaos.org> [DAA]
++INTEL Corp <> [VTPM Extensions]
+diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
+--- orig/tpm_emulator-0.3-x86_64/ChangeLog 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/ChangeLog 2006-05-30 12:23:26.000000000 -0700
@@ -1,3 +1,7 @@
+2005-08-16 Intel Corp
-+ Moved module out of kernel to run as a ring 3 app
-+ Modified save_to_file and load_from_file to call a xen backend driver to call a VTPM manager
-+
- 2005-08-15 Mario Strasser <mast@gmx.net>
- * all: some typos corrected
- * tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-17 09:31:11.000000000 -0700
++ * Moved module out of kernel to run as a ring 3 app
++ * Modified save_to_file and load_from_file to call a xen backend driver to call a VTPM manager
++
+ 2005-12-24 Mario Strasser <mast@gmx.net>
+ * tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
+ Transport session functionality added
+diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
+--- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -77,9 +78,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}
}

-diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
---- orig/tpm_emulator-0.2-x86_64/crypto/rsa.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/crypto/rsa.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
+--- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/crypto/rsa.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -87,7 +88,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -363,7 +364,7 @@ static int encode_message(int type, uint
+@@ -381,7 +382,7 @@ static int encode_message(int type, uint
msg[0] = 0x00;
get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
sha1_init(&ctx);
@@ -96,7 +97,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00,
msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
-@@ -411,7 +412,7 @@ static int decode_message(int type, uint
+@@ -429,7 +430,7 @@ static int decode_message(int type, uint
mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
&msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
sha1_init(&ctx);
@@ -105,10 +106,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
sha1_final(&ctx, &msg[1]);
if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
SHA1_DIGEST_LENGTH) != 0) return -1;
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.2-x86_64/linux_module.c 2006-05-17 09:34:13.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
+--- orig/tpm_emulator-0.3-x86_64/linux_module.c 2006-05-30 12:28:02.000000000 -0700
+++ vtpm/linux_module.c 1969-12-31 16:00:00.000000000 -0800
-@@ -1,163 +0,0 @@
+@@ -1,194 +0,0 @@
-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
- * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
- *
@@ -122,7 +123,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
-- * $Id: linux_module.c 19 2005-05-18 08:29:37Z mast $
+- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $
- */
-
-#include <linux/module.h>
@@ -140,11 +141,11 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
-/* module startup parameters */
-char *startup = "save";
--MODULE_PARM(startup, "s");
+-module_param(startup, charp, 0444);
-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
- "Possible values are 'clear', 'save' (default) and 'deactivated.");
--char *storage_file = "/var/tpm/tpm_emulator-1.2.0.1";
--MODULE_PARM(storage_file, "s");
+-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2";
+-module_param(storage_file, charp, 0644);
-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage "
- "file of the TPM.");
-
@@ -172,6 +173,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-{
- debug("%s()", __FUNCTION__);
- clear_bit(STATE_IS_OPEN, (void*)&module_state);
+- down(&tpm_mutex);
+- if (tpm_response.data != NULL) {
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- }
+- up(&tpm_mutex);
- return 0;
-}
-
@@ -183,6 +190,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
- count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
- *ppos += count;
+- if ((size_t)tpm_response.size == (size_t)*ppos) {
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- }
- } else {
- count = 0;
- }
@@ -205,9 +216,29 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- return count;
-}
-
+-#define TPMIOC_CANCEL _IO('T', 0x00)
+-#define TPMIOC_TRANSMIT _IO('T', 0x01)
+-
-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-- debug("%s(%d, %ld)", __FUNCTION__, cmd, arg);
+- debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg);
+- if (cmd == TPMIOC_TRANSMIT) {
+- uint32_t count = ntohl(*(uint32_t*)(arg + 2));
+- down(&tpm_mutex);
+- if (tpm_response.data != NULL) kfree(tpm_response.data);
+- if (tpm_handle_command((char*)arg, count, &tpm_response.data,
+- &tpm_response.size) == 0) {
+- tpm_response.size -= copy_to_user((char*)arg, tpm_response.data,
+- tpm_response.size);
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- } else {
+- tpm_response.size = 0;
+- tpm_response.data = NULL;
+- }
+- up(&tpm_mutex);
+- return tpm_response.size;
+- }
- return -1;
-}
-
@@ -240,7 +271,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- /* initialize TPM emulator */
- if (!strcmp(startup, "clear")) {
- tpm_emulator_init(1);
-- } else if (!strcmp(startup, "save")) {
+- } else if (!strcmp(startup, "save")) {
- tpm_emulator_init(2);
- } else if (!strcmp(startup, "deactivated")) {
- tpm_emulator_init(3);
@@ -257,6 +288,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-{
- tpm_emulator_shutdown();
- misc_deregister(&tpm_dev);
+- if (tpm_response.data != NULL) kfree(tpm_response.data);
-}
-
-module_init(init_tpm_module);
@@ -264,7 +296,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-
-uint64_t tpm_get_ticks(void)
-{
-- static struct timespec old_time = {0, 0};
+- static struct timespec old_time = {0, 0};
- struct timespec new_time = current_kernel_time();
- uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
- + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
@@ -272,9 +304,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- return (ticks > 0) ? ticks : 1;
-}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.2-x86_64/linux_module.h 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/linux_module.h 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
+--- orig/tpm_emulator-0.3-x86_64/linux_module.h 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/linux_module.h 2006-05-30 12:23:26.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -374,15 +406,15 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
#define BE16_TO_CPU(x) __be16_to_cpu(x)
#define LE16_TO_CPU(x) __le16_to_cpu(x)

-diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.2-x86_64/Makefile 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/Makefile 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
+--- orig/tpm_emulator-0.3-x86_64/Makefile 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/Makefile 2006-05-30 12:23:26.000000000 -0700
@@ -1,22 +1,31 @@
# Software-Based Trusted Platform Module (TPM) Emulator for Linux
# Copyright (C) 2004 Mario Strasser <mast@gmx.net>
-+# Copyright (C) 2005 INTEL Corp.
++# Copyright (C) 2006 INTEL Corp.
#
- # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $

-# kernel settings
-KERNEL_RELEASE := $(shell uname -r)
@@ -394,11 +426,11 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-MODULE_NAME := tpm_emulator
+BIN := vtpmd
VERSION_MAJOR := 0
- VERSION_MINOR := 2
+ VERSION_MINOR := 3
VERSION_BUILD := $(shell date +"%s")

-# enable/disable DEBUG messages
--EXTRA_CFLAGS += -DDEBUG -g
+-EXTRA_CFLAGS += -Wall -DDEBUG -g
+# Installation program and options
+INSTALL = install
+INSTALL_PROG = $(INSTALL) -m0755
@@ -468,10 +500,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/

$(src)/crypto/libgmp.a:
test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.2-x86_64/README vtpm/README
---- orig/tpm_emulator-0.2-x86_64/README 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/README 2006-05-17 09:31:11.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README
+--- orig/tpm_emulator-0.3-x86_64/README 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/README 2006-05-30 12:23:26.000000000 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
Copyright
--------------------------------------------------------------------------
Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal
@@ -481,9 +513,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_audit.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_audit.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -546,9 +578,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_authorization.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_authorization.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -557,7 +589,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -268,7 +269,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
+@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
{
hmac_ctx_t ctx;
TPM_SESSION_DATA *session;
@@ -565,16 +597,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
+ UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);

info("tpm_verify_auth(%08x)", auth->authHandle);
- /* get dedicated authorization session */
-@@ -316,5 +317,3 @@ void tpm_decrypt_auth_secret(TPM_ENCAUTH
- for (i = 0; i < sizeof(TPM_SECRET); i++)
- plainAuth[i] ^= encAuth[i];
- }
--
--
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_capability.c 2006-05-17 09:31:11.000000000 -0700
+ /* get dedicated authorization or transport session */
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_capability.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -583,7 +609,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -398,7 +399,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL

case TPM_CAP_KEY_HANDLE:
debug("[TPM_CAP_KEY_HANDLE]");
@@ -592,14 +618,14 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);

case TPM_CAP_CHECK_LOADED:
-@@ -472,4 +473,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
return TPM_BAD_MODE;
}
}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_cmd_handler.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_cmd_handler.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -608,17 +634,17 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -26,7 +27,7 @@ static void tpm_compute_in_param_digest(
+@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ
{
sha1_ctx_t sha1;
- UINT32 offset;
+ UINT32 offset = tpm_get_param_offset(req->ordinal);
- UINT32 ord = cpu_to_be32(req->ordinal);
+ UINT32 ord = CPU_TO_BE32(req->ordinal);

- /* skip all key-handles at the beginning */
- switch (req->ordinal) {
-@@ -82,8 +83,8 @@ static void tpm_compute_in_param_digest(
- static void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
+ /* compute SHA1 hash */
+ if (offset <= req->paramSize) {
+@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ
+ void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
{
sha1_ctx_t sha1;
- UINT32 res = cpu_to_be32(rsp->result);
@@ -628,7 +654,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/

/* compute SHA1 hash */
sha1_init(&sha1);
-@@ -3081,7 +3082,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
#if 0
if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
@@ -637,7 +663,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
hmac_update(&hmac, (BYTE*)&handle, 4);
}
#endif
-@@ -3096,7 +3097,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
#if 0
if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
@@ -646,25 +672,20 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
hmac_update(&hmac, (BYTE*)&handle, 4);
}
#endif
-@@ -3179,7 +3180,9 @@ extern const char *tpm_error_to_string(T
- static void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T
+ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
TPM_RESULT res;
-
+
-+ req->tag = (BYTE) req->tag; // VIN HACK!!!
++ req->tag = (BYTE) req->tag; // FIXME: Why is this here
+
/* setup authorisation as well as response tag and size */
memset(rsp, 0, sizeof(*rsp));
switch (req->tag) {
-@@ -3878,4 +3881,3 @@ int tpm_handle_command(const uint8_t *in
- tpm_free(rsp.param);
- return 0;
- }
--
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/tpm/tpm_crypto.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/tpm/tpm_crypto.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -683,13 +704,170 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1,
buf, areaToSignSize + 30, *sig)) {
@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
- }
+ }
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2006-05-17 09:34:13.000000000 -0700
-+++ vtpm/tpm/tpm_data.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_daa.c 2006-05-30 12:23:26.000000000 -0700
+@@ -700,14 +700,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -787,14 +787,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1440,14 +1440,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1660,14 +1660,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1740,14 +1740,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
+ sizeof(session->DAA_session.DAA_digest));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_update(&sha1, inputData1, inputSize1);
+ sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+ }
+@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
+ sizeof(session->DAA_session.DAA_digest));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ rsa_export_modulus(&aikData->key, scratch, &size);
+ sha1_update(&sha1, scratch, size);
+ sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-30 12:28:02.000000000 -0700
++++ vtpm/tpm/tpm_data.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -698,8 +876,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -15,9 +16,15 @@
- * $Id: tpm_data.c 9 2005-04-26 18:15:31Z mast $
+@@ -15,10 +16,15 @@
+ * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $
*/

+#include <sys/types.h>
@@ -710,11 +888,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
#include "tpm_emulator.h"
#include "tpm_structures.h"
#include "tpm_marshalling.h"
+-#include "linux_module.h"
+#include "vtpm_manager.h"

TPM_DATA tpmData;

-@@ -28,6 +35,7 @@ BOOL tpm_get_physical_presence(void)
+@@ -39,6 +45,7 @@ static inline void init_pcr_attr(int pcr

void tpm_init_data(void)
{
@@ -722,7 +901,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
/* endorsement key */
uint8_t ek_n[] = "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
"\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
-@@ -66,6 +74,8 @@ void tpm_init_data(void)
+@@ -77,6 +84,8 @@ void tpm_init_data(void)
"\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
"\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
"\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
@@ -731,18 +910,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
int i;
/* reset all data to NULL, FALSE or 0 */
memset(&tpmData, 0, sizeof(tpmData));
-@@ -85,6 +95,10 @@ void tpm_init_data(void)
- tpmData.permanent.data.version.revMinor = VERSION_MINOR;
- /* setup PCR attributes */
- for (i = 0; i < TPM_NUM_PCR; i++) {
-+ int j;
-+ for (j=0; j < TPM_NUM_LOCALITY; j++) {
-+ tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
-+ }
- tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
- }
- /* set tick type */
-@@ -115,49 +129,235 @@ void tpm_release_data(void)
+@@ -150,49 +159,235 @@ void tpm_release_data(void)

#ifdef TPM_STORE_TO_FILE

@@ -1009,7 +1177,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}

#else
-@@ -232,7 +432,6 @@ int tpm_restore_permanent_data(void)
+@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void)

int tpm_erase_permanent_data(void)
{
@@ -1018,9 +1186,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
return res;
}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_deprecated.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_deprecated.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1047,9 +1215,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
authContextSize, &contextBlob);
if (res != TPM_SUCCESS) return res;
len = *authContextSize;
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_emulator.h 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_emulator.h 2006-05-30 12:23:26.000000000 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1064,12 +1232,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-#undef TPM_GENERATE_EK
+//#undef TPM_GENERATE_EK
+#define TPM_GENERATE_EK
-
- /**
- * tpm_emulator_init - initialises and starts the TPM emulator
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_integrity.c 2006-05-17 09:31:11.000000000 -0700
+ #undef TPM_GENERATE_SEED_DAA
+
+ #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_integrity.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1083,9 +1251,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_structures.h 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_structures.h 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1103,9 +1271,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
#include "crypto/rsa.h"

/*
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_testing.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_testing.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1221,9 +1389,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
rsa_private_key_t priv_key;
rsa_public_key_t pub_key;

-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c 2005-08-15 00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_ticks.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_ticks.c 2006-05-30 12:23:26.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
@@ -1306,9 +1474,69 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
}


-diff -uprN orig/tpm_emulator-0.2-x86_64/tpmd.c vtpm/tpmd.c
---- orig/tpm_emulator-0.2-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800
-+++ vtpm/tpmd.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-01-10 04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_transport.c 2006-05-30 12:23:26.000000000 -0700
+@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
+ static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
+ BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
+ {
+- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN);
++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN);
+ BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
+ UINT32 len = sizeof(buf);
+ sha1_ctx_t sha1;
+@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND
+ static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE parameters[20],
+ TPM_MODIFIER_INDICATOR locality, TPM_DIGEST *transDigest)
+ {
+- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT);
++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT);
+ BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
+ UINT32 len = sizeof(buf);
+ sha1_ctx_t sha1;
+@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE
+ sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+ sha1_update(&sha1, "in", 2);
+ sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+- j = cpu_to_be32(i);
++ j = CPU_TO_BE32(i);
+ sha1_update(&sha1, (BYTE*)&j, 4);
+ sha1_final(&sha1, mask);
+ for (j = 0; j < sizeof(mask) && buf_len > 0; j++) {
+@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE
+ sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+ sha1_update(&sha1, "out", 3);
+ sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+- j = cpu_to_be32(i);
++ j = CPU_TO_BE32(i);
+ sha1_update(&sha1, (BYTE*)&j, 4);
+ sha1_final(&sha1, mask);
+ for (j = 0; j < sizeof(mask) && buf_len > 0; j++) {
+@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i
+ /* verify authorization */
+ tpm_compute_in_param_digest(&req);
+ sha1_init(&sha1);
+- res = cpu_to_be32(TPM_ORD_ExecuteTransport);
++ res = CPU_TO_BE32(TPM_ORD_ExecuteTransport);
+ sha1_update(&sha1, (BYTE*)&res, 4);
+- res = cpu_to_be32(inWrappedCmdSize);
++ res = CPU_TO_BE32(inWrappedCmdSize);
+ sha1_update(&sha1, (BYTE*)&res, 4);
+ sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
+ sha1_final(&sha1, auth1->digest);
+@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP
+ /* setup a TPM_SIGN_INFO structure */
+ memcpy(&buf[0], "\x05\x00TRAN", 6);
+ memcpy(&buf[6], antiReplay->nonce, 20);
+- *(UINT32*)&buf[26] = cpu_to_be32(20);
++ *(UINT32*)&buf[26] = CPU_TO_BE32(20);
+ memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
+ /* sign info structure */
+ res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
+--- orig/tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800
++++ vtpm/tpmd.c 2006-05-30 12:23:26.000000000 -0700
@@ -0,0 +1,207 @@
+/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2005 INTEL Corp
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/domain.c Wed May 31 13:05:21 2006 -0600
@@ -146,6 +146,8 @@ struct vcpu *alloc_vcpu_struct(struct do
v->arch.guest_vl4table = __linear_l4_table;
#endif

+ pae_l3_cache_init(&v->arch.pae_l3_cache);
+
return v;
}

diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/hvm/io.c Wed May 31 13:05:21 2006 -0600
@@ -648,6 +648,16 @@ static void hvm_mmio_assist(struct vcpu
regs->eflags &= ~X86_EFLAGS_CF;

break;
+
+ case INSTR_XCHG:
+ if (src & REGISTER) {
+ index = operand_index(src);
+ set_reg_value(size, index, 0, regs, p->u.data);
+ } else {
+ index = operand_index(dst);
+ set_reg_value(size, index, 0, regs, p->u.data);
+ }
+ break;
}

hvm_load_cpu_guest_regs(v, regs);
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/hvm/platform.c Wed May 31 13:05:21 2006 -0600
@@ -954,10 +954,26 @@ void handle_mmio(unsigned long va, unsig
mmio_opp->instr = mmio_inst.instr;
mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
-
- /* send the request and wait for the value */
- send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
- mmio_inst.op_size, 0, IOREQ_WRITE, 0);
+ if (mmio_inst.operand[0] & REGISTER) {
+ long value;
+ unsigned long operand = mmio_inst.operand[0];
+ value = get_reg_value(operand_size(operand),
+ operand_index(operand), 0,
+ mmio_opp->inst_decoder_regs);
+ /* send the request and wait for the value */
+ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+ mmio_inst.op_size, value, IOREQ_WRITE, 0);
+ } else {
+ /* the destination is a register */
+ long value;
+ unsigned long operand = mmio_inst.operand[1];
+ value = get_reg_value(operand_size(operand),
+ operand_index(operand), 0,
+ mmio_opp->inst_decoder_regs);
+ /* send the request and wait for the value */
+ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+ mmio_inst.op_size, value, IOREQ_WRITE, 0);
+ }
break;

default:
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Wed May 31 13:05:21 2006 -0600
@@ -51,9 +51,6 @@

#define SVM_EXTRA_DEBUG

-/* Useful define */
-#define MAX_INST_SIZE 15
-
#define set_segment_register(name, value) \
__asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )

@@ -74,6 +71,9 @@ void svm_dump_regs(const char *from, str
void svm_dump_regs(const char *from, struct cpu_user_regs *regs);

static void svm_relinquish_guest_resources(struct domain *d);
+static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
+ struct cpu_user_regs *regs);
+


extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm );
@@ -438,6 +438,42 @@ unsigned long svm_get_ctrl_reg(struct vc
return 0; /* dummy */
}

+
+/* SVM-specific intitialization code for VCPU application processors */
+void svm_init_ap_context(struct vcpu_guest_context *ctxt,
+ int vcpuid, int trampoline_vector)
+{
+ int i;
+ struct vcpu *v, *bsp = current;
+ struct domain *d = bsp->domain;
+ cpu_user_regs_t *regs;;
+
+
+ if ((v = d->vcpu[vcpuid]) == NULL)
+ {
+ printk("vcpuid %d is invalid! good-bye.\n", vcpuid);
+ domain_crash_synchronous();
+ }
+ regs = &v->arch.guest_context.user_regs;
+
+ memset(ctxt, 0, sizeof(*ctxt));
+ for (i = 0; i < 256; ++i)
+ {
+ ctxt->trap_ctxt[i].vector = i;
+ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS;
+ }
+
+
+ /*
+ * We execute the trampoline code in real mode. The trampoline vector
+ * passed to us is page alligned and is the physicall frame number for
+ * the code. We will execute this code in real mode.
+ */
+ ctxt->user_regs.eip = 0x0;
+ ctxt->user_regs.cs = (trampoline_vector << 8);
+ ctxt->flags = VGCF_HVM_GUEST;
+}
+
int start_svm(void)
{
u32 eax, ecx, edx;
@@ -484,6 +520,7 @@ int start_svm(void)
hvm_funcs.paging_enabled = svm_paging_enabled;
hvm_funcs.instruction_length = svm_instruction_length;
hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
+ hvm_funcs.init_ap_context = svm_init_ap_context;

hvm_enabled = 1;

@@ -660,6 +697,20 @@ static void arch_svm_do_launch(struct vc
if (svm_dbg_on)
svm_dump_host_regs(__func__);
#endif
+ if (v->vcpu_id != 0)
+ {
+ u16 cs_sel = regs->cs;
+ /*
+ * This is the launch of an AP; set state so that we begin executing
+ * the trampoline code in real-mode.
+ */
+ svm_do_vmmcall_reset_to_realmode(v, regs);
+ /* Adjust the state to execute the trampoline code.*/
+ v->arch.hvm_svm.vmcb->rip = 0;
+ v->arch.hvm_svm.vmcb->cs.sel= cs_sel;
+ v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
+ }
+
reset_stack_and_jump(svm_asm_do_launch);
}

@@ -896,8 +947,10 @@ static void svm_do_general_protection_fa
svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
}

-/* Reserved bits: [31:14], [12:1] */
-#define SVM_VCPU_CPUID_L1_RESERVED 0xffffdffe
+/* Reserved bits ECX: [31:14], [12:4], [2:1]*/
+#define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6
+/* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
+#define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400

static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input,
struct cpu_user_regs *regs)
@@ -920,20 +973,17 @@ static void svm_vmexit_do_cpuid(struct v

cpuid(input, &eax, &ebx, &ecx, &edx);

- if (input == 1)
+ if (input == 0x00000001)
{
if ( !hvm_apic_support(v->domain) ||
!vlapic_global_enabled((VLAPIC(v))) )
{
- clear_bit(X86_FEATURE_APIC, &edx);
- /* Since the apic is disabled, avoid any confusion about SMP cpus being available */
- clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */
- ebx &= 0xFF00FFFF; /* set the logical processor count to 1 */
- ebx |= 0x00010000;
- }
-
+ /* Since the apic is disabled, avoid any confusion
+ about SMP cpus being available */
+ clear_bit(X86_FEATURE_APIC, &edx);
+ }
+
#if CONFIG_PAGING_LEVELS < 3
- clear_bit(X86_FEATURE_NX, &edx);
clear_bit(X86_FEATURE_PAE, &edx);
clear_bit(X86_FEATURE_PSE, &edx);
clear_bit(X86_FEATURE_PSE36, &edx);
@@ -942,24 +992,90 @@ static void svm_vmexit_do_cpuid(struct v
{
if ( !v->domain->arch.hvm_domain.pae_enabled )
{
- clear_bit(X86_FEATURE_PAE, &edx);
- clear_bit(X86_FEATURE_NX, &edx);
+ clear_bit(X86_FEATURE_PAE, &edx);
}
clear_bit(X86_FEATURE_PSE, &edx);
clear_bit(X86_FEATURE_PSE36, &edx);
}
#endif
/* Clear out reserved bits. */
- ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
+ ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
+ edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
+
clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
- }
+
+ /* Guest should only see one logical processor.
+ * See details on page 23 of AMD CPUID Specification.
+ */
+ clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */
+ ebx &= 0xFF00FFFF; /* clear the logical processor count when HTT=0 */
+ ebx |= 0x00010000; /* set to 1 just for precaution */
+ }
+ else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
+ {
+ eax = ebx = ecx = edx = 0x0;
+ }
+ else if ( input == 0x80000001 )
+ {
+ /* We duplicate some CPUID_00000001 code because many bits of
+ CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
+
+ if ( !hvm_apic_support(v->domain) ||
+ !vlapic_global_enabled((VLAPIC(v))) )
+ {
+ /* Since the apic is disabled, avoid any confusion
+ about SMP cpus being available */
+ clear_bit(X86_FEATURE_APIC, &edx);
+ }
+
+ /* Clear the Cmp_Legacy bit
+ * This bit is supposed to be zero when HTT = 0.
+ * See details on page 23 of AMD CPUID Specification.
+ */
+ clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
+
#ifdef __i386__
- else if ( input == 0x80000001 )
- {
/* Mask feature for Intel ia32e or AMD long mode. */
+ clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx);
+
clear_bit(X86_FEATURE_LM & 31, &edx);
- }
+ clear_bit(X86_FEATURE_SYSCALL & 31, &edx);
#endif
+
+#if CONFIG_PAGING_LEVELS < 3
+ clear_bit(X86_FEATURE_NX & 31, &edx);
+ clear_bit(X86_FEATURE_PAE, &edx);
+ clear_bit(X86_FEATURE_PSE, &edx);
+ clear_bit(X86_FEATURE_PSE36, &edx);
+#else
+ if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
+ {
+ if ( !v->domain->arch.hvm_domain.pae_enabled )
+ {
+ clear_bit(X86_FEATURE_NX & 31, &edx);
+ clear_bit(X86_FEATURE_PAE, &edx);
+ }
+ clear_bit(X86_FEATURE_PSE, &edx);
+ clear_bit(X86_FEATURE_PSE36, &edx);
+ }
+#endif
+
+ /* Make SVM feature invisible to the guest. */
+ clear_bit(X86_FEATURE_SVME & 31, &ecx);
+
+ /* So far, we do not support 3DNow for the guest. */
+ clear_bit(X86_FEATURE_3DNOW & 31, &edx);
+ clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
+ }
+ else if ( ( input == 0x80000007 ) || ( input == 0x8000000A ) )
+ {
+ /* Mask out features of power management and SVM extension. */
+ eax = ebx = ecx = edx = 0;
+ }
+ else if ( input == 0x80000008 )
+ {
+ ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
+ }

regs->eax = (unsigned long)eax;
regs->ebx = (unsigned long)ebx;
@@ -2036,7 +2152,7 @@ void svm_handle_invlpg(const short invlp
void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
{
struct vcpu *v = current;
- u8 opcode[MAX_INST_SIZE], prefix, length = MAX_INST_SIZE;
+ u8 opcode[MAX_INST_LEN], prefix, length = MAX_INST_LEN;
unsigned long g_vaddr;
int inst_len;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/mm.c Wed May 31 13:05:21 2006 -0600
@@ -260,38 +260,85 @@ void share_xen_page_with_privileged_gues
share_xen_page_with_guest(page, dom_xen, readonly);
}

+#if defined(CONFIG_X86_PAE)
+
+#ifdef NDEBUG
+/* Only PDPTs above 4GB boundary need to be shadowed in low memory. */
+#define l3tab_needs_shadow(mfn) (mfn >= 0x100000)
+#else
+/*
+ * In debug builds we aggressively shadow PDPTs to exercise code paths.
+ * We cannot safely shadow the idle page table, nor shadow-mode page tables
+ * (detected by lack of an owning domain). Always shadow PDPTs above 4GB.
+ */
+#define l3tab_needs_shadow(mfn) \
+ ((((mfn << PAGE_SHIFT) != __pa(idle_pg_table)) && \
+ (page_get_owner(mfn_to_page(mfn)) != NULL)) || \
+ (mfn >= 0x100000))
+#endif
+
+static l1_pgentry_t *fix_pae_highmem_pl1e;
+
+/* Cache the address of PAE high-memory fixmap page tables. */
+static int __init cache_pae_fixmap_address(void)
+{
+ unsigned long fixmap_base = fix_to_virt(FIX_PAE_HIGHMEM_0);
+ l2_pgentry_t *pl2e = virt_to_xen_l2e(fixmap_base);
+ fix_pae_highmem_pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(fixmap_base);
+ return 0;
+}
+__initcall(cache_pae_fixmap_address);
+
static void __write_ptbase(unsigned long mfn)
{
-#ifdef CONFIG_X86_PAE
- if ( mfn >= 0x100000 )
- {
- l3_pgentry_t *highmem_l3tab, *lowmem_l3tab;
- struct vcpu *v = current;
- unsigned long flags;
-
- /* Protects against re-entry and against __pae_flush_pgd(). */
- local_irq_save(flags);
-
- /* Pick an unused low-memory L3 cache slot. */
- v->arch.lowmem_l3tab_inuse ^= 1;
- lowmem_l3tab = v->arch.lowmem_l3tab[v->arch.lowmem_l3tab_inuse];
- v->arch.lowmem_l3tab_high_mfn[v->arch.lowmem_l3tab_inuse] = mfn;
-
- /* Map the guest L3 table and copy to the chosen low-memory cache. */
- highmem_l3tab = map_domain_page(mfn);
- memcpy(lowmem_l3tab, highmem_l3tab, sizeof(v->arch.lowmem_l3tab));
- unmap_domain_page(highmem_l3tab);
-
- /* Install the low-memory L3 table in CR3. */
- write_cr3(__pa(lowmem_l3tab));
-
- local_irq_restore(flags);
+ l3_pgentry_t *highmem_l3tab, *lowmem_l3tab;
+ struct pae_l3_cache *cache = &current->arch.pae_l3_cache;
+ unsigned int cpu = smp_processor_id();
+
+ /* Fast path 1: does this mfn need a shadow at all? */
+ if ( !l3tab_needs_shadow(mfn) )
+ {
+ write_cr3(mfn << PAGE_SHIFT);
return;
}
-#endif
-
+
+ /* Caching logic is not interrupt safe. */
+ ASSERT(!in_irq());
+
+ /* Fast path 2: is this mfn already cached? */
+ if ( cache->high_mfn == mfn )
+ {
+ write_cr3(__pa(cache->table[cache->inuse_idx]));
+ return;
+ }
+
+ /* Protects against pae_flush_pgd(). */
+ spin_lock(&cache->lock);
+
+ cache->inuse_idx ^= 1;
+ cache->high_mfn = mfn;
+
+ /* Map the guest L3 table and copy to the chosen low-memory cache. */
+ *(fix_pae_highmem_pl1e - cpu) = l1e_from_pfn(mfn, __PAGE_HYPERVISOR);
+ highmem_l3tab = (l3_pgentry_t *)fix_to_virt(FIX_PAE_HIGHMEM_0 + cpu);
+ lowmem_l3tab = cache->table[cache->inuse_idx];
+ memcpy(lowmem_l3tab, highmem_l3tab, sizeof(cache->table[0]));
+ *(fix_pae_highmem_pl1e - cpu) = l1e_empty();
+
+ /* Install the low-memory L3 table in CR3. */
+ write_cr3(__pa(lowmem_l3tab));
+
+ spin_unlock(&cache->lock);
+}
+
+#else /* !CONFIG_X86_PAE */
+
+static void __write_ptbase(unsigned long mfn)
+{
write_cr3(mfn << PAGE_SHIFT);
}
+
+#endif /* !CONFIG_X86_PAE */

void write_ptbase(struct vcpu *v)
{
@@ -804,48 +851,39 @@ static int create_pae_xen_mappings(l3_pg
return 1;
}

-struct pae_flush_pgd {
- unsigned long l3tab_mfn;
- unsigned int l3tab_idx;
- l3_pgentry_t nl3e;
-};
-
-static void __pae_flush_pgd(void *data)
-{
- struct pae_flush_pgd *args = data;
- struct vcpu *v = this_cpu(curr_vcpu);
- int i = v->arch.lowmem_l3tab_inuse;
- intpte_t _ol3e, _nl3e, _pl3e;
- l3_pgentry_t *l3tab_ptr;
-
- ASSERT(!local_irq_is_enabled());
-
- if ( v->arch.lowmem_l3tab_high_mfn[i] != args->l3tab_mfn )
- return;
-
- l3tab_ptr = &v->arch.lowmem_l3tab[i][args->l3tab_idx];
-
- _ol3e = l3e_get_intpte(*l3tab_ptr);
- _nl3e = l3e_get_intpte(args->nl3e);
- _pl3e = cmpxchg((intpte_t *)l3tab_ptr, _ol3e, _nl3e);
- BUG_ON(_pl3e != _ol3e);
-}
-
/* Flush a pgdir update into low-memory caches. */
static void pae_flush_pgd(
unsigned long mfn, unsigned int idx, l3_pgentry_t nl3e)
{
struct domain *d = page_get_owner(mfn_to_page(mfn));
- struct pae_flush_pgd args = {
- .l3tab_mfn = mfn,
- .l3tab_idx = idx,
- .nl3e = nl3e };
+ struct vcpu *v;
+ intpte_t _ol3e, _nl3e, _pl3e;
+ l3_pgentry_t *l3tab_ptr;
+ struct pae_l3_cache *cache;

/* If below 4GB then the pgdir is not shadowed in low memory. */
- if ( mfn < 0x100000 )
+ if ( !l3tab_needs_shadow(mfn) )
return;

- on_selected_cpus(d->domain_dirty_cpumask, __pae_flush_pgd, &args, 1, 1);
+ for_each_vcpu ( d, v )
+ {
+ cache = &v->arch.pae_l3_cache;
+
+ spin_lock(&cache->lock);
+
+ if ( cache->high_mfn == mfn )
+ {
+ l3tab_ptr = &cache->table[cache->inuse_idx][idx];
+ _ol3e = l3e_get_intpte(*l3tab_ptr);
+ _nl3e = l3e_get_intpte(nl3e);
+ _pl3e = cmpxchg((intpte_t *)l3tab_ptr, _ol3e, _nl3e);
+ BUG_ON(_pl3e != _ol3e);
+ }
+
+ spin_unlock(&cache->lock);
+ }
+
+ flush_tlb_mask(d->domain_dirty_cpumask);
}

static inline int l1_backptr(
@@ -1567,12 +1605,18 @@ int get_page_type(struct page_info *page
{
if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
{
- if ( current->domain == page_get_owner(page) )
+ if ( (current->domain == page_get_owner(page)) &&
+ ((x & PGT_type_mask) == PGT_writable_page) )
{
/*
* This ensures functions like set_gdt() see up-to-date
* type info without needing to clean up writable p.t.
- * state on the fast path.
+ * state on the fast path. We take this path only
+ * when the current type is writable because:
+ * 1. It's the only type that this path can decrement.
+ * 2. If we take this path more liberally then we can
+ * enter a recursive loop via get_page_from_l1e()
+ * during pagetable revalidation.
*/
LOCK_BIGLOCK(current->domain);
cleanup_writable_pagetable(current->domain);
@@ -3708,11 +3752,10 @@ int map_pages_to_xen(
}

void __set_fixmap(
- enum fixed_addresses idx, unsigned long p, unsigned long flags)
-{
- if ( unlikely(idx >= __end_of_fixed_addresses) )
- BUG();
- map_pages_to_xen(fix_to_virt(idx), p >> PAGE_SHIFT, 1, flags);
+ enum fixed_addresses idx, unsigned long mfn, unsigned long flags)
+{
+ BUG_ON(idx >= __end_of_fixed_addresses);
+ map_pages_to_xen(fix_to_virt(idx), mfn, 1, flags);
}

#ifdef MEMORY_GUARD
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/shadow.c Wed May 31 13:05:21 2006 -0600
@@ -1724,7 +1724,8 @@ static int resync_all(struct domain *d,
unshadow_l1 = 1;
else {
need_flush |= error;
- set_guest_back_ptr(d, *sl1e_p, smfn, i);
+ if ( l1e_get_flags(*sl1e_p) & _PAGE_PRESENT )
+ set_guest_back_ptr(d, *sl1e_p, smfn, i);
}
// can't update snapshots of linear page tables -- they
// are used multiple times...
diff -r 3be4c8288737 -r acabf4bdec4f xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Wed May 31 11:30:07 2006 -0600
+++ b/xen/arch/x86/shadow32.c Wed May 31 13:05:21 2006 -0600
@@ -2691,7 +2691,8 @@ static int resync_all(struct domain *d,
unshadow_l1 = 1;
else {
need_flush |= error;
- set_guest_back_ptr(d, shadow1[i], smfn, i);
+ if ( l1e_get_flags(shadow1[i]) & _PAGE_PRESENT )
+ set_guest_back_ptr(d, shadow1[i], smfn, i);
}

// can't update snapshots of linear page tables -- they
diff -r 3be4c8288737 -r acabf4bdec4f xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Wed May 31 11:30:07 2006 -0600
+++ b/xen/include/asm-x86/domain.h Wed May 31 13:05:21 2006 -0600
@@ -114,23 +114,32 @@ struct arch_domain
unsigned long first_reserved_pfn;
} __cacheline_aligned;

-struct arch_vcpu
-{
- /* Needs 16-byte aligment for FXSAVE/FXRSTOR. */
- struct vcpu_guest_context guest_context
- __attribute__((__aligned__(16)));
-
#ifdef CONFIG_X86_PAE
+struct pae_l3_cache {
/*
* Two low-memory (<4GB) PAE L3 tables, used as fallback when the guest
* supplies a >=4GB PAE L3 table. We need two because we cannot set up
* an L3 table while we are currently running on it (without using
* expensive atomic 64-bit operations).
*/
- l3_pgentry_t lowmem_l3tab[2][4] __attribute__((__aligned__(32)));
- unsigned long lowmem_l3tab_high_mfn[2]; /* The >=4GB MFN being shadowed. */
- unsigned int lowmem_l3tab_inuse; /* Which lowmem_l3tab is in use? */
-#endif
+ l3_pgentry_t table[2][4] __attribute__((__aligned__(32)));
+ unsigned long high_mfn; /* The >=4GB MFN being shadowed. */
+ unsigned int inuse_idx; /* Which of the two cache slots is in use? */
+ spinlock_t lock;
+};
+#define pae_l3_cache_init(c) spin_lock_init(&(c)->lock)
+#else /* !CONFIG_X86_PAE */
+struct pae_l3_cache { };
+#define pae_l3_cache_init(c) ((void)0)
+#endif
+
+struct arch_vcpu
+{
+ /* Needs 16-byte aligment for FXSAVE/FXRSTOR. */
+ struct vcpu_guest_context guest_context
+ __attribute__((__aligned__(16)));
+
+ struct pae_l3_cache pae_l3_cache;

unsigned long flags; /* TF_ */

diff -r 3be4c8288737 -r acabf4bdec4f xen/include/asm-x86/fixmap.h
--- a/xen/include/asm-x86/fixmap.h Wed May 31 11:30:07 2006 -0600
+++ b/xen/include/asm-x86/fixmap.h Wed May 31 13:05:21 2006 -0600
@@ -25,6 +25,10 @@
* from the end of virtual memory backwards.
*/
enum fixed_addresses {
+#ifdef CONFIG_X86_PAE
+ FIX_PAE_HIGHMEM_0,
+ FIX_PAE_HIGHMEM_END = FIX_PAE_HIGHMEM_0 + NR_CPUS-1,
+#endif
FIX_APIC_BASE,
FIX_IO_APIC_BASE_0,
FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
@@ -40,13 +44,13 @@ enum fixed_addresses {
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)

extern void __set_fixmap(
- enum fixed_addresses idx, unsigned long p, unsigned long flags);
+ enum fixed_addresses idx, unsigned long mfn, unsigned long flags);

#define set_fixmap(idx, phys) \
- __set_fixmap(idx, phys, PAGE_HYPERVISOR)
+ __set_fixmap(idx, (phys)>>PAGE_SHIFT, PAGE_HYPERVISOR)

#define set_fixmap_nocache(idx, phys) \
- __set_fixmap(idx, phys, PAGE_HYPERVISOR_NOCACHE)
+ __set_fixmap(idx, (phys)>>PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE)

#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
diff -r 3be4c8288737 -r acabf4bdec4f xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h Wed May 31 11:30:07 2006 -0600
+++ b/xen/include/asm-x86/shadow.h Wed May 31 13:05:21 2006 -0600
@@ -762,10 +762,16 @@ static inline void set_guest_back_ptr(
unsigned long gmfn;

ASSERT(shadow_lock_is_acquired(d));
+ ASSERT( smfn );
gmfn = l1e_get_pfn(spte);
- mfn_to_page(gmfn)->tlbflush_timestamp = smfn;
- mfn_to_page(gmfn)->u.inuse.type_info &= ~PGT_va_mask;
- mfn_to_page(gmfn)->u.inuse.type_info |= (unsigned long) index << PGT_va_shift;
+ ASSERT( gmfn );
+ if ( l1e_get_flags(spte) & _PAGE_RW )
+ {
+ mfn_to_page(gmfn)->tlbflush_timestamp = smfn;
+ mfn_to_page(gmfn)->u.inuse.type_info &= ~PGT_va_mask;
+ mfn_to_page(gmfn)->u.inuse.type_info |=
+ (unsigned long) index << PGT_va_shift;
+ }
}
}

diff -r 3be4c8288737 -r acabf4bdec4f xen/include/public/sched_ctl.h
--- a/xen/include/public/sched_ctl.h Wed May 31 11:30:07 2006 -0600
+++ b/xen/include/public/sched_ctl.h Wed May 31 13:05:21 2006 -0600
@@ -49,7 +49,7 @@ struct sched_adjdom_cmd {
uint32_t extratime;
uint32_t weight;
} sedf;
- struct csched_domain {
+ struct sched_credit_adjdom {
uint16_t weight;
uint16_t cap;
} credit;
diff -r 3be4c8288737 -r acabf4bdec4f xen/include/xen/perfc.h
--- a/xen/include/xen/perfc.h Wed May 31 11:30:07 2006 -0600
+++ b/xen/include/xen/perfc.h Wed May 31 13:05:21 2006 -0600
@@ -56,10 +56,8 @@ extern struct perfcounter perfcounters;
#define perfc_value(x) atomic_read(&perfcounters.x[0])
#define perfc_valuec(x) atomic_read(&perfcounters.x[smp_processor_id()])
#define perfc_valuea(x,y) \
- do { \
- if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
- atomic_read(&perfcounters.x[y]); \
- } while ( 0 )
+ ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ? \
+ atomic_read(&perfcounters.x[y]) : 0 )
#define perfc_set(x,v) atomic_set(&perfcounters.x[0], v)
#define perfc_setc(x,v) atomic_set(&perfcounters.x[smp_processor_id()], v)
#define perfc_seta(x,y,v) \
diff -r 3be4c8288737 -r acabf4bdec4f xen/tools/Makefile
--- a/xen/tools/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/xen/tools/Makefile Wed May 31 13:05:21 2006 -0600
@@ -1,5 +1,6 @@

-include $(BASEDIR)/../Config.mk
+XEN_ROOT = $(BASEDIR)/..
+include $(XEN_ROOT)/Config.mk

.PHONY: default
default:
diff -r 3be4c8288737 -r acabf4bdec4f xen/tools/figlet/Makefile
--- a/xen/tools/figlet/Makefile Wed May 31 11:30:07 2006 -0600
+++ b/xen/tools/figlet/Makefile Wed May 31 13:05:21 2006 -0600
@@ -1,5 +1,6 @@

-include $(BASEDIR)/../Config.mk
+XEN_ROOT = $(BASEDIR)/..
+include $(XEN_ROOT)/Config.mk

figlet: figlet.c
$(HOSTCC) -o $@ $<
diff -r 3be4c8288737 -r acabf4bdec4f config/ia64.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/ia64.mk Wed May 31 13:05:21 2006 -0600
@@ -0,0 +1,4 @@
+CONFIG_IA64 := y
+CONFIG_IOEMU := y
+
+LIBDIR := lib
diff -r 3be4c8288737 -r acabf4bdec4f config/x86_32.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/x86_32.mk Wed May 31 13:05:21 2006 -0600
@@ -0,0 +1,9 @@
+CONFIG_X86 := y
+CONFIG_PLAN9 := y
+CONFIG_HVM := y
+CONFIG_MIGRATE := y
+CONFIG_IOEMU := y
+CONFIG_MBOOTPACK := y
+
+CFLAGS += -m32 -march=i686
+LIBDIR := lib
diff -r 3be4c8288737 -r acabf4bdec4f config/x86_64.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/x86_64.mk Wed May 31 13:05:21 2006 -0600
@@ -0,0 +1,9 @@
+CONFIG_X86 := y
+CONFIG_PLAN9 := y
+CONFIG_HVM := y
+CONFIG_MIGRATE := y
+CONFIG_IOEMU := y
+CONFIG_MBOOTPACK := y
+
+CFLAGS += -m64
+LIBDIR = lib64
diff -r 3be4c8288737 -r acabf4bdec4f tools/vtpm/tpm_emulator-0.3-x86_64.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch Wed May 31 13:05:21 2006 -0600
@@ -0,0 +1,484 @@
+diff -uprN tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
+--- tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-26 11:26:02.000000000 -0700
+@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
+ {
+ void *ret = (void*)kmalloc(size, GFP_KERNEL);
+ if (!ret) panic(KERN_CRIT TPM_MODULE_NAME
+- "GMP: cannot allocate memory (size=%u)\n", size);
++ "GMP: cannot allocate memory (size=%Zu)\n", size);
+ return ret;
+ }
+
+@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne
+ {
+ void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
+ if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
+- "(old_size=%u new_size=%u)\n", old_size, new_size);
++ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
+ memcpy(ret, oldptr, old_size);
+ kfree(oldptr);
+ return ret;
+diff -uprN tpm_emulator-0.3/linux_module.c tpm_emulator-0.3-x86_64/linux_module.c
+--- tpm_emulator-0.3/linux_module.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/linux_module.c 2006-05-26 11:26:02.000000000 -0700
+@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino
+
+ static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+ {
+- debug("%s(%d)", __FUNCTION__, count);
++ debug("%s(%Zu)", __FUNCTION__, count);
+ down(&tpm_mutex);
+ if (tpm_response.data != NULL) {
+ count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
+@@ -91,7 +91,7 @@ static ssize_t tpm_read(struct file *fil
+
+ static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ {
+- debug("%s(%d)", __FUNCTION__, count);
++ debug("%s(%Zu)", __FUNCTION__, count);
+ down(&tpm_mutex);
+ *ppos = 0;
+ if (tpm_response.data != NULL) kfree(tpm_response.data);
+diff -uprN tpm_emulator-0.3/linux_module.h tpm_emulator-0.3-x86_64/linux_module.h
+--- tpm_emulator-0.3/linux_module.h 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/linux_module.h 2006-05-26 11:26:02.000000000 -0700
+@@ -28,8 +28,10 @@
+
+ /* module settings */
+
++#ifndef STR
+ #define STR(s) __STR__(s)
+ #define __STR__(s) #s
++#endif
+ #include "tpm_version.h"
+
+ #define TPM_DEVICE_MINOR 224
+diff -uprN tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
+--- tpm_emulator-0.3/Makefile 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/Makefile 2006-05-26 11:26:02.000000000 -0700
+@@ -7,6 +7,7 @@
+ KERNEL_RELEASE := $(shell uname -r)
+ KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+ MOD_SUBDIR := misc
++COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+
+ # module settings
+ MODULE_NAME := tpm_emulator
+@@ -17,8 +18,14 @@ VERSION_BUILD := $(shell date +"%s")
+ # enable/disable DEBUG messages
+ EXTRA_CFLAGS += -Wall -DDEBUG -g
+
++ifeq ($(COMPILE_ARCH),x86_64)
++LIBDIR = lib64
++else
++LIBDIR = lib
++endif
++
+ # GNU MP configuration
+-GMP_LIB := /usr/lib/libgmp.a
++GMP_LIB := /usr/$(LIBDIR)/libgmp.a
+ GMP_HEADER := /usr/include/gmp.h
+
+ # sources and objects
+diff -uprN tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
+--- tpm_emulator-0.3/README 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/README 2006-05-26 11:26:02.000000000 -0700
+@@ -43,6 +43,12 @@ Example:
+ GMP_LIB := /usr/lib/libgmp.a
+ GMP_HEADER := /usr/include/gmp.h
+
++GNU MP Library on 64 bit Systems
++--------------------------------------------------------------------------
++Some 64-bit kernels have problems with importing the user-space gmp
++library (/usr/lib*/libgmp.a) into kernel space. These kernels will require
++that the gmp library be recompiled for kernel space with -mcmodel=kernel.
++
+ Installation
+ --------------------------------------------------------------------------
+ The compilation and installation process uses the build environment for
+diff -uprN tpm_emulator-0.3/tpm/tpm_credentials.c tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
+--- tpm_emulator-0.3/tpm/tpm_credentials.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 2006-05-26 11:26:02.000000000 -0700
+@@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC
+
+ TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey)
+ {
+- UINT32 key_length;
++ size_t key_length;
+ if (!tpmData.permanent.data.endorsementKey.size) return TPM_NO_ENDORSEMENT;
+ /* setup TPM_PUBKEY structure */
+- key_length = tpmData.permanent.data.endorsementKey.size;
+- pubEndorsementKey->pubKey.keyLength = key_length >> 3;
++ pubEndorsementKey->pubKey.keyLength = tpmData.permanent.data.endorsementKey.size >> 3;
+ pubEndorsementKey->pubKey.key = tpm_malloc(pubEndorsementKey->pubKey.keyLength);
+ if (pubEndorsementKey->pubKey.key == NULL) return TPM_FAIL;
+ rsa_export_modulus(&tpmData.permanent.data.endorsementKey,
+- pubEndorsementKey->pubKey.key,
+- &pubEndorsementKey->pubKey.keyLength);
++ pubEndorsementKey->pubKey.key,
++ &key_length);
++ pubEndorsementKey->pubKey.keyLength = key_length;
+ pubEndorsementKey->algorithmParms.algorithmID = TPM_ALG_RSA;
+ pubEndorsementKey->algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+ pubEndorsementKey->algorithmParms.sigScheme = TPM_SS_NONE;
+@@ -175,6 +175,7 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_
+ {
+ TPM_RESULT res;
+ TPM_KEY_DATA *srk = &tpmData.permanent.data.srk;
++ size_t key_length;
+ info("TPM_OwnerReadInternalPub()");
+ /* verify authorization */
+ res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
+@@ -186,7 +187,8 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_
+ publicPortion->pubKey.key = tpm_malloc(publicPortion->pubKey.keyLength);
+ if (publicPortion->pubKey.key == NULL) return TPM_FAIL;
+ rsa_export_modulus(&srk->key, publicPortion->pubKey.key,
+- &publicPortion->pubKey.keyLength);
++ &key_length);
++ publicPortion->pubKey.keyLength = key_length;
+ publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA;
+ publicPortion->algorithmParms.encScheme = srk->encScheme;
+ publicPortion->algorithmParms.sigScheme = srk->sigScheme;
+diff -uprN tpm_emulator-0.3/tpm/tpm_crypto.c tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
+--- tpm_emulator-0.3/tpm/tpm_crypto.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-26 11:26:02.000000000 -0700
+@@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
+ TPM_KEY_DATA *cert, *key;
+ sha1_ctx_t sha1_ctx;
+ BYTE *buf, *p;
+- UINT32 length;
++ UINT32 length32;
++ size_t length;
+ info("TPM_CertifyKey()");
+ /* get keys */
+ cert = tpm_get_key(certHandle);
+@@ -264,14 +265,15 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
+ /* compute the digest of the CERTIFY_INFO[2] structure and sign it */
+ length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
+ p = buf = tpm_malloc(length);
++ length32=(UINT32) length;
+ if (buf == NULL
+- || tpm_marshal_TPM_CERTIFY_INFO(&p, &length, certifyInfo)) {
++ || tpm_marshal_TPM_CERTIFY_INFO(&p, &length32, certifyInfo)) {
+ free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
+ return TPM_FAIL;
+ }
+ length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
+ sha1_init(&sha1_ctx);
+- sha1_update(&sha1_ctx, buf, length);
++ sha1_update(&sha1_ctx, buf, (size_t) length);
+ sha1_final(&sha1_ctx, buf);
+ res = tpm_sign(cert, auth1, FALSE, buf, SHA1_DIGEST_LENGTH, outData, outDataSize);
+ tpm_free(buf);
+@@ -292,7 +294,8 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+ TPM_KEY_DATA *cert, *key;
+ sha1_ctx_t sha1_ctx;
+ BYTE *buf, *p;
+- UINT32 length;
++ size_t length;
++ UINT32 length32;
+ info("TPM_CertifyKey2()");
+ /* get keys */
+ cert = tpm_get_key(certHandle);
+@@ -362,8 +365,9 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+ /* compute the digest of the CERTIFY_INFO[2] structure and sign it */
+ length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
+ p = buf = tpm_malloc(length);
++ length32 = (UINT32) length;
+ if (buf == NULL
+- || tpm_marshal_TPM_CERTIFY_INFO(&p, &length, certifyInfo)) {
++ || tpm_marshal_TPM_CERTIFY_INFO(&p, &length32, certifyInfo)) {
+ free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
+ return TPM_FAIL;
+ }
+diff -uprN tpm_emulator-0.3/tpm/tpm_data.c tpm_emulator-0.3-x86_64/tpm/tpm_data.c
+--- tpm_emulator-0.3/tpm/tpm_data.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-26 11:26:02.000000000 -0700
+@@ -214,7 +214,7 @@ static int read_from_file(uint8_t **data
+ int tpm_store_permanent_data(void)
+ {
+ uint8_t *buf, *ptr;
+- size_t buf_length, len;
++ UINT32 buf_length, len;
+
+ /* marshal data */
+ buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
+@@ -242,13 +242,14 @@ int tpm_store_permanent_data(void)
+ int tpm_restore_permanent_data(void)
+ {
+ uint8_t *buf, *ptr;
+- size_t buf_length, len;
++ size_t buf_length;
++ UINT32 len;
+ TPM_VERSION ver;
+
+ /* read data */
+ if (read_from_file(&buf, &buf_length)) return -1;
+ ptr = buf;
+- len = buf_length;
++ len = (uint32_t) buf_length;
+ /* unmarshal data */
+ if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
+ || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
+diff -uprN tpm_emulator-0.3/tpm/tpm_marshalling.c tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
+--- tpm_emulator-0.3/tpm/tpm_marshalling.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 2006-05-26 11:26:02.000000000 -0700
+@@ -1212,7 +1212,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE *
+
+ int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v)
+ {
+- UINT32 m_len, e_len, q_len;
++ size_t m_len, e_len, q_len;
+ if (*length < sizeof_RSA((*v))) return -1;
+ if (v->size > 0) {
+ rsa_export_modulus(v, &(*ptr)[6], &m_len);
+diff -uprN tpm_emulator-0.3/tpm/tpm_owner.c tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
+--- tpm_emulator-0.3/tpm/tpm_owner.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 2006-05-26 11:26:02.000000000 -0700
+@@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
+ TPM_RESULT res;
+ rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
+ TPM_KEY_DATA *srk = &tpmData.permanent.data.srk;
+- UINT32 buf_size = ek->size >> 3;
++ size_t buf_size = ek->size >> 3, key_length;
+ BYTE buf[buf_size];
+
+ info("TPM_TakeOwnership()");
+@@ -172,7 +172,8 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
+ return TPM_FAIL;
+ }
+ rsa_export_modulus(&srk->key, srkPub->pubKey.key,
+- &srkPub->pubKey.keyLength);
++ &key_length);
++ srkPub->pubKey.keyLength = (UINT32) key_length;
+ /* setup tpmProof and set state to owned */
+ tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce,
+ sizeof(tpmData.permanent.data.tpmProof.nonce));
+diff -uprN tpm_emulator-0.3/tpm/tpm_storage.c tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
+--- tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 2006-05-26 14:33:18.000000000 -0700
+@@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
+ BYTE *enc, UINT32 *enc_size)
+ {
+ UINT32 len;
++ size_t enc_size32 = *enc_size;
+ BYTE *buf, *ptr;
+ rsa_public_key_t pub_key;
+ int scheme;
+@@ -72,7 +73,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
+ if (buf == NULL
+ || tpm_marshal_TPM_SEALED_DATA(&ptr, &len, seal)
+ || rsa_encrypt(&pub_key, scheme, buf, sizeof_TPM_SEALED_DATA((*seal)),
+- enc, enc_size)) {
++ enc, &enc_size32)) {
+ tpm_free(buf);
+ rsa_release_public_key(&pub_key);
+ return -1;
+@@ -85,7 +86,8 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
+ int decrypt_sealed_data(TPM_KEY_DATA *key, BYTE *enc, UINT32 enc_size,
+ TPM_SEALED_DATA *seal, BYTE **buf)
+ {
+- UINT32 len;
++ size_t len;
++ UINT32 len32;
+ BYTE *ptr;
+ int scheme;
+ switch (key->encScheme) {
+@@ -96,8 +98,12 @@ int decrypt_sealed_data(TPM_KEY_DATA *ke
+ len = enc_size;
+ *buf = ptr = tpm_malloc(len);
+ if (*buf == NULL
+- || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len)
+- || tpm_unmarshal_TPM_SEALED_DATA(&ptr, &len, seal)) {
++ || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len) ){
++ tpm_free(*buf);
++ return -1;
++ }
++ len32 = len;
++ if (tpm_unmarshal_TPM_SEALED_DATA(&ptr, &len32, seal)) {
+ tpm_free(*buf);
+ return -1;
+ }
+@@ -237,11 +243,12 @@ TPM_RESULT TPM_Unseal(TPM_KEY_HANDLE par
+
+ TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE keyHandle, UINT32 inDataSize,
+ BYTE *inData, TPM_AUTH *auth1,
+- UINT32 *outDataSize, BYTE **outData)
++ UINT32 *outDataSize32, BYTE **outData)
+ {
+ TPM_RESULT res;
+ TPM_KEY_DATA *key;
+ int scheme;
++ size_t outDataSize;
+ info("TPM_UnBind()");
+ /* get key */
+ key = tpm_get_key(keyHandle);
+@@ -258,8 +265,8 @@ TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE key
+ /* the size of the input data muss be greater than zero */
+ if (inDataSize == 0) return TPM_BAD_PARAMETER;
+ /* decrypt data */
+- *outDataSize = inDataSize;
+- *outData = tpm_malloc(*outDataSize);
++ outDataSize = inDataSize;
++ *outData = tpm_malloc(outDataSize);
+ if (*outData == NULL) return TPM_FAIL;
+ switch (key->encScheme) {
+ case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
+@@ -267,20 +274,21 @@ TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE key
+ default: tpm_free(*outData); return TPM_DECRYPT_ERROR;
+ }
+ if (rsa_decrypt(&key->key, scheme, inData, inDataSize,
+- *outData, outDataSize)) {
++ *outData, &outDataSize)) {
+ tpm_free(*outData);
+ return TPM_DECRYPT_ERROR;
+ }
+ /* verify data if it is of type TPM_BOUND_DATA */
+ if (key->encScheme == TPM_ES_RSAESOAEP_SHA1_MGF1
+ || key->keyUsage != TPM_KEY_LEGACY) {
+- if (*outDataSize < 5 || memcmp(*outData, "\x01\x01\00\x00\x02", 5) != 0) {
++ if (outDataSize < 5 || memcmp(*outData, "\x01\x01\00\x00\x02", 5) != 0) {
+ tpm_free(*outData);
+ return TPM_DECRYPT_ERROR;
+ }
+- *outDataSize -= 5;
+- memmove(*outData, &(*outData)[5], *outDataSize);
++ outDataSize -= 5;
++ memmove(*outData, &(*outData)[5], outDataSize);
+ }
++ *outDataSize32 = (UINT32) outDataSize;
+ return TPM_SUCCESS;
+ }
+
+@@ -311,12 +319,13 @@ static int verify_key_digest(TPM_KEY *ke
+ }
+
+ int encrypt_private_key(TPM_KEY_DATA *key, TPM_STORE_ASYMKEY *store,
+- BYTE *enc, UINT32 *enc_size)
++ BYTE *enc, UINT32 *enc_size32)
+ {
+ UINT32 len;
+ BYTE *buf, *ptr;
+ rsa_public_key_t pub_key;
+ int scheme;
++ size_t enc_size;
+ switch (key->encScheme) {
+ case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
+ case TPM_ES_RSAESPKCSv15: scheme = RSA_ES_PKCSV15; break;
+@@ -328,11 +337,12 @@ int encrypt_private_key(TPM_KEY_DATA *ke
+ if (buf == NULL
+ || tpm_marshal_TPM_STORE_ASYMKEY(&ptr, &len, store)
+ || rsa_encrypt(&pub_key, scheme, buf, sizeof_TPM_STORE_ASYMKEY((*store)),
+- enc, enc_size)) {
++ enc, &enc_size)) {
+ tpm_free(buf);
+ rsa_release_public_key(&pub_key);
+ return -1;
+ }
++ *enc_size32 = (UINT32) enc_size;
+ tpm_free(buf);
+ rsa_release_public_key(&pub_key);
+ return 0;
+@@ -341,7 +351,8 @@ int encrypt_private_key(TPM_KEY_DATA *ke
+ int decrypt_private_key(TPM_KEY_DATA *key, BYTE *enc, UINT32 enc_size,
+ TPM_STORE_ASYMKEY *store, BYTE **buf)
+ {
+- UINT32 len;
++ UINT32 len32;
++ size_t len;
+ BYTE *ptr;
+ int scheme;
+ switch (key->encScheme) {
+@@ -352,8 +363,12 @@ int decrypt_private_key(TPM_KEY_DATA *ke
+ len = enc_size;
+ *buf = ptr = tpm_malloc(len);
+ if (*buf == NULL
+- || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len)
+- || tpm_unmarshal_TPM_STORE_ASYMKEY(&ptr, &len, store)) {
++ || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len) ) {
++ tpm_free(*buf);
++ return -1;
++ }
++ len32 = (UINT32) len;
++ if (tpm_unmarshal_TPM_STORE_ASYMKEY(&ptr, &len32, store)) {
+ tpm_free(*buf);
+ return -1;
+ }
+@@ -371,7 +386,7 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
+ TPM_SESSION_DATA *session;
+ TPM_STORE_ASYMKEY store;
+ rsa_private_key_t rsa;
+- UINT32 key_length;
++ size_t key_length;
+
+ info("TPM_CreateWrapKey()");
+ /* get parent key */
+@@ -428,11 +443,11 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
+ }
+ if (compute_key_digest(wrappedKey, &store.pubDataDigest)) return TPM_FAIL;
+ /* generate key and store it */
+- key_length = keyInfo->algorithmParms.parms.rsa.keyLength;
+- if (rsa_generate_key(&rsa, key_length)) return TPM_FAIL;
+- wrappedKey->pubKey.keyLength = key_length >> 3;
++ if (rsa_generate_key(&rsa, keyInfo->algorithmParms.parms.rsa.keyLength))
++ return TPM_FAIL;
++ wrappedKey->pubKey.keyLength = keyInfo->algorithmParms.parms.rsa.keyLength >> 3;
+ wrappedKey->pubKey.key = tpm_malloc(wrappedKey->pubKey.keyLength);
+- store.privKey.keyLength = key_length >> 4;
++ store.privKey.keyLength = keyInfo->algorithmParms.parms.rsa.keyLength >> 4;
+ store.privKey.key = tpm_malloc(store.privKey.keyLength);
+ wrappedKey->encDataSize = parent->key.size >> 3;
+ wrappedKey->encData = tpm_malloc(wrappedKey->encDataSize);
+@@ -444,9 +459,11 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
+ tpm_free(wrappedKey->encData);
+ return TPM_FAIL;
+ }
+- rsa_export_modulus(&rsa, wrappedKey->pubKey.key,
+- &wrappedKey->pubKey.keyLength);
+- rsa_export_prime1(&rsa, store.privKey.key, &store.privKey.keyLength);
++ rsa_export_modulus(&rsa, wrappedKey->pubKey.key,
++ &key_length);
++ wrappedKey->pubKey.keyLength = (UINT32) key_length;
++ rsa_export_prime1(&rsa, store.privKey.key, &key_length);
++ store.privKey.keyLength = (UINT32) key_length;
+ rsa_release_private_key(&rsa);
+ /* encrypt private key data */
+ if (encrypt_private_key(parent, &store, wrappedKey->encData,
+@@ -567,6 +584,7 @@ TPM_RESULT TPM_LoadKey2(TPM_KEY_HANDLE p
+
+ int tpm_setup_key_parms(TPM_KEY_DATA *key, TPM_KEY_PARMS *parms)
+ {
++ size_t key_length;
+ parms->algorithmID = TPM_ALG_RSA;
+ parms->encScheme = key->encScheme;
+ parms->sigScheme = key->sigScheme;
+@@ -576,7 +594,8 @@ int tpm_setup_key_parms(TPM_KEY_DATA *ke
+ parms->parms.rsa.exponent = tpm_malloc(parms->parms.rsa.exponentSize);
+ if (parms->parms.rsa.exponent == NULL) return -1;
+ rsa_export_exponent(&key->key, parms->parms.rsa.exponent,
+- &parms->parms.rsa.exponentSize);
++ &key_length);
++ parms->parms.rsa.exponentSize = (UINT32) key_length;
+ parms->parmSize = 12 + parms->parms.rsa.exponentSize;
+ return 0;
+ }
+@@ -587,6 +606,7 @@ TPM_RESULT TPM_GetPubKey(TPM_KEY_HANDLE
+ TPM_RESULT res;
+ TPM_KEY_DATA *key;
+ TPM_DIGEST digest;
++ size_t key_length;
+ info("TPM_GetPubKey()");
+ /* get key */
+ if (keyHandle == TPM_KH_SRK) return TPM_BAD_PARAMETER;
+@@ -614,8 +634,8 @@ TPM_RESULT TPM_GetPubKey(TPM_KEY_HANDLE
+ pubKey->pubKey.keyLength = key->key.size >> 3;
+ pubKey->pubKey.key = tpm_malloc(pubKey->pubKey.keyLength);
+ if (pubKey->pubKey.key == NULL) return TPM_FAIL;
+- rsa_export_modulus(&key->key, pubKey->pubKey.key,
+- &pubKey->pubKey.keyLength);
++ rsa_export_modulus(&key->key, pubKey->pubKey.key, &key_length);
++ pubKey->pubKey.keyLength = (UINT32) key_length;
+ if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) {
+ tpm_free(pubKey->pubKey.key);
+ return TPM_FAIL;
diff -r 3be4c8288737 -r acabf4bdec4f tools/vtpm/tpm_emulator-0.2b-x86_64.patch
--- a/tools/vtpm/tpm_emulator-0.2b-x86_64.patch Wed May 31 11:30:07 2006 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,499 +0,0 @@
-diff -uprN tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c
---- tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2005-09-19 14:10:29.000000000 -0700
-@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
- {
- void *ret = (void*)kmalloc(size, GFP_KERNEL);
- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME
-- "GMP: cannot allocate memory (size=%u)\n", size);
-+ "GMP: cannot allocate memory (size=%Zu)\n", size);
- return ret;
- }
-
-@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne
- {
- void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
-- "(old_size=%u new_size=%u)\n", old_size, new_size);
-+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
- memcpy(ret, oldptr, old_size);
- kfree(oldptr);
- return ret;
-diff -uprN tpm_emulator-0.2/linux_module.c tpm_emulator-0.2-x86_64/linux_module.c
---- tpm_emulator-0.2/linux_module.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/linux_module.c 2005-09-19 14:10:29.000000000 -0700
-@@ -66,7 +66,7 @@ static int tpm_release(struct inode *ino
-
- static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
- {
-- debug("%s(%d)", __FUNCTION__, count);
-+ debug("%s(%Zu)", __FUNCTION__, count);
- down(&tpm_mutex);
- if (tpm_response.data != NULL) {
- count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
-@@ -81,7 +81,7 @@ static ssize_t tpm_read(struct file *fil
-
- static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
- {
-- debug("%s(%d)", __FUNCTION__, count);
-+ debug("%s(%Zu)", __FUNCTION__, count);
- down(&tpm_mutex);
- *ppos = 0;
- if (tpm_response.data != NULL) kfree(tpm_response.data);
-diff -uprN tpm_emulator-0.2/linux_module.h tpm_emulator-0.2-x86_64/linux_module.h
---- tpm_emulator-0.2/linux_module.h 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/linux_module.h 2005-09-19 14:10:29.000000000 -0700
-@@ -28,8 +28,10 @@
-
- /* module settings */
-
-+#ifndef STR
- #define STR(s) __STR__(s)
- #define __STR__(s) #s
-+#endif
- #include "tpm_version.h"
-
- #define TPM_DEVICE_MINOR 224
-diff -uprN tpm_emulator-0.2/Makefile tpm_emulator-0.2-x86_64/Makefile
---- tpm_emulator-0.2/Makefile 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/Makefile 2005-09-19 14:10:29.000000000 -0700
-@@ -7,6 +7,7 @@
- KERNEL_RELEASE := $(shell uname -r)
- KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
- MOD_SUBDIR := misc
-+COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
-
- # module settings
- MODULE_NAME := tpm_emulator
-@@ -17,8 +18,14 @@ VERSION_BUILD := $(shell date +"%s")
- # enable/disable DEBUG messages
- EXTRA_CFLAGS += -DDEBUG -g
-
-+ifeq ($(COMPILE_ARCH),x86_64)
-+LIBDIR = lib64
-+else
-+LIBDIR = lib
-+endif
-+
- # GNU MP configuration
--GMP_LIB := /usr/lib/libgmp.a
-+GMP_LIB := /usr/$(LIBDIR)/libgmp.a
- GMP_HEADER := /usr/include/gmp.h
-
- # sources and objects
-diff -uprN tpm_emulator-0.2/README tpm_emulator-0.2-x86_64/README
---- tpm_emulator-0.2/README 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/README 2005-09-19 14:21:43.000000000 -0700
-@@ -45,6 +45,12 @@ Example:
- GMP_LIB := /usr/lib/libgmp.a
- GMP_HEADER := /usr/include/gmp.h
-
-+GNU MP Library on 64 bit Systems
-+--------------------------------------------------------------------------
-+Some 64-bit kernels have problems with importing the user-space gmp
-+library (/usr/lib*/libgmp.a) into kernel space. These kernels will require
-+that the gmp library be recompiled for kernel space with -mcmodel=kernel.
-+
- Installation
- --------------------------------------------------------------------------
- The compilation and installation process uses the build environment for
-diff -uprN tpm_emulator-0.2/tpm/tpm_credentials.c tpm_emulator-0.2-x86_64/tpm/tpm_credentials.c
---- tpm_emulator-0.2/tpm/tpm_credentials.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_credentials.c 2005-09-19 14:10:29.000000000 -0700
-@@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC
-
- TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey)
- {
-- UINT32 key_length;
-+ size_t key_length;
- if (!tpmData.permanent.data.endorsementKey.size) return TPM_NO_ENDORSEMENT;
- /* setup TPM_PUBKEY structure */
-- key_length = tpmData.permanent.data.endorsementKey.size;
-- pubEndorsementKey->pubKey.keyLength = key_length >> 3;
-+ pubEndorsementKey->pubKey.keyLength = tpmData.permanent.data.endorsementKey.size >> 3;
- pubEndorsementKey->pubKey.key = tpm_malloc(pubEndorsementKey->pubKey.keyLength);
- if (pubEndorsementKey->pubKey.key == NULL) return TPM_FAIL;
- rsa_export_modulus(&tpmData.permanent.data.endorsementKey,
-- pubEndorsementKey->pubKey.key,
-- &pubEndorsementKey->pubKey.keyLength);
-+ pubEndorsementKey->pubKey.key,
-+ &key_length);
-+ pubEndorsementKey->pubKey.keyLength = key_length;
- pubEndorsementKey->algorithmParms.algorithmID = TPM_ALG_RSA;
- pubEndorsementKey->algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
- pubEndorsementKey->algorithmParms.sigScheme = TPM_SS_NONE;
-@@ -169,6 +169,7 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_
- {
- TPM_RESULT res;
- TPM_KEY_DATA *srk = &tpmData.permanent.data.srk;
-+ size_t key_length;
- info("TPM_OwnerReadInternalPub()");
- /* verify authorization */
- res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
-@@ -180,7 +181,8 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_
- publicPortion->pubKey.key = tpm_malloc(publicPortion->pubKey.keyLength);
- if (publicPortion->pubKey.key == NULL) return TPM_FAIL;
- rsa_export_modulus(&srk->key, publicPortion->pubKey.key,
-- &publicPortion->pubKey.keyLength);
-+ &key_length);
-+ publicPortion->pubKey.keyLength = key_length;
- publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA;
- publicPortion->algorithmParms.encScheme = srk->encScheme;
- publicPortion->algorithmParms.sigScheme = srk->sigScheme;
-diff -uprN tpm_emulator-0.2/tpm/tpm_crypto.c tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c
---- tpm_emulator-0.2/tpm/tpm_crypto.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2005-09-19 14:10:29.000000000 -0700
-@@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
- TPM_KEY_DATA *cert, *key;
- sha1_ctx_t sha1_ctx;
- BYTE *buf, *p;
-- UINT32 length;
-+ UINT32 length32;
-+ size_t length;
- info("TPM_CertifyKey()");
- /* get keys */
- cert = tpm_get_key(certHandle);
-@@ -264,14 +265,15 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
- /* compute the digest of the CERTIFY_INFO[2] structure and sign it */
- length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
- p = buf = tpm_malloc(length);
-+ length32=(UINT32) length;
- if (buf == NULL
-- || tpm_marshal_TPM_CERTIFY_INFO(&p, &length, certifyInfo)) {
-+ || tpm_marshal_TPM_CERTIFY_INFO(&p, &length32, certifyInfo)) {
- free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
- return TPM_FAIL;
- }
- length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
- sha1_init(&sha1_ctx);
-- sha1_update(&sha1_ctx, buf, length);
-+ sha1_update(&sha1_ctx, buf, (size_t) length);
- sha1_final(&sha1_ctx, buf);
- res = tpm_sign(cert, auth1, FALSE, buf, SHA1_DIGEST_LENGTH, outData, outDataSize);
- tpm_free(buf);
-@@ -292,7 +294,8 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
- TPM_KEY_DATA *cert, *key;
- sha1_ctx_t sha1_ctx;
- BYTE *buf, *p;
-- UINT32 length;
-+ size_t length;
-+ UINT32 length32;
- info("TPM_CertifyKey2()");
- /* get keys */
- cert = tpm_get_key(certHandle);
-@@ -362,8 +365,9 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
- /* compute the digest of the CERTIFY_INFO[2] structure and sign it */
- length = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
- p = buf = tpm_malloc(length);
-+ length32 = (UINT32) length;
- if (buf == NULL
-- || tpm_marshal_TPM_CERTIFY_INFO(&p, &length, certifyInfo)) {
-+ || tpm_marshal_TPM_CERTIFY_INFO(&p, &length32, certifyInfo)) {
- free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
- return TPM_FAIL;
- }
-diff -uprN tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2-x86_64/tpm/tpm_data.c
---- tpm_emulator-0.2/tpm/tpm_data.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-19 14:10:29.000000000 -0700
-@@ -179,7 +179,7 @@ static int read_from_file(uint8_t **data
- int tpm_store_permanent_data(void)
- {
- uint8_t *buf, *ptr;
-- size_t buf_length, len;
-+ UINT32 buf_length, len;
-
- /* marshal data */
- buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
-@@ -207,13 +207,14 @@ int tpm_store_permanent_data(void)
- int tpm_restore_permanent_data(void)
- {
- uint8_t *buf, *ptr;
-- size_t buf_length, len;
-+ size_t buf_length;
-+ UINT32 len;
- TPM_VERSION ver;
-
- /* read data */
- if (read_from_file(&buf, &buf_length)) return -1;
- ptr = buf;
-- len = buf_length;
-+ len = (uint32_t) buf_length;
- /* unmarshal data */
- if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
- || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
-diff -uprN tpm_emulator-0.2/tpm/tpm_marshalling.c tpm_emulator-0.2-x86_64/tpm/tpm_marshalling.c
---- tpm_emulator-0.2/tpm/tpm_marshalling.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_marshalling.c 2005-09-19 14:10:29.000000000 -0700
-@@ -981,7 +981,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE *
-
- int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v)
- {
-- UINT32 m_len, e_len, q_len;
-+ size_t m_len, e_len, q_len;
- if (*length < sizeof_RSA((*v))) return -1;
- if (v->size > 0) {
- rsa_export_modulus(v, &(*ptr)[6], &m_len);
-diff -uprN tpm_emulator-0.2/tpm/tpm_owner.c tpm_emulator-0.2-x86_64/tpm/tpm_owner.c
---- tpm_emulator-0.2/tpm/tpm_owner.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_owner.c 2005-09-19 14:10:29.000000000 -0700
-@@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
- TPM_RESULT res;
- rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
- TPM_KEY_DATA *srk = &tpmData.permanent.data.srk;
-- UINT32 buf_size = ek->size >> 3;
-+ size_t buf_size = ek->size >> 3, key_length;
- BYTE buf[buf_size];
-
- info("TPM_TakeOwnership()");
-@@ -172,7 +172,8 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
- return TPM_FAIL;
- }
- rsa_export_modulus(&srk->key, srkPub->pubKey.key,
-- &srkPub->pubKey.keyLength);
-+ &key_length);
-+ srkPub->pubKey.keyLength = (UINT32) key_length;
- /* setup tpmProof and set state to owned */
- tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce,
- sizeof(tpmData.permanent.data.tpmProof.nonce));
-diff -uprN tpm_emulator-0.2/tpm/tpm_storage.c tpm_emulator-0.2-x86_64/tpm/tpm_storage.c
---- tpm_emulator-0.2/tpm/tpm_storage.c 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm/tpm_storage.c 2005-09-19 14:10:29.000000000 -0700
-@@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
- BYTE *enc, UINT32 *enc_size)
- {
- UINT32 len;
-+ size_t enc_size32 = *enc_size;
- BYTE *buf, *ptr;
- rsa_public_key_t pub_key;
- int scheme;
-@@ -72,7 +73,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
- if (buf == NULL
- || tpm_marshal_TPM_SEALED_DATA(&ptr, &len, seal)
- || rsa_encrypt(&pub_key, scheme, buf, sizeof_TPM_SEALED_DATA((*seal)),
-- enc, enc_size)) {
-+ enc, &enc_size32)) {
- tpm_free(buf);
- rsa_release_public_key(&pub_key);
- return -1;
-@@ -85,7 +86,8 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
- int decrypt_sealed_data(TPM_KEY_DATA *key, BYTE *enc, UINT32 enc_size,
- TPM_SEALED_DATA *seal, BYTE **buf)
- {
-- UINT32 len;
-+ size_t len;
-+ UINT32 len32;
- BYTE *ptr;
- int scheme;
- switch (key->encScheme) {
-@@ -96,8 +98,12 @@ int decrypt_sealed_data(TPM_KEY_DATA *ke
- len = enc_size;
- *buf = ptr = tpm_malloc(len);
- if (*buf == NULL
-- || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len)
-- || tpm_unmarshal_TPM_SEALED_DATA(&ptr, &len, seal)) {
-+ || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len) ){
-+ tpm_free(*buf);
-+ return -1;
-+ }
-+ len32 = len;
-+ if (tpm_unmarshal_TPM_SEALED_DATA(&ptr, &len32, seal)) {
- tpm_free(*buf);
- return -1;
- }
-@@ -237,11 +243,12 @@ TPM_RESULT TPM_Unseal(TPM_KEY_HANDLE par
-
- TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE keyHandle, UINT32 inDataSize,
- BYTE *inData, TPM_AUTH *auth1,
-- UINT32 *outDataSize, BYTE **outData)
-+ UINT32 *outDataSize32, BYTE **outData)
- {
- TPM_RESULT res;
- TPM_KEY_DATA *key;
- int scheme;
-+ size_t outDataSize;
- info("TPM_UnBind()");
- /* get key */
- key = tpm_get_key(keyHandle);
-@@ -258,8 +265,8 @@ TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE key
- /* the size of the input data muss be greater than zero */
- if (inDataSize == 0) return TPM_BAD_PARAMETER;
- /* decrypt data */
-- *outDataSize = inDataSize;
-- *outData = tpm_malloc(*outDataSize);
-+ outDataSize = inDataSize;
-+ *outData = tpm_malloc(outDataSize);
- if (*outData == NULL) return TPM_FAIL;
- switch (key->encScheme) {
- case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
-@@ -267,20 +274,21 @@ TPM_RESULT TPM_UnBind(TPM_KEY_HANDLE key
- default: tpm_free(*outData); return TPM_DECRYPT_ERROR;
- }
- if (rsa_decrypt(&key->key, scheme, inData, inDataSize,
-- *outData, outDataSize)) {
-+ *outData, &outDataSize) ) {
- tpm_free(*outData);
- return TPM_DECRYPT_ERROR;
- }
- /* verify data if it is of type TPM_BOUND_DATA */
- if (key->encScheme == TPM_ES_RSAESOAEP_SHA1_MGF1
- || key->keyUsage != TPM_KEY_LEGACY) {
-- if (*outDataSize < 5 || memcmp(*outData, "\x01\x01\00\x00\x02", 5) != 0) {
-+ if (outDataSize < 5 || memcmp(*outData, "\x01\x01\00\x00\x02", 5) != 0) {
- tpm_free(*outData);
- return TPM_DECRYPT_ERROR;
- }
-- *outDataSize -= 5;
-- memmove(*outData, &(*outData)[5], *outDataSize);
-- }
-+ outDataSize -= 5;
-+ memmove(*outData, &(*outData)[5], outDataSize);
-+ }
-+ *outDataSize32 = (UINT32) outDataSize;
- return TPM_SUCCESS;
- }
-
-@@ -311,12 +319,13 @@ static int verify_key_digest(TPM_KEY *ke
- }
-
- int encrypt_private_key(TPM_KEY_DATA *key, TPM_STORE_ASYMKEY *store,
-- BYTE *enc, UINT32 *enc_size)
-+ BYTE *enc, UINT32 *enc_size32)
- {
- UINT32 len;
- BYTE *buf, *ptr;
- rsa_public_key_t pub_key;
- int scheme;
-+ size_t enc_size;
- switch (key->encScheme) {
- case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
- case TPM_ES_RSAESPKCSv15: scheme = RSA_ES_PKCSV15; break;
-@@ -328,11 +337,12 @@ int encrypt_private_key(TPM_KEY_DATA *ke
- if (buf == NULL
- || tpm_marshal_TPM_STORE_ASYMKEY(&ptr, &len, store)
- || rsa_encrypt(&pub_key, scheme, buf, sizeof_TPM_STORE_ASYMKEY((*store)),
-- enc, enc_size)) {
-+ enc, &enc_size)) {
- tpm_free(buf);
- rsa_release_public_key(&pub_key);
- return -1;
- }
-+ *enc_size32 = (UINT32) enc_size;
- tpm_free(buf);
- rsa_release_public_key(&pub_key);
- return 0;
-@@ -341,7 +351,8 @@ int encrypt_private_key(TPM_KEY_DATA *ke
- int decrypt_private_key(TPM_KEY_DATA *key, BYTE *enc, UINT32 enc_size,
- TPM_STORE_ASYMKEY *store, BYTE **buf)
- {
-- UINT32 len;
-+ UINT32 len32;
-+ size_t len;
- BYTE *ptr;
- int scheme;
- switch (key->encScheme) {
-@@ -352,11 +363,16 @@ int decrypt_private_key(TPM_KEY_DATA *ke
- len = enc_size;
- *buf = ptr = tpm_malloc(len);
- if (*buf == NULL
-- || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len)
-- || tpm_unmarshal_TPM_STORE_ASYMKEY(&ptr, &len, store)) {
-+ || rsa_decrypt(&key->key, scheme, enc, enc_size, *buf, &len) ) {
-+ tpm_free(*buf);
-+ return -1;
-+ }
-+ len32 = (UINT32) len;
-+ if (tpm_unmarshal_TPM_STORE_ASYMKEY(&ptr, &len32, store)) {
- tpm_free(*buf);
- return -1;
- }
-+
- return 0;
- }
-
-@@ -371,7 +387,7 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
- TPM_SESSION_DATA *session;
- TPM_STORE_ASYMKEY store;
- rsa_private_key_t rsa;
-- UINT32 key_length;
-+ size_t key_length;
-
- info("TPM_CreateWrapKey()");
- /* get parent key */
-@@ -428,11 +444,11 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
- }
- if (compute_key_digest(wrappedKey, &store.pubDataDigest)) return TPM_FAIL;
- /* generate key and store it */
-- key_length = keyInfo->algorithmParms.parms.rsa.keyLength;
-- if (rsa_generate_key(&rsa, key_length)) return TPM_FAIL;
-- wrappedKey->pubKey.keyLength = key_length >> 3;
-+ if (rsa_generate_key(&rsa, keyInfo->algorithmParms.parms.rsa.keyLength))
-+ return TPM_FAIL;
-+ wrappedKey->pubKey.keyLength = keyInfo->algorithmParms.parms.rsa.keyLength >> 3;
- wrappedKey->pubKey.key = tpm_malloc(wrappedKey->pubKey.keyLength);
-- store.privKey.keyLength = key_length >> 4;
-+ store.privKey.keyLength = keyInfo->algorithmParms.parms.rsa.keyLength >> 4;
- store.privKey.key = tpm_malloc(store.privKey.keyLength);
- wrappedKey->encDataSize = parent->key.size >> 3;
- wrappedKey->encData = tpm_malloc(wrappedKey->encDataSize);
-@@ -444,9 +460,11 @@ TPM_RESULT TPM_CreateWrapKey(TPM_KEY_HAN
- tpm_free(wrappedKey->encData);
- return TPM_FAIL;
- }
-- rsa_export_modulus(&rsa, wrappedKey->pubKey.key,
-- &wrappedKey->pubKey.keyLength);
-- rsa_export_prime1(&rsa, store.privKey.key, &store.privKey.keyLength);
-+ rsa_export_modulus(&rsa, wrappedKey->pubKey.key,
-+ &key_length);
-+ wrappedKey->pubKey.keyLength = (UINT32) key_length;
-+ rsa_export_prime1(&rsa, store.privKey.key, &key_length);
-+ store.privKey.keyLength = (UINT32) key_length;
- rsa_release_private_key(&rsa);
- /* encrypt private key data */
- if (encrypt_private_key(parent, &store, wrappedKey->encData,
-@@ -560,6 +578,7 @@ TPM_RESULT TPM_LoadKey(TPM_KEY_HANDLE pa
-
- int tpm_setup_key_parms(TPM_KEY_DATA *key, TPM_KEY_PARMS *parms)
- {
-+ size_t key_length;
- parms->algorithmID = TPM_ALG_RSA;
- parms->encScheme = key->encScheme;
- parms->sigScheme = key->sigScheme;
-@@ -569,7 +588,8 @@ int tpm_setup_key_parms(TPM_KEY_DATA *ke
- parms->parms.rsa.exponent = tpm_malloc(parms->parms.rsa.exponentSize);
- if (parms->parms.rsa.exponent == NULL) return -1;
- rsa_export_exponent(&key->key, parms->parms.rsa.exponent,
-- &parms->parms.rsa.exponentSize);
-+ &key_length);
-+ parms->parms.rsa.exponentSize = (UINT32) key_length;
- parms->parmSize = 12 + parms->parms.rsa.exponentSize;
- return 0;
- }
-@@ -580,6 +600,7 @@ TPM_RESULT TPM_GetPubKey(TPM_KEY_HANDLE
- TPM_RESULT res;
- TPM_KEY_DATA *key;
- TPM_DIGEST digest;
-+ size_t key_length;
- info("TPM_GetPubKey()");
- /* get key */
- if (keyHandle == TPM_KH_SRK) return TPM_BAD_PARAMETER;
-@@ -607,8 +628,8 @@ TPM_RESULT TPM_GetPubKey(TPM_KEY_HANDLE
- pubKey->pubKey.keyLength = key->key.size >> 3;
- pubKey->pubKey.key = tpm_malloc(pubKey->pubKey.keyLength);
- if (pubKey->pubKey.key == NULL) return TPM_FAIL;
-- rsa_export_modulus(&key->key, pubKey->pubKey.key,
-- &pubKey->pubKey.keyLength);
-+ rsa_export_modulus(&key->key, pubKey->pubKey.key, &key_length);
-+ pubKey->pubKey.keyLength = (UINT32) key_length;
- if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) {
- tpm_free(pubKey->pubKey.key);
- return TPM_FAIL;
-diff -uprN tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2-x86_64/tpm_version.h
---- tpm_emulator-0.2/tpm_version.h 2005-08-15 00:58:57.000000000 -0700
-+++ tpm_emulator-0.2-x86_64/tpm_version.h 1969-12-31 16:00:00.000000000 -0800
-@@ -1,6 +0,0 @@
--#ifndef _TPM_VERSION_H_
--#define _TPM_VERSION_H_
--#define VERSION_MAJOR 0
--#define VERSION_MINOR 2
--#define VERSION_BUILD 1123950310
--#endif /* _TPM_VERSION_H_ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog