[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxx # 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 = ¤t->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@xxxxxxxxxxxxxx> - * Dave Safford <safford@xxxxxxxxxxxxxx> - * Reiner Sailer <sailer@xxxxxxxxxxxxxx> - * Kylene Hall <kjhall@xxxxxxxxxx> - * Stefan Berger <stefanb@xxxxxxxxxx> + * Author: Stefan Berger, stefanb@xxxxxxxxxx + * Grant table support: Mahadevan Gomathisankaran * - * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx> + * 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@xxxxxxxxxx)"); -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@xxxxxx> -# 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@xxxxxxxxxx> # +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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> -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@xxxxxxxxxx> 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@xxxxxxxxxx> 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@xxxxxxxxxx> 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@xxxxxxxxxx> 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@xxxxxxxxxx) @@ -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@xxxxxxxxxx> 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, ®s->rflags); - __vmread(GUEST_SS_SELECTOR, ®s->ss); - __vmread(GUEST_CS_SELECTOR, ®s->cs); - __vmread(GUEST_DS_SELECTOR, ®s->ds); - __vmread(GUEST_ES_SELECTOR, ®s->es); - __vmread(GUEST_GS_SELECTOR, ®s->gs); - __vmread(GUEST_FS_SELECTOR, ®s->fs); - __vmread(GUEST_RIP, ®s->rip); - __vmread(GUEST_RSP, ®s->rsp); -#elif defined (__i386__) __vmread(GUEST_RFLAGS, ®s->eflags); __vmread(GUEST_SS_SELECTOR, ®s->ss); __vmread(GUEST_CS_SELECTOR, ®s->cs); @@ -472,7 +461,6 @@ static void vmx_store_cpu_guest_regs( __vmread(GUEST_FS_SELECTOR, ®s->fs); __vmread(GUEST_RIP, ®s->eip); __vmread(GUEST_RSP, ®s->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@xxxxxxxxxx> + * + * 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@xxxxxxxxxxxxxx> + */ + +#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@xxxxxxxxxxxxxx> + */ + +#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@xxxxxxxxxxxxxx> + */ + +#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@xxxxxxxxxxxxxx> + */ + +#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@xxxxxxxxxxxxxxxxx> + * ++ * 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@xxxxxxxxxxxxxxxxx> + * ++ * 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@xxxxxxxxxxxxxxxxx> ++ * ++ * 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@xxxxxxxxxxxxxxxxx> ++ * ++ * 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@xxxxxxxxxxxxxx> + * Stefan Berger <stefanb@xxxxxxxxxxxxxx> + * + * 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@xxxxxxxxxx> + Daniel Stekloff <dsteklof@xxxxxxxxxx> + + 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@xxxxxxxxxx> + Daniel Stekloff <dsteklof@xxxxxxxxxx> + + 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@xxxxxxxxxxxxx> + +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@xxxxxxxxxx - * 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@xxxxxxxxxxxx> ---- - 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@xxxxxxxxxxxxxxxxx> - * -+ * 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@xxxxxxxxxxxxxxxxx> - * -+ * 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@xxxxxxxxxxxxxxxxx> -+ * -+ * 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@xxxxxxxxxxxxxxxxx> -+ * -+ * 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@xxxxxxxxxx> - * Judy Fischbach <jfisch@xxxxxxxxxx> - * - * 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@xxxxxxxxxx> - * Judy Fischbach <jfisch@xxxxxxxxxx> - * - * 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@xxxxxxxxxx> - - 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@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |