[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxxx # Date 1173296308 25200 # Node ID 50d5bf02e59e47735d563cf95d792dd14bc30939 # Parent 8a58ea36e4207e6d47f8870632ab8fe14e3622cb # Parent 8117f668499171a4a0ea5486228fa597902b4af0 merge with xen-unstable.hg --- linux-2.6-xen-sparse/arch/i386/kernel/alternative-xen.c | 389 -- linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c | 774 ----- linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c | 60 linux-2.6-xen-sparse/mm/Kconfig | 157 - tools/ptsname/Makefile | 22 tools/ptsname/ptsname.c | 44 tools/ptsname/setup.py | 11 Config.mk | 7 README | 2 config/StdGNU.mk | 6 config/SunOS.mk | 6 docs/misc/dump-core-format.txt | 231 + docs/xen-api/xenapi-datamodel.tex | 1463 +++++++--- extras/mini-os/Makefile | 3 extras/mini-os/arch/ia64/mm.c | 4 extras/mini-os/arch/x86/Makefile | 1 extras/mini-os/arch/x86/arch.mk | 10 extras/mini-os/arch/x86/mm.c | 43 extras/mini-os/include/mm.h | 1 extras/mini-os/mm.c | 2 linux-2.6-xen-sparse/arch/i386/Kconfig | 6 linux-2.6-xen-sparse/arch/i386/Kconfig.cpu | 4 linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S | 59 linux-2.6-xen-sparse/arch/i386/kernel/fixup.c | 1 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S | 9 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c | 10 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 3 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 13 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c | 1 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c | 4 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c | 61 linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h | 2 linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S | 1 linux-2.6-xen-sparse/arch/ia64/xen/mem.c | 1 linux-2.6-xen-sparse/arch/ia64/xen/util.c | 1 linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c | 1 linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S | 2 linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S | 2 linux-2.6-xen-sparse/arch/ia64/xen/xenminstate.h | 2 linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S | 1 linux-2.6-xen-sparse/arch/x86_64/Kconfig | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c | 1 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S | 83 linux-2.6-xen-sparse/arch/x86_64/kernel/genapic_xen.c | 1 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S | 26 linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c | 2 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 6 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 27 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 218 - linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c | 11 linux-2.6-xen-sparse/drivers/char/mem.c | 2 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 192 - linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 1 linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c | 1 linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 1 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h | 1 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 2 linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 1 linux-2.6-xen-sparse/drivers/xen/char/mem.c | 3 linux-2.6-xen-sparse/drivers/xen/console/console.c | 1 linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c | 38 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 122 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 12 linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c | 1 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c | 173 - linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 18 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 12 linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c | 1 linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c | 1 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 3 linux-2.6-xen-sparse/drivers/xen/netback/common.h | 16 linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 18 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 1 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 21 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 4 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 65 linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c | 11 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 3 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 5 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 2 linux-2.6-xen-sparse/drivers/xen/util.c | 1 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c | 27 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h | 2 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c | 55 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 103 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h | 1 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h | 5 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h | 21 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h | 2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h | 2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h | 2 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 1 linux-2.6-xen-sparse/include/asm-ia64/swiotlb.h | 2 linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h | 2 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h | 5 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h | 6 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irq.h | 1 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h | 13 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h | 2 linux-2.6-xen-sparse/include/linux/page-flags.h | 6 linux-2.6-xen-sparse/include/xen/cpu_hotplug.h | 14 linux-2.6-xen-sparse/include/xen/driver_util.h | 1 linux-2.6-xen-sparse/include/xen/evtchn.h | 1 linux-2.6-xen-sparse/include/xen/gnttab.h | 1 linux-2.6-xen-sparse/include/xen/pcifront.h | 1 linux-2.6-xen-sparse/include/xen/xen_proc.h | 1 patches/linux-2.6.18/blktap-aio-16_03_06.patch | 5 tools/Makefile | 9 tools/blktap/drivers/blktapctrl.c | 2 tools/blktap/drivers/block-aio.c | 33 tools/blktap/drivers/block-qcow.c | 87 tools/blktap/drivers/block-ram.c | 28 tools/blktap/drivers/block-sync.c | 28 tools/blktap/drivers/block-vmdk.c | 29 tools/blktap/drivers/img2qcow.c | 2 tools/blktap/drivers/qcow2raw.c | 4 tools/blktap/drivers/tapdisk.c | 255 + tools/blktap/drivers/tapdisk.h | 45 tools/blktap/lib/Makefile | 4 tools/blktap/lib/blktaplib.h | 1 tools/blktap/lib/xenbus.c | 7 tools/console/Makefile | 4 tools/examples/init.d/xendomains | 31 tools/firmware/hvmloader/acpi/dsdt.asl | 18 tools/firmware/hvmloader/acpi/dsdt.c | 23 tools/firmware/hvmloader/config.h | 2 tools/firmware/rombios/rombios.c | 288 - tools/guest-headers/Makefile | 2 tools/ioemu/Makefile | 8 tools/ioemu/hw/ide.c | 125 tools/ioemu/target-i386-dm/qemu-ifup | 3 tools/ioemu/vl.c | 99 tools/ioemu/vnc.c | 8 tools/ioemu/xenstore.c | 51 tools/libxc/Makefile | 5 tools/libxc/ia64/xc_ia64_hvm_build.c | 14 tools/libxc/powerpc64/mk_flatdevtree.c | 2 tools/libxc/powerpc64/xc_linux_build.c | 103 tools/libxc/xc_core.c | 774 ++++- tools/libxc/xc_core.h | 165 + tools/libxc/xc_core_ia64.c | 315 ++ tools/libxc/xc_core_ia64.h | 60 tools/libxc/xc_core_x86.c | 136 tools/libxc/xc_core_x86.h | 64 tools/libxc/xc_dom.h | 44 tools/libxc/xc_dom_binloader.c | 73 tools/libxc/xc_dom_boot.c | 458 +-- tools/libxc/xc_dom_compat_linux.c | 150 - tools/libxc/xc_dom_core.c | 650 ++-- tools/libxc/xc_dom_elfloader.c | 349 +- tools/libxc/xc_dom_ia64.c | 50 tools/libxc/xc_dom_x86.c | 429 +- tools/libxc/xc_domain.c | 15 tools/libxc/xc_efi.h | 68 tools/libxc/xc_hvm_build.c | 31 tools/libxc/xc_hvm_restore.c | 27 tools/libxc/xc_hvm_save.c | 52 tools/libxc/xc_linux.c | 35 tools/libxc/xc_linux_restore.c | 221 + tools/libxc/xc_linux_save.c | 160 - tools/libxc/xc_private.c | 2 tools/libxc/xc_private.h | 10 tools/libxc/xc_ptrace_core.c | 601 +++- tools/libxc/xc_resume.c | 8 tools/libxc/xc_solaris.c | 6 tools/libxc/xenctrl.h | 23 tools/libxc/xenguest.h | 14 tools/libxc/xg_private.c | 116 tools/libxc/xg_private.h | 17 tools/libxc/xg_save_restore.h | 21 tools/libxen/Makefile | 4 tools/libxen/include/xen_console.h | 7 tools/libxen/include/xen_host.h | 40 tools/libxen/include/xen_host_cpu.h | 43 tools/libxen/include/xen_host_metrics.h | 18 tools/libxen/include/xen_network.h | 36 tools/libxen/include/xen_pbd.h | 9 tools/libxen/include/xen_pif.h | 9 tools/libxen/include/xen_pif_metrics.h | 18 tools/libxen/include/xen_vbd.h | 40 tools/libxen/include/xen_vbd_metrics.h | 7 tools/libxen/include/xen_vdi.h | 7 tools/libxen/include/xen_vif.h | 40 tools/libxen/include/xen_vif_metrics.h | 7 tools/libxen/include/xen_vm.h | 44 tools/libxen/include/xen_vm_guest_metrics.h | 226 + tools/libxen/include/xen_vm_guest_metrics_decl.h | 30 tools/libxen/include/xen_vm_metrics.h | 7 tools/libxen/src/xen_console.c | 12 tools/libxen/src/xen_host.c | 101 tools/libxen/src/xen_host_cpu.c | 87 tools/libxen/src/xen_host_metrics.c | 36 tools/libxen/src/xen_network.c | 78 tools/libxen/src/xen_pbd.c | 14 tools/libxen/src/xen_pif.c | 14 tools/libxen/src/xen_pif_metrics.c | 36 tools/libxen/src/xen_vbd.c | 92 tools/libxen/src/xen_vbd_metrics.c | 12 tools/libxen/src/xen_vdi.c | 12 tools/libxen/src/xen_vif.c | 92 tools/libxen/src/xen_vif_metrics.c | 12 tools/libxen/src/xen_vm.c | 109 tools/libxen/src/xen_vm_guest_metrics.c | 251 + tools/libxen/src/xen_vm_metrics.c | 12 tools/libxen/test/test_bindings.c | 24 tools/misc/sxp-pretty | 45 tools/pygrub/Makefile | 7 tools/python/Makefile | 3 tools/python/ptsname/ptsname.c | 44 tools/python/scripts/test_vm_create.py | 2 tools/python/scripts/xapi.py | 4 tools/python/scripts/xapi.vdicfg.py | 2 tools/python/setup.py | 9 tools/python/xen/lowlevel/xc/xc.c | 103 tools/python/xen/util/xmlrpclib2.py | 7 tools/python/xen/xend/XendAPI.py | 161 - tools/python/xen/xend/XendAPIVersion.py | 22 tools/python/xen/xend/XendBootloader.py | 3 tools/python/xen/xend/XendCheckpoint.py | 37 tools/python/xen/xend/XendConfig.py | 34 tools/python/xen/xend/XendConstants.py | 10 tools/python/xen/xend/XendDomain.py | 52 tools/python/xen/xend/XendDomainInfo.py | 74 tools/python/xen/xend/XendNetwork.py | 46 tools/python/xen/xend/XendNode.py | 98 tools/python/xen/xend/XendQCoWStorageRepo.py | 2 tools/python/xen/xend/image.py | 4 tools/python/xen/xend/server/SrvDomainDir.py | 2 tools/python/xen/xend/server/XMLRPCServer.py | 2 tools/python/xen/xm/main.py | 76 tools/security/Makefile | 35 tools/vnet/libxutil/Makefile | 2 tools/xcutils/readnotes.c | 30 tools/xenfb/Makefile | 9 tools/xenfb/xenfb.c | 5 tools/xenstat/libxenstat/Makefile | 31 tools/xenstat/libxenstat/src/xenstat.c | 289 - tools/xenstat/libxenstat/src/xenstat.h | 5 tools/xenstat/libxenstat/src/xenstat_linux.c | 265 + tools/xenstat/libxenstat/src/xenstat_priv.h | 101 tools/xenstat/libxenstat/src/xenstat_solaris.c | 431 ++ tools/xenstat/xentop/xentop.c | 22 tools/xenstore/Makefile | 12 tools/xenstore/xenstored_domain.c | 51 tools/xenstore/xenstored_transaction.c | 16 tools/xenstore/xenstored_transaction.h | 3 tools/xenstore/xenstored_watch.c | 11 tools/xenstore/xenstored_watch.h | 2 tools/xentrace/formats | 76 tools/xentrace/xentrace.8 | 54 tools/xentrace/xentrace.c | 29 tools/xentrace/xentrace_format | 7 tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py | 18 unmodified_drivers/linux-2.6/overrides.mk | 2 unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 1 unmodified_drivers/linux-2.6/platform-pci/platform-compat.c | 1 xen/Rules.mk | 8 xen/acm/acm_core.c | 8 xen/acm/acm_simple_type_enforcement_hooks.c | 125 xen/arch/ia64/vmx/mmio.c | 53 xen/arch/ia64/vmx/vlsapic.c | 20 xen/arch/ia64/vmx/vmx_hypercall.c | 3 xen/arch/ia64/vmx/vmx_init.c | 2 xen/arch/ia64/vmx/vmx_process.c | 8 xen/arch/ia64/xen/dom0_ops.c | 40 xen/arch/ia64/xen/mm.c | 17 xen/arch/powerpc/Makefile | 1 xen/arch/powerpc/boot_of.c | 7 xen/arch/powerpc/domain.c | 6 xen/arch/powerpc/domain_build.c | 123 xen/arch/powerpc/domctl.c | 22 xen/arch/powerpc/exceptions.c | 19 xen/arch/powerpc/iommu.c | 3 xen/arch/powerpc/memory.c | 1 xen/arch/powerpc/mm.c | 275 + xen/arch/powerpc/ofd_fixup.c | 27 xen/arch/powerpc/ofd_fixup_memory.c | 37 xen/arch/powerpc/oftree.h | 3 xen/arch/powerpc/papr/xlate.c | 3 xen/arch/powerpc/platform.c | 43 xen/arch/powerpc/powerpc64/ppc970.c | 12 xen/arch/powerpc/setup.c | 7 xen/arch/powerpc/time.c | 2 xen/arch/x86/crash.c | 2 xen/arch/x86/domain.c | 81 xen/arch/x86/domain_build.c | 23 xen/arch/x86/domctl.c | 51 xen/arch/x86/hvm/hvm.c | 49 xen/arch/x86/hvm/io.c | 11 xen/arch/x86/hvm/svm/emulate.c | 22 xen/arch/x86/hvm/svm/intr.c | 7 xen/arch/x86/hvm/svm/svm.c | 348 +- xen/arch/x86/hvm/vmx/intr.c | 3 xen/arch/x86/hvm/vmx/vmx.c | 158 - xen/arch/x86/mm.c | 189 - xen/arch/x86/mm/p2m.c | 4 xen/arch/x86/mm/shadow/common.c | 77 xen/arch/x86/mm/shadow/multi.c | 77 xen/arch/x86/mm/shadow/private.h | 7 xen/arch/x86/setup.c | 13 xen/arch/x86/smp.c | 2 xen/arch/x86/x86_32/mm.c | 25 xen/arch/x86/x86_64/mm.c | 39 xen/common/acm_ops.c | 46 xen/common/domain.c | 7 xen/common/domctl.c | 83 xen/common/event_channel.c | 18 xen/common/grant_table.c | 79 xen/common/libelf/libelf-dominfo.c | 8 xen/common/memory.c | 28 xen/common/page_alloc.c | 580 ++- xen/common/schedule.c | 4 xen/common/sysctl.c | 7 xen/common/trace.c | 2 xen/drivers/acpi/numa.c | 9 xen/include/acm/acm_hooks.h | 6 xen/include/asm-ia64/config.h | 2 xen/include/asm-ia64/mm.h | 2 xen/include/asm-ia64/shadow.h | 2 xen/include/asm-ia64/vmx.h | 2 xen/include/asm-ia64/vmx_platform.h | 5 xen/include/asm-ia64/vmx_vpd.h | 1 xen/include/asm-powerpc/config.h | 9 xen/include/asm-powerpc/domain.h | 13 xen/include/asm-powerpc/grant_table.h | 4 xen/include/asm-powerpc/mm.h | 33 xen/include/asm-powerpc/platform.h | 28 xen/include/asm-powerpc/processor.h | 1 xen/include/asm-powerpc/shadow.h | 7 xen/include/asm-powerpc/time.h | 2 xen/include/asm-x86/config.h | 2 xen/include/asm-x86/domain.h | 3 xen/include/asm-x86/hvm/hvm.h | 21 xen/include/asm-x86/hvm/support.h | 6 xen/include/asm-x86/hvm/svm/emulate.h | 10 xen/include/asm-x86/hvm/svm/svm.h | 35 xen/include/asm-x86/hvm/svm/vmcb.h | 16 xen/include/asm-x86/hvm/trace.h | 44 xen/include/asm-x86/hvm/vcpu.h | 2 xen/include/asm-x86/hvm/vmx/vmx.h | 6 xen/include/asm-x86/mm.h | 5 xen/include/asm-x86/page.h | 4 xen/include/asm-x86/perfc_defn.h | 1 xen/include/asm-x86/shadow.h | 7 xen/include/asm-x86/x86_64/page.h | 2 xen/include/public/arch-ia64.h | 9 xen/include/public/arch-powerpc.h | 8 xen/include/public/arch-x86/xen.h | 1 xen/include/public/domctl.h | 30 xen/include/public/elfnote.h | 45 xen/include/public/hvm/ioreq.h | 20 xen/include/public/libelf.h | 19 xen/include/public/trace.h | 35 xen/include/public/xen.h | 18 xen/include/xen/grant_table.h | 26 xen/include/xen/mm.h | 29 xen/include/xen/perfc.h | 1 xen/include/xen/sched.h | 33 359 files changed, 11928 insertions(+), 6782 deletions(-) diff -r 8a58ea36e420 -r 50d5bf02e59e Config.mk --- a/Config.mk Thu Mar 01 15:02:09 2007 -0700 +++ b/Config.mk Wed Mar 07 12:38:28 2007 -0700 @@ -73,9 +73,10 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY # Optional components -XENSTAT_XENTOP ?= y -VTPM_TOOLS ?= n +XENSTAT_XENTOP ?= y +VTPM_TOOLS ?= n LIBXENAPI_BINDINGS ?= n -XENFB_TOOLS ?= n +XENFB_TOOLS ?= n +PYTHON_TOOLS ?= y -include $(XEN_ROOT)/.config diff -r 8a58ea36e420 -r 50d5bf02e59e README --- a/README Thu Mar 01 15:02:09 2007 -0700 +++ b/README Wed Mar 07 12:38:28 2007 -0700 @@ -92,6 +92,8 @@ provided by your Linux distributor: * Development install of zlib (e.g., zlib-dev) * Development install of Python v2.3 or later (e.g., python-dev) * Development install of curses (e.g., libncurses-dev) + * Development install of openssl (e.g., openssl-dev) + * Development install of x11 (e.g. xorg-x11-dev) * bridge-utils package (/sbin/brctl) * iproute package (/sbin/ip) * hotplug or udev diff -r 8a58ea36e420 -r 50d5bf02e59e config/StdGNU.mk --- a/config/StdGNU.mk Thu Mar 01 15:02:09 2007 -0700 +++ b/config/StdGNU.mk Wed Mar 07 12:38:28 2007 -0700 @@ -12,9 +12,9 @@ MSGFMT = msgfmt MSGFMT = msgfmt INSTALL = install -INSTALL_DIR = $(INSTALL) -d -m0755 -INSTALL_DATA = $(INSTALL) -m0644 -INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 -p +INSTALL_DATA = $(INSTALL) -m0644 -p +INSTALL_PROG = $(INSTALL) -m0755 -p LIB64DIR = lib64 diff -r 8a58ea36e420 -r 50d5bf02e59e config/SunOS.mk --- a/config/SunOS.mk Thu Mar 01 15:02:09 2007 -0700 +++ b/config/SunOS.mk Wed Mar 07 12:38:28 2007 -0700 @@ -14,9 +14,9 @@ SHELL = bash SHELL = bash INSTALL = ginstall -INSTALL_DIR = $(INSTALL) -d -m0755 -INSTALL_DATA = $(INSTALL) -m0644 -INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 -p +INSTALL_DATA = $(INSTALL) -m0644 -p +INSTALL_PROG = $(INSTALL) -m0755 -p LIB64DIR = lib/amd64 diff -r 8a58ea36e420 -r 50d5bf02e59e docs/misc/dump-core-format.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/misc/dump-core-format.txt Wed Mar 07 12:38:28 2007 -0700 @@ -0,0 +1,231 @@ +xen dump-core format + Written by Isaku Yamahata <yamahata at valinux co jp> Feb. 2007 + + +Introduction +------------ +With xm dump-core command, the guest domain's core can be created as a file. +Its format was changed to be based on ELF format because elf format is easily +extensible and handy. This document describes the new format. +In this document the new format is called new xen dump-core format, +xen dump-core format or simply dump-core format. The file of xen dump-core +format is called xen dump-core file or dump-core file. + +The usual process core file includes program headers and no section header. +On the other hand the xen dump-core file includes no program headers and +some sections because of its peculiar requirements. + + +Reference +--------- +For ELF format itself, see Tool Interface Standard(TIS) Executable and +Linking Format(ELF) Specification version 1.2. +For xen related structure, please see the xen header files. + + +Elf header +---------- +The elf header members are set as follows + e_ident[EI_CLASS] = ELFCLASS64 = 2 + e_ident[EI_OSABI] = ELFOSABI_SYSV = 0 + e_type = ET_CORE = 4 +ELFCLASS64 is always used independent of architecture. +e_ident[EI_DATA] and e_flags are set according to the dumping system's +architecture. Other members are set as usual. + +Sections +-------- +Currently the following sections are defined. Some sections are optional. + +".note.Xen" section + name ".note.Xen" + type SHT_NOTE + description + This section is used as note section to store xen dump-core + file specific informations. The each detailed informations are + described in note section. This section must exist. + +".xen_prstatus" section + name ".xen_prstatus" + type SHT_PROGBITS + structure array of vcpu_guest_context_t + description + This section stores the array of vcpu_guest_context_t + which is obtained by XEN_DOMCTL_getvcpucontext hypercall + when the xen dump-core file is created. + The size of array is stored in xch_nr_vcpus member of header + note descriptor in .note.Xen note section. + This section must exist. + +".xen_shared_info" section + name ".xen_shared_info" + type SHT_PROGBITS + structure shared_info_t + description + This section stores the contents of shared info page + of a domain. This section is optional. + +".xen_p2m" section + name ".xen_p2m" + type SHT_PROGBITS + structure array of struct xen_dumpcore_p2m + struct xen_dumpcore_p2m { + uint64_t pfn; + uint64_t gmfn; + }; + description + This elements represents the frame number of the page + in .xen_pages section. + pfn: guest-specific pseudo-physical frame number + gmfn: machine physical frame number + The size of arrays is stored in xch_nr_pages member of header + note descriptor in .note.Xen note section. + There is no rule about the order. Analysis tools must no rely + on its order. + This section must exist when the domain is non auto + translated physmap mode. Currently x86 paravirtualized domain. + +".xen_pfn" section + name ".xen_pfn" + type SHT_PROGBITS + structure array of uint64_t + description + This elements represents the frame number of the page + in .xen_pages section. + The size of arrays is stored in xch_nr_pages member of header + note descriptor in .note.Xen note section. + There is no rule about the order. Analysis tools must no rely + on its order. + This section must exist when the domain is auto translated + physmap mode. Currently x86 full virtualized domain and + ia64 domain. + +".xen_pages" section + name ".xen_pages" + type SHT_PROGBITS + structure array of page where page is page size byte array + description + This section includes the contents of pages. + The corresponding address is described in .xen_p2m section + or .xen_pfn section. + The page size is stored in xch_page_size member of header note + descriptor in .note.Xen section. + The array size is stored in xch_nr_pages member of header note + descriptor in .note.Xen section. + This section must exist. + + +".xen_ia64_mapped_regs" section + name ".xen_ia64_mapped_regs" + type SHT_PROGBITS + structure array of mapped_regs_t + description + This section stores the array of mapped_regs_t. + The size of array is stored in xch_nr_vcpus member of header + note descriptor in .note.Xen note section. + This section is ia64 specific and must exist for ia64 domain. + This section must not exist for non-ia64 domain. + + +note section +------------ +The note types are defined in xen/include/public/elfnote.h. +The note descriptors are defined in tools/libxc/xc_core.h +Currently the following note informations are defined. + + +elf note section + +"Xen" is used as elf note name in elf note info + namesz 4 + name "Xen" (null-terminated) + + +Descriptors + +none note descriptor + type XEN_ELFNOTE_DUMPCORE_NONE = 0x2000000 + structure struct xen_dumpcore_elfnote_none_desc { + /* nothing is defined */ + }; + description + This note descriptor is defined to just indicate that this + file is xen dump-core format without any specific information. + This note information must exist. + +header note descriptor + type XEN_ELFNOTE_DUMPCORE_HEADER = 0x2000001 + structure struct xen_dumpcore_elfnote_header_desc { + uint64_t xch_magic; + uint64_t xch_nr_vcpus; + uint64_t xch_nr_pages; + uint64_t xch_page_size; + }; + description + This note descriptor stores basic information of the domain. + xch_magic magic number + XC_CORE_MAGIC = 0xF00FEBED for paravirtualized domain + XC_CORE_MAGIC_HVM = 0xF00FEBEE for full virtualized domain + xch_nr_vcpus the number of vcpus + xch_nr_pages the number of pages + xch_page_size guest OS's page size + This note information must exist. + +xen_version descriptor + type XEN_ELFNOTE_DUMPCORE_XEN_VERSION = 0x2000002 + structure struct xen_dumpcore_elfnote_xen_version_desc { + uint64_t major_version; + uint64_t minor_version; + xen_extraversion_t extra_version; + xen_compile_info_t compile_info; + xen_capabilities_info_t capabilities; + xen_changeset_info_t changeset; + xen_platform_parameters_t platform_parameters; + uint64_t pagesize; + }; + description + This note descriptor stores basic information about xen + hypervisor. The each members store the result of + __HYPERVISOR_xen_version hypercall. + major_version 16msb bit of the result of XENVER_version + minor_version 16lsb bit of the result of XENVER_version + uint64_t is used to make struct + xen_dumpcore_elfnote_xen_version_desc independent + on 32bit/64bit instead of uint32_t. + extra_version the result of XENVER_extraversion + compile_info the result of XENVER_compile_info + capabilities the result of XENVER_capabilities + changeset the result of XENVER_changeset + platform_parameters + the result of XENVER_platform_parameters + pagesize the result of XENVER_pagesize + This note information must exist. + +format_version descriptor + type XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION = 0x2000003 + structure struct xen_dumpcore_elfnote_format_version_desc { + uint64_t version; + }; + description + This note descriptor stores xen dump-core format version. + The 32msb bit is major version and the 32lsb bit is minor + version. + The minor version will be incremented when the format + is changed in compatible way. e.g. new sections, new note + descriptors are added. + the major version will be incremented when the format is + changed in incompatible way. + This note information must exit. Analysis tools should check + this format version. + This note information must exist. + + +Format version history +---------------------- +Currently only (major, minor) = (0, 1) is used. +[When the format is changed, it would be described here.] + +(0, 1) update +- EI_CLASS member of elf header was changed to ELFCLASS64 independent of + architecture. This is mainly for x86_32pae. + The format version isn't bumped because analysis tools can distinguish it. diff -r 8a58ea36e420 -r 50d5bf02e59e docs/xen-api/xenapi-datamodel.tex --- a/docs/xen-api/xenapi-datamodel.tex Thu Mar 01 15:02:09 2007 -0700 +++ b/docs/xen-api/xenapi-datamodel.tex Wed Mar 07 12:38:28 2007 -0700 @@ -26,6 +26,7 @@ Name & Description \\ {\tt task} & A long-running asynchronous task \\ {\tt VM} & A virtual machine (or 'guest') \\ {\tt VM\_metrics} & The metrics associated with a VM \\ +{\tt VM\_guest\_metrics} & The metrics reported by the guest (as opposed to inferred from outside) \\ {\tt host} & A physical host \\ {\tt host\_metrics} & The metrics associated with a host \\ {\tt host\_cpu} & A physical CPU \\ @@ -61,8 +62,6 @@ crashdump.VM & VM.crash\_dumps & one-to- crashdump.VM & VM.crash\_dumps & one-to-many\\ VIF.VM & VM.VIFs & one-to-many\\ VIF.network & network.VIFs & one-to-many\\ -host.metrics & host\_metrics.host & one-to-one\\ -PIF.metrics & PIF\_metrics.PIF & one-to-one\\ PIF.host & host.PIFs & one-to-many\\ PIF.network & network.PIFs & one-to-many\\ SR.VDIs & VDI.SR & many-to-one\\ @@ -1098,10 +1097,11 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt platform/clock\_offset} & bool & timeshift applied to guest's clock \\ $\mathit{RW}$ & {\tt platform/enable\_audio} & bool & emulate audio \\ $\mathit{RO}_\mathit{ins}$ & {\tt PCI\_bus} & string & PCI bus path for pass-through devices \\ -$\mathit{RO}_\mathit{run}$ & {\tt tools\_version} & (string $\rightarrow$ string) Map & versions of installed paravirtualised drivers \\ $\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ +$\mathit{RO}_\mathit{run}$ & {\tt domid} & int & domain ID (if available, -1 otherwise) \\ $\mathit{RO}_\mathit{run}$ & {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\ $\mathit{RO}_\mathit{run}$ & {\tt metrics} & VM\_metrics ref & metrics associated with this VM. \\ +$\mathit{RO}_\mathit{run}$ & {\tt guest\_metrics} & VM\_guest\_metrics ref & metrics associated with the running guest \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VM} @@ -3800,38 +3800,6 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_tools\_version} - -{\bf Overview:} -Get the tools\_version field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} ((string -> string) Map) get_tools_version (session_id s, VM ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt VM ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -(string $\rightarrow$ string) Map -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} \subsubsection{RPC name:~get\_other\_config} {\bf Overview:} @@ -3969,6 +3937,38 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~get\_domid} + +{\bf Overview:} +Get the domid field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} int get_domid (session_id s, VM ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_is\_control\_domain} {\bf Overview:} @@ -4026,6 +4026,38 @@ Get the metrics field of the given VM. \noindent {\bf Return Type:} {\tt VM\_metrics ref +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_guest\_metrics} + +{\bf Overview:} +Get the guest\_metrics field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} (VM_guest_metrics ref) get_guest_metrics (session_id s, VM ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +VM\_guest\_metrics ref } @@ -4214,6 +4246,27 @@ Quals & Field & Type & Description \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VM\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VM\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VM_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VM\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -4399,6 +4452,338 @@ Get a record containing the current stat \noindent {\bf Return Type:} {\tt VM\_metrics record +} + + +all fields from the object +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} + +\vspace{1cm} +\newpage +\section{Class: VM\_guest\_metrics} +\subsection{Fields for class: VM\_guest\_metrics} +\begin{longtable}{|lllp{0.38\textwidth}|} +\hline +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VM\_guest\_metrics} \\ +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em +The metrics reported by the guest (as opposed to inferred from outside).}} \\ +\hline +Quals & Field & Type & Description \\ +\hline +$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ +$\mathit{RO}_\mathit{run}$ & {\tt os\_version} & (string $\rightarrow$ string) Map & version of the OS \\ +$\mathit{RO}_\mathit{run}$ & {\tt PV\_drivers\_version} & (string $\rightarrow$ string) Map & version of the PV drivers \\ +$\mathit{RO}_\mathit{run}$ & {\tt memory} & (string $\rightarrow$ string) Map & free/used/total memory \\ +$\mathit{RO}_\mathit{run}$ & {\tt disks} & (string $\rightarrow$ string) Map & disk configuration/free space \\ +$\mathit{RO}_\mathit{run}$ & {\tt networks} & (string $\rightarrow$ string) Map & network configuration \\ +$\mathit{RO}_\mathit{run}$ & {\tt other} & (string $\rightarrow$ string) Map & anything else \\ +\hline +\end{longtable} +\subsection{Additional RPCs associated with class: VM\_guest\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VM\_guest\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VM_guest_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VM\_guest\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_uuid} + +{\bf Overview:} +Get the uuid field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} string get_uuid (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_os\_version} + +{\bf Overview:} +Get the os\_version field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_os_version (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_PV\_drivers\_version} + +{\bf Overview:} +Get the PV\_drivers\_version field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_PV_drivers_version (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_memory} + +{\bf Overview:} +Get the memory field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_memory (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_disks} + +{\bf Overview:} +Get the disks field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_disks (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_networks} + +{\bf Overview:} +Get the networks field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_networks (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_other} + +{\bf Overview:} +Get the other field of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_other (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_by\_uuid} + +{\bf Overview:} +Get a reference to the VM\_guest\_metrics instance with the specified UUID. + + \noindent {\bf Signature:} +\begin{verbatim} (VM_guest_metrics ref) get_by_uuid (session_id s, string uuid)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt string } & uuid & UUID of object to return \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +VM\_guest\_metrics ref +} + + +reference to the object +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_record} + +{\bf Overview:} +Get a record containing the current state of the given VM\_guest\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} (VM_guest_metrics record) get_record (session_id s, VM_guest_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +VM\_guest\_metrics record } @@ -4422,8 +4807,13 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ $\mathit{RW}$ & {\tt name/label} & string & a human-readable name \\ $\mathit{RW}$ & {\tt name/description} & string & a notes field containg human-readable description \\ +$\mathit{RO}_\mathit{run}$ & {\tt API\_version/major} & int & major version number \\ +$\mathit{RO}_\mathit{run}$ & {\tt API\_version/minor} & int & minor version number \\ +$\mathit{RO}_\mathit{run}$ & {\tt API\_version/vendor} & string & identification of vendor \\ +$\mathit{RO}_\mathit{run}$ & {\tt API\_version/vendor\_implementation} & (string $\rightarrow$ string) Map & details of vendor implementation \\ $\mathit{RO}_\mathit{run}$ & {\tt software\_version} & (string $\rightarrow$ string) Map & version strings \\ $\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\ +$\mathit{RO}_\mathit{run}$ & {\tt capabilities} & string Set & Xen capabilities \\ $\mathit{RO}_\mathit{run}$ & {\tt supported\_bootloaders} & string Set & a list of the bootloaders installed on the machine \\ $\mathit{RO}_\mathit{run}$ & {\tt resident\_VMs} & (VM ref) Set & list of VMs currently resident on host \\ $\mathit{RW}$ & {\tt logging} & (string $\rightarrow$ string) Map & logging configuration \\ @@ -4784,6 +5174,134 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~get\_API\_version\_major} + +{\bf Overview:} +Get the API\_version/major field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} int get_API_version_major (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_API\_version\_minor} + +{\bf Overview:} +Get the API\_version/minor field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} int get_API_version_minor (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_API\_version\_vendor} + +{\bf Overview:} +Get the API\_version/vendor field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} string get_API_version_vendor (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_API\_version\_vendor\_implementation} + +{\bf Overview:} +Get the API\_version/vendor\_implementation field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_API_version_vendor_implementation (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_software\_version} {\bf Overview:} @@ -4950,6 +5468,38 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_capabilities} + +{\bf Overview:} +Get the capabilities field of the given host. + + \noindent {\bf Signature:} +\begin{verbatim} (string Set) get_capabilities (session_id s, host ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string Set +} + + +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -5524,12 +6074,32 @@ Quals & Field & Type & Description \\ Quals & Field & Type & Description \\ \hline $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ -$\mathit{RO}_\mathit{ins}$ & {\tt host} & host ref & Host to which these metrics apply \\ $\mathit{RO}_\mathit{run}$ & {\tt memory/total} & int & Host's total memory (bytes) \\ $\mathit{RO}_\mathit{run}$ & {\tt memory/free} & int & Host's free memory (bytes) \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: host\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the host\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((host_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(host\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -5555,38 +6125,6 @@ Get the uuid field of the given host\_me \noindent {\bf Return Type:} {\tt string -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_host} - -{\bf Overview:} -Get the host field of the given host\_metrics. - - \noindent {\bf Signature:} -\begin{verbatim} (host ref) get_host (session_id s, host_metrics ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt host\_metrics ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -host ref } @@ -5735,15 +6273,38 @@ Quals & Field & Type & Description \\ Quals & Field & Type & Description \\ \hline $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ -$\mathit{RO}_\mathit{ins}$ & {\tt host} & host ref & the host the CPU is in \\ -$\mathit{RO}_\mathit{ins}$ & {\tt number} & int & the number of the physical CPU within the host \\ -$\mathit{RO}_\mathit{ins}$ & {\tt vendor} & string & the vendor of the physical CPU \\ -$\mathit{RO}_\mathit{ins}$ & {\tt speed} & int & the speed of the physical CPU \\ -$\mathit{RO}_\mathit{ins}$ & {\tt modelname} & string & the model name of the physical CPU \\ +$\mathit{RO}_\mathit{run}$ & {\tt host} & host ref & the host the CPU is in \\ +$\mathit{RO}_\mathit{run}$ & {\tt number} & int & the number of the physical CPU within the host \\ +$\mathit{RO}_\mathit{run}$ & {\tt vendor} & string & the vendor of the physical CPU \\ +$\mathit{RO}_\mathit{run}$ & {\tt speed} & int & the speed of the physical CPU \\ +$\mathit{RO}_\mathit{run}$ & {\tt modelname} & string & the model name of the physical CPU \\ +$\mathit{RO}_\mathit{run}$ & {\tt stepping} & string & the stepping of the physical CPU \\ +$\mathit{RO}_\mathit{run}$ & {\tt flags} & string & the flags of the physical CPU \\ $\mathit{RO}_\mathit{run}$ & {\tt utilisation} & float & the current CPU utilisation \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: host\_cpu} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the host\_cpus known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((host_cpu ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(host\_cpu ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -5936,6 +6497,70 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~get\_stepping} + +{\bf Overview:} +Get the stepping field of the given host\_cpu. + + \noindent {\bf Signature:} +\begin{verbatim} string get_stepping (session_id s, host_cpu ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host\_cpu ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_flags} + +{\bf Overview:} +Get the flags field of the given host\_cpu. + + \noindent {\bf Signature:} +\begin{verbatim} string get_flags (session_id s, host_cpu ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt host\_cpu ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_utilisation} {\bf Overview:} @@ -5965,70 +6590,6 @@ float value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~create} - -{\bf Overview:} -Create a new host\_cpu instance, and return its handle. - - \noindent {\bf Signature:} -\begin{verbatim} (host_cpu ref) create (session_id s, host_cpu record args)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt host\_cpu record } & args & All constructor arguments \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -host\_cpu ref -} - - -reference to the newly created object -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~destroy} - -{\bf Overview:} -Destroy the specified host\_cpu instance. - - \noindent {\bf Signature:} -\begin{verbatim} void destroy (session_id s, host_cpu ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt host\_cpu ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -6114,8 +6675,6 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt name/description} & string & a notes field containg human-readable description \\ $\mathit{RO}_\mathit{run}$ & {\tt VIFs} & (VIF ref) Set & list of connected vifs \\ $\mathit{RO}_\mathit{run}$ & {\tt PIFs} & (PIF ref) Set & list of connected pifs \\ -$\mathit{RW}$ & {\tt default\_gateway} & string & default gateway IP address. Used for auto-configuring guests with fixed IP setting \\ -$\mathit{RW}$ & {\tt default\_netmask} & string & default netmask. Used for auto-configuring guests with fixed IP setting \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: network} @@ -6365,138 +6924,6 @@ Get the PIFs field of the given network. value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_default\_gateway} - -{\bf Overview:} -Get the default\_gateway field of the given network. - - \noindent {\bf Signature:} -\begin{verbatim} string get_default_gateway (session_id s, network ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt network ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -string -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_default\_gateway} - -{\bf Overview:} -Set the default\_gateway field of the given network. - - \noindent {\bf Signature:} -\begin{verbatim} void set_default_gateway (session_id s, network ref self, string value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt network ref } & self & reference to the object \\ \hline - -{\tt string } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_default\_netmask} - -{\bf Overview:} -Get the default\_netmask field of the given network. - - \noindent {\bf Signature:} -\begin{verbatim} string get_default_netmask (session_id s, network ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt network ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -string -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~set\_default\_netmask} - -{\bf Overview:} -Set the default\_netmask field of the given network. - - \noindent {\bf Signature:} -\begin{verbatim} void set_default_netmask (session_id s, network ref self, string value)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt network ref } & self & reference to the object \\ \hline - -{\tt string } & value & New value to set \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -6679,12 +7106,37 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{ins}$ & {\tt VM} & VM ref & virtual machine to which this vif is connected \\ $\mathit{RW}$ & {\tt MAC} & string & ethernet MAC address of virtual interface, as exposed to guest \\ $\mathit{RW}$ & {\tt MTU} & int & MTU in octets \\ +$\mathit{RO}_\mathit{run}$ & {\tt currently\_attached} & bool & is the device currently attached (erased on reboot) \\ +$\mathit{RO}_\mathit{run}$ & {\tt status\_code} & int & error/success code associated with last attach-operation (erased on reboot) \\ +$\mathit{RO}_\mathit{run}$ & {\tt status\_detail} & string & error/success information associated with last attach-operation status (erased on reboot) \\ $\mathit{RW}$ & {\tt qos/algorithm\_type} & string & QoS algorithm to use \\ -$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & Paramters for chosen QoS algorithm \\ +$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & parameters for chosen QoS algorithm \\ +$\mathit{RO}_\mathit{run}$ & {\tt qos/supported\_algorithms} & string Set & supported QoS algorithms for this VIF \\ $\mathit{RO}_\mathit{run}$ & {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF. \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VIF} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VIFs known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VIF ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VIF ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -6976,6 +7428,102 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_currently\_attached} + +{\bf Overview:} +Get the currently\_attached field of the given VIF. + + \noindent {\bf Signature:} +\begin{verbatim} bool get_currently_attached (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +bool +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_status\_code} + +{\bf Overview:} +Get the status\_code field of the given VIF. + + \noindent {\bf Signature:} +\begin{verbatim} int get_status_code (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_status\_detail} + +{\bf Overview:} +Get the status\_detail field of the given VIF. + + \noindent {\bf Signature:} +\begin{verbatim} string get_status_detail (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -7181,6 +7729,38 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_qos\_supported\_algorithms} + +{\bf Overview:} +Get the qos/supported\_algorithms field of the given VIF. + + \noindent {\bf Signature:} +\begin{verbatim} (string Set) get_qos_supported_algorithms (session_id s, VIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VIF ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string Set +} + + +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -7363,6 +7943,27 @@ Quals & Field & Type & Description \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VIF\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VIF\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VIF_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VIF\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -7623,6 +8224,27 @@ void \noindent{\bf Possible Error Codes:} {\tt PIF\_IS\_PHYSICAL} \vspace{0.6cm} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the PIFs known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((PIF ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(PIF ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -8093,12 +8715,32 @@ Quals & Field & Type & Description \\ Quals & Field & Type & Description \\ \hline $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ -$\mathit{RO}_\mathit{ins}$ & {\tt PIF} & PIF ref & PIF to which these metrics apply \\ $\mathit{RO}_\mathit{run}$ & {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\ $\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: PIF\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the PIF\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((PIF_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(PIF\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -8124,38 +8766,6 @@ Get the uuid field of the given PIF\_met \noindent {\bf Return Type:} {\tt string -} - - -value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~get\_PIF} - -{\bf Overview:} -Get the PIF field of the given PIF\_metrics. - - \noindent {\bf Signature:} -\begin{verbatim} (PIF ref) get_PIF (session_id s, PIF_metrics ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt PIF\_metrics ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -PIF ref } @@ -8942,7 +9552,7 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt SR} & SR ref & storage repository in which the VDI resides \\ $\mathit{RO}_\mathit{run}$ & {\tt VBDs} & (VBD ref) Set & list of vbds that refer to this disk \\ $\mathit{RO}_\mathit{run}$ & {\tt crash\_dumps} & (crashdump ref) Set & list of crash dumps that refer to this disk \\ -$\mathit{RW}$ & {\tt virtual\_size} & int & size of disk as presented to the guest (in multiples of sector\_size field) \\ +$\mathit{RW}$ & {\tt virtual\_size} & int & size of disk as presented to the guest (in bytes). Note that, depending on storage backend type, requested size may not be respected exactly \\ $\mathit{RO}_\mathit{run}$ & {\tt physical\_utilisation} & int & amount of physical space that the disk image is currently taking up on the storage repository (in bytes) \\ $\mathit{RO}_\mathit{ins}$ & {\tt sector\_size} & int & sector size of VDI (in bytes) \\ $\mathit{RO}_\mathit{ins}$ & {\tt type} & vdi\_type & type of the VDI \\ @@ -9015,6 +9625,27 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VDIs known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VDI ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VDI ref) Set +} + + +references to all objects \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -9786,9 +10417,13 @@ Quals & Field & Type & Description \\ $\mathit{RW}$ & {\tt bootable} & bool & true if this VBD is bootable \\ $\mathit{RW}$ & {\tt mode} & vbd\_mode & the mode the VBD should be mounted with \\ $\mathit{RW}$ & {\tt type} & vbd\_type & how the VBD will appear to the guest (e.g. disk or CD) \\ +$\mathit{RO}_\mathit{run}$ & {\tt currently\_attached} & bool & is the device currently attached (erased on reboot) \\ +$\mathit{RO}_\mathit{run}$ & {\tt status\_code} & int & error/success code associated with last attach-operation (erased on reboot) \\ +$\mathit{RO}_\mathit{run}$ & {\tt status\_detail} & string & error/success information associated with last attach-operation status (erased on reboot) \\ $\mathit{RW}$ & {\tt qos/algorithm\_type} & string & QoS algorithm to use \\ -$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & Paramters for chosen QoS algorithm \\ -$\mathit{RO}_\mathit{run}$ & {\tt metrics} & VBD\_metrics ref & metrics associated with this VBD. \\ +$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & parameters for chosen QoS algorithm \\ +$\mathit{RO}_\mathit{run}$ & {\tt qos/supported\_algorithms} & string Set & supported QoS algorithms for this VBD \\ +$\mathit{RO}_\mathit{run}$ & {\tt metrics} & VBD\_metrics ref & metrics associated with this VBD \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VBD} @@ -9827,6 +10462,27 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VBDs known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VBD ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VBD ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -10184,6 +10840,102 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_currently\_attached} + +{\bf Overview:} +Get the currently\_attached field of the given VBD. + + \noindent {\bf Signature:} +\begin{verbatim} bool get_currently_attached (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +bool +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_status\_code} + +{\bf Overview:} +Get the status\_code field of the given VBD. + + \noindent {\bf Signature:} +\begin{verbatim} int get_status_code (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_status\_detail} + +{\bf Overview:} +Get the status\_detail field of the given VBD. + + \noindent {\bf Signature:} +\begin{verbatim} string get_status_detail (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -10389,6 +11141,38 @@ void +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_qos\_supported\_algorithms} + +{\bf Overview:} +Get the qos/supported\_algorithms field of the given VBD. + + \noindent {\bf Signature:} +\begin{verbatim} (string Set) get_qos_supported_algorithms (session_id s, VBD ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VBD ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string Set +} + + +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -10571,6 +11355,27 @@ Quals & Field & Type & Description \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: VBD\_metrics} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the VBD\_metrics instances known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((VBD_metrics ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(VBD\_metrics ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -10752,6 +11557,27 @@ Quals & Field & Type & Description \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: PBD} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the PBDs known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((PBD ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(PBD ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} @@ -11568,6 +12394,27 @@ Quals & Field & Type & Description \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: console} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the consoles known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((console ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(console ref) Set +} + + +references to all objects +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~get\_uuid} {\bf Overview:} diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/Makefile --- a/extras/mini-os/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -3,8 +3,6 @@ # Every architecture directory below mini-os/arch has to have a # Makefile and a arch.mk. # - -pae ?= n XEN_ROOT = ../.. include $(XEN_ROOT)/Config.mk @@ -35,6 +33,7 @@ export TARGET_ARCH export TARGET_ARCH export TARGET_ARCH_DIR export TARGET_ARCH_FAM +export XEN_TARGET_X86_PAE # This is used for architecture specific links. # This can be overwritten from arch specific rules. diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/arch/ia64/mm.c --- a/extras/mini-os/arch/ia64/mm.c Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/arch/ia64/mm.c Wed Mar 07 12:38:28 2007 -0700 @@ -130,3 +130,7 @@ map_frames(unsigned long* frames, unsign return (void*) __va(frames[0] << PAGE_SHIFT); } +void arch_init_p2m(unsigned long max_pfn) +{ + printk("Warn: p2m map not implemented.\n"); +} diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/arch/x86/Makefile --- a/extras/mini-os/arch/x86/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/arch/x86/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -4,6 +4,7 @@ # # include arch.mk has to be before mini-os.mk! + include arch.mk include ../../minios.mk diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/arch/x86/arch.mk --- a/extras/mini-os/arch/x86/arch.mk Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/arch/x86/arch.mk Wed Mar 07 12:38:28 2007 -0700 @@ -9,13 +9,11 @@ ARCH_ASFLAGS := -m32 ARCH_ASFLAGS := -m32 EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) EXTRA_SRC += arch/$(EXTRA_INC) + +ifeq ($(XEN_TARGET_X86_PAE),y) +ARCH_CFLAGS += -DCONFIG_X86_PAE=1 +ARCH_ASFLAGS += -DCONFIG_X86_PAE=1 endif - -ifeq ($(TARGET_ARCH)$(pae),x86_32y) -ARCH_CFLAGS := -DCONFIG_X86_PAE=1 -ARCH_ASFLAGS := -DCONFIG_X86_PAE=1 -EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) -EXTRA_SRC += arch/$(EXTRA_INC) endif ifeq ($(TARGET_ARCH),x86_64) diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/arch/x86/mm.c Wed Mar 07 12:38:28 2007 -0700 @@ -402,6 +402,49 @@ void *map_frames(unsigned long *f, unsig } } + +void arch_init_p2m(unsigned long max_pfn) +{ +#define L1_P2M_SHIFT 10 +#define L2_P2M_SHIFT 20 +#define L3_P2M_SHIFT 30 +#define L1_P2M_ENTRIES (1 << L1_P2M_SHIFT) +#define L2_P2M_ENTRIES (1 << (L2_P2M_SHIFT - L1_P2M_SHIFT)) +#define L3_P2M_ENTRIES (1 << (L3_P2M_SHIFT - L2_P2M_SHIFT)) +#define L1_P2M_MASK (L1_P2M_ENTRIES - 1) +#define L2_P2M_MASK (L2_P2M_ENTRIES - 1) +#define L3_P2M_MASK (L3_P2M_ENTRIES - 1) + + unsigned long *l1_list, *l2_list, *l3_list; + unsigned long pfn; + + l3_list = (unsigned long *)alloc_page(); + for(pfn=0; pfn<max_pfn; pfn++) + { + if(!(pfn % (L1_P2M_ENTRIES * L2_P2M_ENTRIES))) + { + l2_list = (unsigned long*)alloc_page(); + if((pfn >> L3_P2M_SHIFT) > 0) + { + printk("Error: Too many pfns.\n"); + do_exit(); + } + l3_list[(pfn >> L2_P2M_SHIFT)] = virt_to_mfn(l2_list); + } + if(!(pfn % (L1_P2M_ENTRIES))) + { + l1_list = (unsigned long*)alloc_page(); + l2_list[(pfn >> L1_P2M_SHIFT) & L2_P2M_MASK] = + virt_to_mfn(l1_list); + } + + l1_list[pfn & L1_P2M_MASK] = pfn_to_mfn(pfn); + } + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = + virt_to_mfn(l3_list); + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; +} + void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) { diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/include/mm.h Wed Mar 07 12:38:28 2007 -0700 @@ -55,6 +55,7 @@ static __inline__ int get_order(unsigned void arch_init_demand_mapping_area(unsigned long max_pfn); void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p); +void arch_init_p2m(unsigned long max_pfn_p); void *map_frames(unsigned long *f, unsigned long n); diff -r 8a58ea36e420 -r 50d5bf02e59e extras/mini-os/mm.c --- a/extras/mini-os/mm.c Thu Mar 01 15:02:09 2007 -0700 +++ b/extras/mini-os/mm.c Wed Mar 07 12:38:28 2007 -0700 @@ -379,6 +379,8 @@ void init_mm(void) init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn)); printk("MM: done\n"); + arch_init_p2m(max_pfn); + arch_init_demand_mapping_area(max_pfn); } diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/Kconfig --- a/linux-2.6-xen-sparse/arch/i386/Kconfig Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Wed Mar 07 12:38:28 2007 -0700 @@ -255,7 +255,6 @@ config SCHED_SMT config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" depends on X86_HT - depends on !X86_XEN help SMT scheduler support improves the CPU scheduler's decision making when dealing with Intel Pentium 4 chips with HyperThreading at a @@ -311,11 +310,6 @@ config X86_VISWS_APIC config X86_VISWS_APIC bool depends on X86_VISWS - default y - -config X86_TSC - bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN default y config X86_MCE diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/Kconfig.cpu --- a/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu Wed Mar 07 12:38:28 2007 -0700 @@ -311,5 +311,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ - default y + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ && !X86_XEN + default y diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/alternative-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/alternative-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,389 +0,0 @@ -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/list.h> -#include <asm/alternative.h> -#include <asm/sections.h> - -static int no_replacement = 0; -static int smp_alt_once = 0; -static int debug_alternative = 0; - -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 1; -} -static int __init bootonly(char *str) -{ - smp_alt_once = 1; - return 1; -} -static int __init debug_alt(char *str) -{ - debug_alternative = 1; - return 1; -} - -__setup("noreplacement", noreplacement_setup); -__setup("smp-alt-boot", bootonly); -__setup("debug-alternative", debug_alt); - -#define DPRINTK(fmt, args...) if (debug_alternative) \ - printk(KERN_DEBUG fmt, args) - -#ifdef GENERIC_NOP1 -/* Use inline assembly to define this because the nops are defined - as inline assembly strings in the include files and we cannot - get them easily into strings. */ -asm("\t.data\nintelnops: " - GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 - GENERIC_NOP7 GENERIC_NOP8); -extern unsigned char intelnops[]; -static unsigned char *intel_nops[ASM_NOP_MAX+1] = { - NULL, - intelnops, - intelnops + 1, - intelnops + 1 + 2, - intelnops + 1 + 2 + 3, - intelnops + 1 + 2 + 3 + 4, - intelnops + 1 + 2 + 3 + 4 + 5, - intelnops + 1 + 2 + 3 + 4 + 5 + 6, - intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -#endif - -#ifdef K8_NOP1 -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); -extern unsigned char k8nops[]; -static unsigned char *k8_nops[ASM_NOP_MAX+1] = { - NULL, - k8nops, - k8nops + 1, - k8nops + 1 + 2, - k8nops + 1 + 2 + 3, - k8nops + 1 + 2 + 3 + 4, - k8nops + 1 + 2 + 3 + 4 + 5, - k8nops + 1 + 2 + 3 + 4 + 5 + 6, - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -#endif - -#ifdef K7_NOP1 -asm("\t.data\nk7nops: " - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 - K7_NOP7 K7_NOP8); -extern unsigned char k7nops[]; -static unsigned char *k7_nops[ASM_NOP_MAX+1] = { - NULL, - k7nops, - k7nops + 1, - k7nops + 1 + 2, - k7nops + 1 + 2 + 3, - k7nops + 1 + 2 + 3 + 4, - k7nops + 1 + 2 + 3 + 4 + 5, - k7nops + 1 + 2 + 3 + 4 + 5 + 6, - k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -#endif - -#ifdef CONFIG_X86_64 - -extern char __vsyscall_0; -static inline unsigned char** find_nop_table(void) -{ - return k8_nops; -} - -#else /* CONFIG_X86_64 */ - -static struct nop { - int cpuid; - unsigned char **noptable; -} noptypes[] = { - { X86_FEATURE_K8, k8_nops }, - { X86_FEATURE_K7, k7_nops }, - { -1, NULL } -}; - -static unsigned char** find_nop_table(void) -{ - unsigned char **noptable = intel_nops; - int i; - - for (i = 0; noptypes[i].cpuid >= 0; i++) { - if (boot_cpu_has(noptypes[i].cpuid)) { - noptable = noptypes[i].noptable; - break; - } - } - return noptable; -} - -#endif /* CONFIG_X86_64 */ - -extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; -extern u8 *__smp_locks[], *__smp_locks_end[]; - -extern u8 __smp_alt_begin[], __smp_alt_end[]; - -/* Replace instructions with better alternatives for this CPU type. - This runs before SMP is initialized to avoid SMP problems with - self modifying code. This implies that assymetric systems where - APs have less capabilities than the boot processor are not handled. - Tough. Make sure you disable such features by hand. */ - -void apply_alternatives(struct alt_instr *start, struct alt_instr *end) -{ - unsigned char **noptable = find_nop_table(); - struct alt_instr *a; - u8 *instr; - int diff, i, k; - - DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); - for (a = start; a < end; a++) { - BUG_ON(a->replacementlen > a->instrlen); - if (!boot_cpu_has(a->cpuid)) - continue; - instr = a->instr; -#ifdef CONFIG_X86_64 - /* vsyscall code is not mapped yet. resolve it manually. */ - if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { - instr -= VSYSCALL_START - (unsigned long)&__vsyscall_0; - DPRINTK("%s: vsyscall fixup: %p => %p\n", - __FUNCTION__, a->instr, instr); - } -#endif - memcpy(instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); - } - } -} - -#ifdef CONFIG_SMP - -static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); - for (a = start; a < end; a++) { - memcpy(a->replacement + a->replacementlen, - a->instr, - a->instrlen); - } -} - -static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) -{ - struct alt_instr *a; - - for (a = start; a < end; a++) { - memcpy(a->instr, - a->replacement + a->replacementlen, - a->instrlen); - } -} - -static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) -{ - u8 **ptr; - - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) - continue; - **ptr = 0xf0; /* lock prefix */ - }; -} - -static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) -{ - unsigned char **noptable = find_nop_table(); - u8 **ptr; - - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) - continue; - **ptr = noptable[1][0]; - }; -} - -struct smp_alt_module { - /* what is this ??? */ - struct module *mod; - char *name; - - /* ptrs to lock prefixes */ - u8 **locks; - u8 **locks_end; - - /* .text segment, needed to avoid patching init code ;) */ - u8 *text; - u8 *text_end; - - struct list_head next; -}; -static LIST_HEAD(smp_alt_modules); -static DEFINE_SPINLOCK(smp_alt); - -void alternatives_smp_module_add(struct module *mod, char *name, - void *locks, void *locks_end, - void *text, void *text_end) -{ - struct smp_alt_module *smp; - unsigned long flags; - - if (no_replacement) - return; - - if (smp_alt_once) { - if (boot_cpu_has(X86_FEATURE_UP)) - alternatives_smp_unlock(locks, locks_end, - text, text_end); - return; - } - - smp = kzalloc(sizeof(*smp), GFP_KERNEL); - if (NULL == smp) - return; /* we'll run the (safe but slow) SMP code then ... */ - - smp->mod = mod; - smp->name = name; - smp->locks = locks; - smp->locks_end = locks_end; - smp->text = text; - smp->text_end = text_end; - DPRINTK("%s: locks %p -> %p, text %p -> %p, name %s\n", - __FUNCTION__, smp->locks, smp->locks_end, - smp->text, smp->text_end, smp->name); - - spin_lock_irqsave(&smp_alt, flags); - list_add_tail(&smp->next, &smp_alt_modules); - if (boot_cpu_has(X86_FEATURE_UP)) - alternatives_smp_unlock(smp->locks, smp->locks_end, - smp->text, smp->text_end); - spin_unlock_irqrestore(&smp_alt, flags); -} - -void alternatives_smp_module_del(struct module *mod) -{ - struct smp_alt_module *item; - unsigned long flags; - - if (no_replacement || smp_alt_once) - return; - - spin_lock_irqsave(&smp_alt, flags); - list_for_each_entry(item, &smp_alt_modules, next) { - if (mod != item->mod) - continue; - list_del(&item->next); - spin_unlock_irqrestore(&smp_alt, flags); - DPRINTK("%s: %s\n", __FUNCTION__, item->name); - kfree(item); - return; - } - spin_unlock_irqrestore(&smp_alt, flags); -} - -void alternatives_smp_switch(int smp) -{ - struct smp_alt_module *mod; - unsigned long flags; - -#ifdef CONFIG_LOCKDEP - /* - * A not yet fixed binutils section handling bug prevents - * alternatives-replacement from working reliably, so turn - * it off: - */ - printk("lockdep: not fixing up alternatives.\n"); - return; -#endif - - if (no_replacement || smp_alt_once) - return; - BUG_ON(!smp && (num_online_cpus() > 1)); - - spin_lock_irqsave(&smp_alt, flags); - if (smp) { - printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); - clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - alternatives_smp_apply(__smp_alt_instructions, - __smp_alt_instructions_end); - list_for_each_entry(mod, &smp_alt_modules, next) - alternatives_smp_lock(mod->locks, mod->locks_end, - mod->text, mod->text_end); - } else { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); - set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); - list_for_each_entry(mod, &smp_alt_modules, next) - alternatives_smp_unlock(mod->locks, mod->locks_end, - mod->text, mod->text_end); - } - spin_unlock_irqrestore(&smp_alt, flags); -} - -#endif - -void __init alternative_instructions(void) -{ - if (no_replacement) { - printk(KERN_INFO "(SMP-)alternatives turned off\n"); - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - return; - } - apply_alternatives(__alt_instructions, __alt_instructions_end); - - /* switch to patch-once-at-boottime-only mode and free the - * tables in case we know the number of CPUs will never ever - * change */ -#ifdef CONFIG_HOTPLUG_CPU - if (num_possible_cpus() < 2) - smp_alt_once = 1; -#else - smp_alt_once = 1; -#endif - -#ifdef CONFIG_SMP - if (smp_alt_once) { - if (1 == num_possible_cpus()) { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); - set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); - set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); - apply_alternatives(__smp_alt_instructions, - __smp_alt_instructions_end); - alternatives_smp_unlock(__smp_locks, __smp_locks_end, - _text, _etext); - } - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - } else { - alternatives_smp_save(__smp_alt_instructions, - __smp_alt_instructions_end); - alternatives_smp_module_add(NULL, "core kernel", - __smp_locks, __smp_locks_end, - _text, _etext); - alternatives_smp_switch(0); - } -#endif -} diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,774 +0,0 @@ -/* - * Routines to indentify caches on Intel CPU. - * - * Changes: - * Venkatesh Pallipadi : Adding cache identification through cpuid(4) - * Ashok Raj <ashok.raj@xxxxxxxxx>: Work with CPU hotplug infrastructure. - * Andi Kleen : CPUID4 emulation on AMD. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/compiler.h> -#include <linux/cpu.h> -#include <linux/sched.h> - -#include <asm/processor.h> -#include <asm/smp.h> - -#define LVL_1_INST 1 -#define LVL_1_DATA 2 -#define LVL_2 3 -#define LVL_3 4 -#define LVL_TRACE 5 - -struct _cache_table -{ - unsigned char descriptor; - char cache_type; - short size; -}; - -/* all the cache descriptor types we care about (no TLB or trace cache entries) */ -static struct _cache_table cache_table[] __cpuinitdata = -{ - { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ - { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ - { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ - { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ - { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */ - { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */ - { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */ - { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */ - { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */ - { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */ - { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */ - { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */ - { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */ - { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */ - { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */ - { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */ - { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ - { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */ - { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ - { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */ - { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */ - { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */ - { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */ - { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */ - { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */ - { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */ - { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */ - { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ - { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */ - { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */ - { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */ - { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */ - { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */ - { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ - { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ - { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ - { 0x00, 0, 0} -}; - - -enum _cache_type -{ - CACHE_TYPE_NULL = 0, - CACHE_TYPE_DATA = 1, - CACHE_TYPE_INST = 2, - CACHE_TYPE_UNIFIED = 3 -}; - -union _cpuid4_leaf_eax { - struct { - enum _cache_type type:5; - unsigned int level:3; - unsigned int is_self_initializing:1; - unsigned int is_fully_associative:1; - unsigned int reserved:4; - unsigned int num_threads_sharing:12; - unsigned int num_cores_on_die:6; - } split; - u32 full; -}; - -union _cpuid4_leaf_ebx { - struct { - unsigned int coherency_line_size:12; - unsigned int physical_line_partition:10; - unsigned int ways_of_associativity:10; - } split; - u32 full; -}; - -union _cpuid4_leaf_ecx { - struct { - unsigned int number_of_sets:32; - } split; - u32 full; -}; - -struct _cpuid4_info { - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; - unsigned long size; - cpumask_t shared_cpu_map; -}; - -unsigned short num_cache_leaves; - -/* AMD doesn't have CPUID4. Emulate it here to report the same - information to the user. This makes some assumptions about the machine: - No L3, L2 not shared, no SMT etc. that is currently true on AMD CPUs. - - In theory the TLBs could be reported as fake type (they are in "dummy"). - Maybe later */ -union l1_cache { - struct { - unsigned line_size : 8; - unsigned lines_per_tag : 8; - unsigned assoc : 8; - unsigned size_in_kb : 8; - }; - unsigned val; -}; - -union l2_cache { - struct { - unsigned line_size : 8; - unsigned lines_per_tag : 4; - unsigned assoc : 4; - unsigned size_in_kb : 16; - }; - unsigned val; -}; - -static const unsigned short assocs[] = { - [1] = 1, [2] = 2, [4] = 4, [6] = 8, - [8] = 16, - [0xf] = 0xffff // ?? - }; -static const unsigned char levels[] = { 1, 1, 2 }; -static const unsigned char types[] = { 1, 2, 3 }; - -static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, - union _cpuid4_leaf_ebx *ebx, - union _cpuid4_leaf_ecx *ecx) -{ - unsigned dummy; - unsigned line_size, lines_per_tag, assoc, size_in_kb; - union l1_cache l1i, l1d; - union l2_cache l2; - - eax->full = 0; - ebx->full = 0; - ecx->full = 0; - - cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val); - cpuid(0x80000006, &dummy, &dummy, &l2.val, &dummy); - - if (leaf > 2 || !l1d.val || !l1i.val || !l2.val) - return; - - eax->split.is_self_initializing = 1; - eax->split.type = types[leaf]; - eax->split.level = levels[leaf]; - eax->split.num_threads_sharing = 0; - eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; - - if (leaf <= 1) { - union l1_cache *l1 = leaf == 0 ? &l1d : &l1i; - assoc = l1->assoc; - line_size = l1->line_size; - lines_per_tag = l1->lines_per_tag; - size_in_kb = l1->size_in_kb; - } else { - assoc = l2.assoc; - line_size = l2.line_size; - lines_per_tag = l2.lines_per_tag; - /* cpu_data has errata corrections for K7 applied */ - size_in_kb = current_cpu_data.x86_cache_size; - } - - if (assoc == 0xf) - eax->split.is_fully_associative = 1; - ebx->split.coherency_line_size = line_size - 1; - ebx->split.ways_of_associativity = assocs[assoc] - 1; - ebx->split.physical_line_partition = lines_per_tag - 1; - ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / - (ebx->split.ways_of_associativity + 1) - 1; -} - -static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) -{ - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; - unsigned edx; - - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) - amd_cpuid4(index, &eax, &ebx, &ecx); - else - cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); - if (eax.split.type == CACHE_TYPE_NULL) - return -EIO; /* better error ? */ - - this_leaf->eax = eax; - this_leaf->ebx = ebx; - this_leaf->ecx = ecx; - this_leaf->size = (ecx.split.number_of_sets + 1) * - (ebx.split.coherency_line_size + 1) * - (ebx.split.physical_line_partition + 1) * - (ebx.split.ways_of_associativity + 1); - return 0; -} - -/* will only be called once; __init is safe here */ -static int __init find_num_cache_leaves(void) -{ - unsigned int eax, ebx, ecx, edx; - union _cpuid4_leaf_eax cache_eax; - int i = -1; - - do { - ++i; - /* Do cpuid(4) loop to find out num_cache_leaves */ - cpuid_count(4, i, &eax, &ebx, &ecx, &edx); - cache_eax.full = eax; - } while (cache_eax.split.type != CACHE_TYPE_NULL); - return i; -} - -unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) -{ - unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ - unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ - unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ - unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; -#ifdef CONFIG_X86_HT - unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); -#endif - - if (c->cpuid_level > 3) { - static int is_initialized; - - if (is_initialized == 0) { - /* Init num_cache_leaves from boot CPU */ - num_cache_leaves = find_num_cache_leaves(); - is_initialized++; - } - - /* - * Whenever possible use cpuid(4), deterministic cache - * parameters cpuid leaf to find the cache details - */ - for (i = 0; i < num_cache_leaves; i++) { - struct _cpuid4_info this_leaf; - - int retval; - - retval = cpuid4_cache_lookup(i, &this_leaf); - if (retval >= 0) { - switch(this_leaf.eax.split.level) { - case 1: - if (this_leaf.eax.split.type == - CACHE_TYPE_DATA) - new_l1d = this_leaf.size/1024; - else if (this_leaf.eax.split.type == - CACHE_TYPE_INST) - new_l1i = this_leaf.size/1024; - break; - case 2: - new_l2 = this_leaf.size/1024; - num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; - index_msb = get_count_order(num_threads_sharing); - l2_id = c->apicid >> index_msb; - break; - case 3: - new_l3 = this_leaf.size/1024; - num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; - index_msb = get_count_order(num_threads_sharing); - l3_id = c->apicid >> index_msb; - break; - default: - break; - } - } - } - } - /* - * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for - * trace cache - */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { - /* supports eax=2 call */ - int i, j, n; - int regs[4]; - unsigned char *dp = (unsigned char *)regs; - int only_trace = 0; - - if (num_cache_leaves != 0 && c->x86 == 15) - only_trace = 1; - - /* Number of times to iterate */ - n = cpuid_eax(2) & 0xFF; - - for ( i = 0 ; i < n ; i++ ) { - cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); - - /* If bit 31 is set, this is an unknown format */ - for ( j = 0 ; j < 3 ; j++ ) { - if ( regs[j] < 0 ) regs[j] = 0; - } - - /* Byte 0 is level count, not a descriptor */ - for ( j = 1 ; j < 16 ; j++ ) { - unsigned char des = dp[j]; - unsigned char k = 0; - - /* look up this descriptor in the table */ - while (cache_table[k].descriptor != 0) - { - if (cache_table[k].descriptor == des) { - if (only_trace && cache_table[k].cache_type != LVL_TRACE) - break; - switch (cache_table[k].cache_type) { - case LVL_1_INST: - l1i += cache_table[k].size; - break; - case LVL_1_DATA: - l1d += cache_table[k].size; - break; - case LVL_2: - l2 += cache_table[k].size; - break; - case LVL_3: - l3 += cache_table[k].size; - break; - case LVL_TRACE: - trace += cache_table[k].size; - break; - } - - break; - } - - k++; - } - } - } - } - - if (new_l1d) - l1d = new_l1d; - - if (new_l1i) - l1i = new_l1i; - - if (new_l2) { - l2 = new_l2; -#ifdef CONFIG_X86_HT - cpu_llc_id[cpu] = l2_id; -#endif - } - - if (new_l3) { - l3 = new_l3; -#ifdef CONFIG_X86_HT - cpu_llc_id[cpu] = l3_id; -#endif - } - - if (trace) - printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); - else if ( l1i ) - printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); - - if (l1d) - printk(", L1 D cache: %dK\n", l1d); - else - printk("\n"); - - if (l2) - printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); - - if (l3) - printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); - - c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); - - return l2; -} - -/* pointer to _cpuid4_info array (for each cache leaf) */ -static struct _cpuid4_info *cpuid4_info[NR_CPUS]; -#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) - -#ifdef CONFIG_SMP -static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) -{ - struct _cpuid4_info *this_leaf, *sibling_leaf; - unsigned long num_threads_sharing; - int index_msb, i; - struct cpuinfo_x86 *c = cpu_data; - - this_leaf = CPUID4_INFO_IDX(cpu, index); - num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; - - if (num_threads_sharing == 1) - cpu_set(cpu, this_leaf->shared_cpu_map); - else { - index_msb = get_count_order(num_threads_sharing); - - for_each_online_cpu(i) { - if (c[i].apicid >> index_msb == - c[cpu].apicid >> index_msb) { - cpu_set(i, this_leaf->shared_cpu_map); - if (i != cpu && cpuid4_info[i]) { - sibling_leaf = CPUID4_INFO_IDX(i, index); - cpu_set(cpu, sibling_leaf->shared_cpu_map); - } - } - } - } -} -static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) -{ - struct _cpuid4_info *this_leaf, *sibling_leaf; - int sibling; - - this_leaf = CPUID4_INFO_IDX(cpu, index); - for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) { - sibling_leaf = CPUID4_INFO_IDX(sibling, index); - cpu_clear(cpu, sibling_leaf->shared_cpu_map); - } -} -#else -static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} -static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {} -#endif - -static void free_cache_attributes(unsigned int cpu) -{ - kfree(cpuid4_info[cpu]); - cpuid4_info[cpu] = NULL; -} - -static int __cpuinit detect_cache_attributes(unsigned int cpu) -{ - struct _cpuid4_info *this_leaf; - unsigned long j; - int retval; - cpumask_t oldmask; - - if (num_cache_leaves == 0) - return -ENOENT; - - cpuid4_info[cpu] = kmalloc( - sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); - if (unlikely(cpuid4_info[cpu] == NULL)) - return -ENOMEM; - memset(cpuid4_info[cpu], 0, - sizeof(struct _cpuid4_info) * num_cache_leaves); - - oldmask = current->cpus_allowed; - retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (retval) - goto out; - - /* Do cpuid and store the results */ - retval = 0; - for (j = 0; j < num_cache_leaves; j++) { - this_leaf = CPUID4_INFO_IDX(cpu, j); - retval = cpuid4_cache_lookup(j, this_leaf); - if (unlikely(retval < 0)) - break; - cache_shared_cpu_map_setup(cpu, j); - } - set_cpus_allowed(current, oldmask); - -out: - if (retval) - free_cache_attributes(cpu); - return retval; -} - -#ifdef CONFIG_SYSFS - -#include <linux/kobject.h> -#include <linux/sysfs.h> - -extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */ - -/* pointer to kobject for cpuX/cache */ -static struct kobject * cache_kobject[NR_CPUS]; - -struct _index_kobject { - struct kobject kobj; - unsigned int cpu; - unsigned short index; -}; - -/* pointer to array of kobjects for cpuX/cache/indexY */ -static struct _index_kobject *index_kobject[NR_CPUS]; -#define INDEX_KOBJECT_PTR(x,y) (&((index_kobject[x])[y])) - -#define show_one_plus(file_name, object, val) \ -static ssize_t show_##file_name \ - (struct _cpuid4_info *this_leaf, char *buf) \ -{ \ - return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \ -} - -show_one_plus(level, eax.split.level, 0); -show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1); -show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1); -show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1); -show_one_plus(number_of_sets, ecx.split.number_of_sets, 1); - -static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf) -{ - return sprintf (buf, "%luK\n", this_leaf->size / 1024); -} - -static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf) -{ - char mask_str[NR_CPUS]; - cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map); - return sprintf(buf, "%s\n", mask_str); -} - -static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) { - switch(this_leaf->eax.split.type) { - case CACHE_TYPE_DATA: - return sprintf(buf, "Data\n"); - break; - case CACHE_TYPE_INST: - return sprintf(buf, "Instruction\n"); - break; - case CACHE_TYPE_UNIFIED: - return sprintf(buf, "Unified\n"); - break; - default: - return sprintf(buf, "Unknown\n"); - break; - } -} - -struct _cache_attr { - struct attribute attr; - ssize_t (*show)(struct _cpuid4_info *, char *); - ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count); -}; - -#define define_one_ro(_name) \ -static struct _cache_attr _name = \ - __ATTR(_name, 0444, show_##_name, NULL) - -define_one_ro(level); -define_one_ro(type); -define_one_ro(coherency_line_size); -define_one_ro(physical_line_partition); -define_one_ro(ways_of_associativity); -define_one_ro(number_of_sets); -define_one_ro(size); -define_one_ro(shared_cpu_map); - -static struct attribute * default_attrs[] = { - &type.attr, - &level.attr, - &coherency_line_size.attr, - &physical_line_partition.attr, - &ways_of_associativity.attr, - &number_of_sets.attr, - &size.attr, - &shared_cpu_map.attr, - NULL -}; - -#define to_object(k) container_of(k, struct _index_kobject, kobj) -#define to_attr(a) container_of(a, struct _cache_attr, attr) - -static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) -{ - struct _cache_attr *fattr = to_attr(attr); - struct _index_kobject *this_leaf = to_object(kobj); - ssize_t ret; - - ret = fattr->show ? - fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), - buf) : - 0; - return ret; -} - -static ssize_t store(struct kobject * kobj, struct attribute * attr, - const char * buf, size_t count) -{ - return 0; -} - -static struct sysfs_ops sysfs_ops = { - .show = show, - .store = store, -}; - -static struct kobj_type ktype_cache = { - .sysfs_ops = &sysfs_ops, - .default_attrs = default_attrs, -}; - -static struct kobj_type ktype_percpu_entry = { - .sysfs_ops = &sysfs_ops, -}; - -static void cpuid4_cache_sysfs_exit(unsigned int cpu) -{ - kfree(cache_kobject[cpu]); - kfree(index_kobject[cpu]); - cache_kobject[cpu] = NULL; - index_kobject[cpu] = NULL; - free_cache_attributes(cpu); -} - -static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) -{ - - if (num_cache_leaves == 0) - return -ENOENT; - - detect_cache_attributes(cpu); - if (cpuid4_info[cpu] == NULL) - return -ENOENT; - - /* Allocate all required memory */ - cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL); - if (unlikely(cache_kobject[cpu] == NULL)) - goto err_out; - memset(cache_kobject[cpu], 0, sizeof(struct kobject)); - - index_kobject[cpu] = kmalloc( - sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); - if (unlikely(index_kobject[cpu] == NULL)) - goto err_out; - memset(index_kobject[cpu], 0, - sizeof(struct _index_kobject) * num_cache_leaves); - - return 0; - -err_out: - cpuid4_cache_sysfs_exit(cpu); - return -ENOMEM; -} - -/* Add/Remove cache interface for CPU device */ -static int __cpuinit cache_add_dev(struct sys_device * sys_dev) -{ - unsigned int cpu = sys_dev->id; - unsigned long i, j; - struct _index_kobject *this_object; - int retval = 0; - - retval = cpuid4_cache_sysfs_init(cpu); - if (unlikely(retval < 0)) - return retval; - - cache_kobject[cpu]->parent = &sys_dev->kobj; - kobject_set_name(cache_kobject[cpu], "%s", "cache"); - cache_kobject[cpu]->ktype = &ktype_percpu_entry; - retval = kobject_register(cache_kobject[cpu]); - - for (i = 0; i < num_cache_leaves; i++) { - this_object = INDEX_KOBJECT_PTR(cpu,i); - this_object->cpu = cpu; - this_object->index = i; - this_object->kobj.parent = cache_kobject[cpu]; - kobject_set_name(&(this_object->kobj), "index%1lu", i); - this_object->kobj.ktype = &ktype_cache; - retval = kobject_register(&(this_object->kobj)); - if (unlikely(retval)) { - for (j = 0; j < i; j++) { - kobject_unregister( - &(INDEX_KOBJECT_PTR(cpu,j)->kobj)); - } - kobject_unregister(cache_kobject[cpu]); - cpuid4_cache_sysfs_exit(cpu); - break; - } - } - return retval; -} - -static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) -{ - unsigned int cpu = sys_dev->id; - unsigned long i; - - for (i = 0; i < num_cache_leaves; i++) { - cache_remove_shared_cpu_map(cpu, i); - kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); - } - kobject_unregister(cache_kobject[cpu]); - cpuid4_cache_sysfs_exit(cpu); - return; -} - -static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - switch (action) { - case CPU_ONLINE: - cache_add_dev(sys_dev); - break; - case CPU_DEAD: - cache_remove_dev(sys_dev); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = -{ - .notifier_call = cacheinfo_cpu_callback, -}; - -static int __cpuinit cache_sysfs_init(void) -{ - int i; - - if (num_cache_leaves == 0) - return 0; - - register_hotcpu_notifier(&cacheinfo_cpu_notifier); - - for_each_online_cpu(i) { - cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE, - (void *)(long)i); - } - - return 0; -} - -device_initcall(cache_sysfs_init); - -#endif diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Wed Mar 07 12:38:28 2007 -0700 @@ -368,6 +368,7 @@ sysexit_scrit: /**** START OF SYSEXIT CR movl ESI(%esp), %esi sysexit 14: __DISABLE_INTERRUPTS + TRACE_IRQS_OFF sysexit_ecrit: /**** END OF SYSEXIT CRITICAL REGION ****/ push %esp call evtchn_do_upcall @@ -427,11 +428,13 @@ restore_nocheck: restore_nocheck: movl EFLAGS(%esp), %eax testl $(VM_MASK|NMI_MASK), %eax + CFI_REMEMBER_STATE jnz hypervisor_iret shr $9, %eax # EAX[0] == IRET_EFLAGS.IF GET_VCPU_INFO andb evtchn_upcall_mask(%esi),%al andb $1,%al # EAX[0] == IRET_EFLAGS.IF & event_mask + CFI_REMEMBER_STATE jnz restore_all_enable_events # != 0 => enable event delivery #endif TRACE_IRQS_IRET @@ -455,8 +458,8 @@ iret_exc: .long 1b,iret_exc .previous + CFI_RESTORE_STATE #ifndef CONFIG_XEN - CFI_RESTORE_STATE ldt_ss: larl OLDSS(%esp), %eax jnz restore_nocheck @@ -485,14 +488,36 @@ 1: iret .align 4 .long 1b,iret_exc .previous - CFI_ENDPROC #else + ALIGN +restore_all_enable_events: + TRACE_IRQS_ON + __ENABLE_INTERRUPTS +scrit: /**** START OF CRITICAL REGION ****/ + __TEST_PENDING + jnz 14f # process more events if necessary... + RESTORE_REGS + addl $4, %esp + CFI_ADJUST_CFA_OFFSET -4 +1: iret +.section __ex_table,"a" + .align 4 + .long 1b,iret_exc +.previous +14: __DISABLE_INTERRUPTS + TRACE_IRQS_OFF + jmp 11f +ecrit: /**** END OF CRITICAL REGION ****/ + + CFI_RESTORE_STATE hypervisor_iret: andl $~NMI_MASK, EFLAGS(%esp) RESTORE_REGS addl $4, %esp + CFI_ADJUST_CFA_OFFSET -4 jmp hypercall_page + (__HYPERVISOR_iret * 32) #endif + CFI_ENDPROC # perform work that needs to be done immediately before resumption ALIGN @@ -736,7 +761,9 @@ error_code: # critical region we know that the entire frame is present and correct # so we can simply throw away the new one. ENTRY(hypervisor_callback) + RING0_INT_FRAME pushl %eax + CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL movl EIP(%esp),%eax cmpl $scrit,%eax @@ -749,26 +776,13 @@ ENTRY(hypervisor_callback) ja 11f addl $OLDESP,%esp # Remove eflags...ebx from stack frame. 11: push %esp + CFI_ADJUST_CFA_OFFSET 4 call evtchn_do_upcall add $4,%esp + CFI_ADJUST_CFA_OFFSET -4 jmp ret_from_intr - - ALIGN -restore_all_enable_events: - __ENABLE_INTERRUPTS -scrit: /**** START OF CRITICAL REGION ****/ - __TEST_PENDING - jnz 14f # process more events if necessary... - RESTORE_REGS - addl $4, %esp -1: iret -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous -14: __DISABLE_INTERRUPTS - jmp 11b -ecrit: /**** END OF CRITICAL REGION ****/ + CFI_ENDPROC + # [How we do the fixup]. We want to merge the current stack frame with the # just-interrupted frame. How we do this depends on where in the critical # region the interrupted handler was executing, and so how many saved @@ -835,6 +849,7 @@ 4: mov 16(%esp),%gs addl $16,%esp # EAX != 0 => Category 2 (Bad IRET) jmp iret_exc 5: addl $16,%esp # EAX == 0 => Category 1 (Bad segment) + RING0_INT_FRAME pushl $0 SAVE_ALL jmp ret_from_exception @@ -860,6 +875,7 @@ 9: xorl %eax,%eax; \ .long 4b,9b; \ .previous #endif + CFI_ENDPROC ENTRY(coprocessor_error) RING0_INT_FRAME @@ -1187,8 +1203,11 @@ ENDPROC(arch_unwind_init_running) #endif ENTRY(fixup_4gb_segment) + RING0_EC_FRAME pushl $do_fixup_4gb_segment - jmp error_code + CFI_ADJUST_CFA_OFFSET 4 + jmp error_code + CFI_ENDPROC .section .rodata,"a" .align 4 diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/fixup.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Wed Mar 07 12:38:28 2007 -0700 @@ -27,7 +27,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/config.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/slab.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Wed Mar 07 12:38:28 2007 -0700 @@ -9,10 +9,9 @@ #include <asm/cache.h> #include <asm/thread_info.h> #include <asm/asm-offsets.h> +#include <asm/dwarf2.h> #include <xen/interface/xen.h> #include <xen/interface/elfnote.h> - -#define _PAGE_PRESENT 0x1 /* * References to members of the new_cpu_data structure. @@ -65,14 +64,13 @@ ENTRY(startup_32) pushl %eax # fake return address jmp start_kernel -L6: - jmp L6 # main should never return here, but - # just in case, we know what happens. #define HYPERCALL_PAGE_OFFSET 0x1000 .org HYPERCALL_PAGE_OFFSET ENTRY(hypercall_page) + CFI_STARTPROC .skip 0x1000 + CFI_ENDPROC /* * Real beginning of normal "text" segment @@ -206,3 +204,4 @@ ENTRY(cpu_gdt_table) ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, _PAGE_PRESENT,_PAGE_PRESENT) #endif ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") + ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -60,9 +60,6 @@ #include <asm/tlbflush.h> #include <asm/cpu.h> -#include <asm/tlbflush.h> -#include <asm/cpu.h> - asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); static int hlt_counter; @@ -104,7 +101,7 @@ EXPORT_SYMBOL(enable_hlt); * to poll the ->work.need_resched flag instead of waiting for the * cross-CPU IPI to arrive. Use this option with caution. */ -static void poll_idle(void) +static void poll_idle (void) { local_irq_enable(); @@ -172,10 +169,7 @@ void cpu_idle(void) __get_cpu_var(cpu_idle_state) = 0; rmb(); - idle = pm_idle; - - if (!idle) - idle = xen_idle; + idle = xen_idle; /* no alternatives */ if (cpu_is_offline(cpu)) play_dead(); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -1847,6 +1847,9 @@ static __init int add_pcspkr(void) struct platform_device *pd; int ret; + if (!is_initial_xendomain()) + return 0; + pd = platform_device_alloc("pcspkr", -1); if (!pd) return -ENOMEM; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -1022,16 +1022,21 @@ void halt(void) } EXPORT_SYMBOL(halt); -/* No locking required. We are only CPU running, and interrupts are off. */ +/* No locking required. Interrupts are disabled on all CPUs. */ void time_resume(void) { + unsigned int cpu; + init_cpu_khz(); - get_time_values_from_xen(0); + for_each_online_cpu(cpu) { + get_time_values_from_xen(cpu); + per_cpu(processed_system_time, cpu) = + per_cpu(shadow_time, 0).system_timestamp; + init_missing_ticks_accounting(cpu); + } processed_system_time = per_cpu(shadow_time, 0).system_timestamp; - per_cpu(processed_system_time, 0) = processed_system_time; - init_missing_ticks_accounting(0); update_wallclock(); } diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Mar 07 12:38:28 2007 -0700 @@ -30,7 +30,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/vmalloc.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -374,8 +374,6 @@ void iounmap(volatile void __iomem *addr } EXPORT_SYMBOL(iounmap); -#ifdef __i386__ - void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) { unsigned long offset, last_addr; @@ -443,5 +441,3 @@ void __init bt_iounmap(void *addr, unsig --nrpages; } } - -#endif /* __i386__ */ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -573,64 +573,67 @@ void make_pages_writable(void *va, unsig } } -static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags) +static inline void pgd_walk_set_prot(struct page *page, pgprot_t flags) { unsigned long pfn = page_to_pfn(page); - - if (PageHighMem(page)) - return pgprot_val(flags) & _PAGE_RW - ? test_and_clear_bit(PG_pinned, &page->flags) - : !test_and_set_bit(PG_pinned, &page->flags); - - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - pfn_pte(pfn, flags), 0)); - - return 0; -} - -static int pgd_walk(pgd_t *pgd_base, pgprot_t flags) + int rc; + + if (PageHighMem(page)) { + if (pgprot_val(flags) & _PAGE_RW) + clear_bit(PG_pinned, &page->flags); + else + set_bit(PG_pinned, &page->flags); + } else { + rc = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte(pfn, flags), 0); + if (rc) + BUG(); + } +} + +static void pgd_walk(pgd_t *pgd_base, pgprot_t flags) { pgd_t *pgd = pgd_base; pud_t *pud; pmd_t *pmd; - int g, u, m, flush; + int g, u, m, rc; if (xen_feature(XENFEAT_auto_translated_physmap)) return 0; - for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { + for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { if (pgd_none(*pgd)) continue; pud = pud_offset(pgd, 0); if (PTRS_PER_PUD > 1) /* not folded */ - flush |= pgd_walk_set_prot(virt_to_page(pud),flags); + pgd_walk_set_prot(virt_to_page(pud),flags); for (u = 0; u < PTRS_PER_PUD; u++, pud++) { if (pud_none(*pud)) continue; pmd = pmd_offset(pud, 0); if (PTRS_PER_PMD > 1) /* not folded */ - flush |= pgd_walk_set_prot(virt_to_page(pmd),flags); + pgd_walk_set_prot(virt_to_page(pmd),flags); for (m = 0; m < PTRS_PER_PMD; m++, pmd++) { if (pmd_none(*pmd)) continue; - flush |= pgd_walk_set_prot(pmd_page(*pmd),flags); + pgd_walk_set_prot(pmd_page(*pmd),flags); } } } - BUG_ON(HYPERVISOR_update_va_mapping( + rc = HYPERVISOR_update_va_mapping( (unsigned long)pgd_base, pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags), - UVMF_TLB_FLUSH)); - - return flush; + UVMF_TLB_FLUSH); + if (rc) + BUG(); } static void __pgd_pin(pgd_t *pgd) { - if (pgd_walk(pgd, PAGE_KERNEL_RO)) - kmap_flush_unused(); + pgd_walk(pgd, PAGE_KERNEL_RO); + kmap_flush_unused(); xen_pgd_pin(__pa(pgd)); set_bit(PG_pinned, &virt_to_page(pgd)->flags); } @@ -638,8 +641,7 @@ static void __pgd_unpin(pgd_t *pgd) static void __pgd_unpin(pgd_t *pgd) { xen_pgd_unpin(__pa(pgd)); - if (pgd_walk(pgd, PAGE_KERNEL)) - kmap_flush_unused(); + pgd_walk(pgd, PAGE_KERNEL); clear_bit(PG_pinned, &virt_to_page(pgd)->flags); } @@ -670,9 +672,6 @@ void mm_pin_all(void) void mm_pin_all(void) { struct page *page; - - /* Only pgds on the pgd_list please: none hidden in the slab cache. */ - kmem_cache_shrink(pgd_cache); if (xen_feature(XENFEAT_writable_page_tables)) return; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h Wed Mar 07 12:38:28 2007 -0700 @@ -1,7 +1,5 @@ #ifndef OPROFILE_PERFMON_H #define OPROFILE_PERFMON_H - -#include <linux/config.h> #ifdef CONFIG_PERFMON int __perfmon_init(void); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S Wed Mar 07 12:38:28 2007 -0700 @@ -4,7 +4,6 @@ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@xxxxxx> */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/asmmacro.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/mem.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/mem.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/mem.c Wed Mar 07 12:38:28 2007 -0700 @@ -15,7 +15,6 @@ * VA Linux Systems Japan K.K. */ -#include <linux/config.h> #include <linux/mm.h> #include <linux/efi.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/util.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/util.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/util.c Wed Mar 07 12:38:28 2007 -0700 @@ -21,7 +21,6 @@ * */ -#include <linux/config.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Wed Mar 07 12:38:28 2007 -0700 @@ -303,6 +303,7 @@ xencomm_privcmd_domctl(privcmd_hypercall case XEN_DOMCTL_hypercall_init: case XEN_DOMCTL_arch_setup: case XEN_DOMCTL_settimeoffset: + case XEN_DOMCTL_sendtrigger: break; default: printk("%s: unknown domctl cmd %d\n", __func__, kern_op.cmd); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Wed Mar 07 12:38:28 2007 -0700 @@ -7,8 +7,6 @@ * Copyright (C) 2005 Hewlett-Packard Co * Dan Magenheimer <dan.magenheimer@.hp.com> */ - -#include <linux/config.h> #include <asm/asmmacro.h> #include <asm/cache.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S Wed Mar 07 12:38:28 2007 -0700 @@ -28,8 +28,6 @@ * * Table is based upon EAS2.6 (Oct 1999) */ - -#include <linux/config.h> #include <asm/asmmacro.h> #include <asm/break.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/xenminstate.h --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenminstate.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenminstate.h Wed Mar 07 12:38:28 2007 -0700 @@ -1,5 +1,3 @@ -#include <linux/config.h> - #include <asm/cache.h> #ifdef CONFIG_XEN diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S Wed Mar 07 12:38:28 2007 -0700 @@ -4,7 +4,6 @@ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@xxxxxx> */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/asmmacro.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/Kconfig --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig Wed Mar 07 12:38:28 2007 -0700 @@ -450,7 +450,7 @@ config CALGARY_IOMMU bool "IBM Calgary IOMMU support" default y select SWIOTLB - depends on PCI && EXPERIMENTAL + depends on PCI && !X86_64_XEN && EXPERIMENTAL help Support for hardware IOMMUs in IBM's xSeries x366 and x460 systems. Needed to run systems with more than 3GB of memory diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -61,9 +61,7 @@ time-y += ../../i386/kernel/time-xen. time-y += ../../i386/kernel/time-xen.o pci-dma-y += ../../i386/kernel/pci-dma-xen.o microcode-$(subst m,y,$(CONFIG_MICROCODE)) := ../../i386/kernel/microcode-xen.o -intel_cacheinfo-y := ../../i386/kernel/cpu/intel_cacheinfo-xen.o quirks-y := ../../i386/kernel/quirks-xen.o -alternative-y := ../../i386/kernel/alternative-xen.o n-obj-xen := i8259.o reboot.o i8237.o smpboot.o trampoline.o diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/console.h> #include <linux/kernel.h> #include <linux/init.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Wed Mar 07 12:38:28 2007 -0700 @@ -116,19 +116,21 @@ NMI_MASK = 0x80000000 CFI_ADJUST_CFA_OFFSET -(6*8) .endm - .macro CFI_DEFAULT_STACK start=1 + .macro CFI_DEFAULT_STACK start=1,adj=0 .if \start CFI_STARTPROC simple - CFI_DEF_CFA rsp,SS+8 + CFI_DEF_CFA rsp,SS+8-(\adj*ARGOFFSET) .else - CFI_DEF_CFA_OFFSET SS+8 + CFI_DEF_CFA_OFFSET SS+8-(\adj*ARGOFFSET) .endif + .if \adj == 0 CFI_REL_OFFSET r15,R15 CFI_REL_OFFSET r14,R14 CFI_REL_OFFSET r13,R13 CFI_REL_OFFSET r12,R12 CFI_REL_OFFSET rbp,RBP CFI_REL_OFFSET rbx,RBX + .endif CFI_REL_OFFSET r11,R11 CFI_REL_OFFSET r10,R10 CFI_REL_OFFSET r9,R9 @@ -363,8 +365,8 @@ ENTRY(int_ret_from_sys_call) CFI_REL_OFFSET r9,R9-ARGOFFSET CFI_REL_OFFSET r10,R10-ARGOFFSET CFI_REL_OFFSET r11,R11-ARGOFFSET + XEN_BLOCK_EVENTS(%rsi) TRACE_IRQS_OFF - XEN_BLOCK_EVENTS(%rsi) testb $3,CS-ARGOFFSET(%rsp) jnz 1f /* Need to set the proper %ss (not NULL) for ring 3 iretq */ @@ -534,7 +536,7 @@ END(stub_rt_sigreturn) */ retint_check: - CFI_DEFAULT_STACK + CFI_DEFAULT_STACK adj=1 movl threadinfo_flags(%rcx),%edx andl %edi,%edx CFI_REMEMBER_STATE @@ -838,6 +840,7 @@ ENTRY(error_entry) CFI_REL_OFFSET r15,R15 #if 0 cmpl $__KERNEL_CS,CS(%rsp) + CFI_REMEMBER_STATE je error_kernelspace #endif error_call_handler: @@ -864,7 +867,7 @@ error_exit: TRACE_IRQS_IRETQ jmp retint_restore_args -error_kernelspace: +#if 0 /* * We need to re-write the logic here because we don't do iretq to * to return to user mode. It's still possible that we get trap/fault @@ -872,7 +875,8 @@ error_kernelspace: * for example). * */ -#if 0 + CFI_RESTORE_STATE +error_kernelspace: incl %ebx /* There are two places in the kernel that can potentially fault with usergs. Handle them here. The exception handlers after @@ -888,11 +892,13 @@ error_kernelspace: cmpq $gs_change,RIP(%rsp) je error_swapgs jmp error_sti -#endif +#endif + CFI_ENDPROC END(error_entry) ENTRY(hypervisor_callback) zeroentry do_hypervisor_callback +END(hypervisor_callback) /* * Copied from arch/xen/i386/kernel/entry.S @@ -909,48 +915,66 @@ ENTRY(hypervisor_callback) # existing activation in its critical region -- if so, we pop the current # activation and restart the handler using the previous one. ENTRY(do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) + CFI_STARTPROC # Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will # see the correct pointer to the pt_regs movq %rdi, %rsp # we don't return, adjust the stack frame -11: movq %gs:pda_irqstackptr,%rax - incl %gs:pda_irqcount - cmovzq %rax,%rsp - pushq %rdi + CFI_ENDPROC + CFI_DEFAULT_STACK +11: incl %gs:pda_irqcount + movq %rsp,%rbp + CFI_DEF_CFA_REGISTER rbp + cmovzq %gs:pda_irqstackptr,%rsp + pushq %rbp # backlink for old unwinder call evtchn_do_upcall popq %rsp + CFI_DEF_CFA_REGISTER rsp decl %gs:pda_irqcount jmp error_exit + CFI_ENDPROC +END(do_hypervisor_callback) #ifdef CONFIG_X86_LOCAL_APIC KPROBE_ENTRY(nmi) zeroentry do_nmi_callback ENTRY(do_nmi_callback) + CFI_STARTPROC addq $8, %rsp + CFI_ENDPROC + CFI_DEFAULT_STACK call do_nmi orl $NMI_MASK,EFLAGS(%rsp) RESTORE_REST XEN_BLOCK_EVENTS(%rsi) + TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) jmp retint_restore_args + CFI_ENDPROC .previous .text +END(nmi) #endif ALIGN restore_all_enable_events: + CFI_DEFAULT_STACK adj=1 + TRACE_IRQS_ON XEN_UNBLOCK_EVENTS(%rsi) # %rsi is already set up... scrit: /**** START OF CRITICAL REGION ****/ XEN_TEST_PENDING(%rsi) + CFI_REMEMBER_STATE jnz 14f # process more events if necessary... XEN_PUT_VCPU_INFO(%rsi) RESTORE_ARGS 0,8,0 HYPERVISOR_IRET 0 + CFI_RESTORE_STATE 14: XEN_LOCKED_BLOCK_EVENTS(%rsi) XEN_PUT_VCPU_INFO(%rsi) SAVE_REST movq %rsp,%rdi # set the argument again jmp 11b + CFI_ENDPROC ecrit: /**** END OF CRITICAL REGION ****/ # At this point, unlike on x86-32, we don't do the fixup to simplify the # code and the stack frame is more complex on x86-64. @@ -970,8 +994,12 @@ ecrit: /**** END OF CRITICAL REGION *** # We distinguish between categories by comparing each saved segment register # with its current contents: any discrepancy means we in category 1. ENTRY(failsafe_callback) + _frame (RIP-0x30) + CFI_REL_OFFSET rcx, 0 + CFI_REL_OFFSET r11, 8 movw %ds,%cx cmpw %cx,0x10(%rsp) + CFI_REMEMBER_STATE jne 1f movw %es,%cx cmpw %cx,0x18(%rsp) @@ -984,17 +1012,26 @@ ENTRY(failsafe_callback) jne 1f /* All segments match their saved values => Category 2 (Bad IRET). */ movq (%rsp),%rcx + CFI_RESTORE rcx movq 8(%rsp),%r11 + CFI_RESTORE r11 addq $0x30,%rsp + CFI_ADJUST_CFA_OFFSET -0x30 movq $11,%rdi /* SIGSEGV */ jmp do_exit + CFI_RESTORE_STATE 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ movq (%rsp),%rcx + CFI_RESTORE rcx movq 8(%rsp),%r11 + CFI_RESTORE r11 addq $0x30,%rsp + CFI_ADJUST_CFA_OFFSET -0x30 pushq $0 + CFI_ADJUST_CFA_OFFSET 8 SAVE_ALL jmp error_exit + CFI_ENDPROC #if 0 .section __ex_table,"a" .align 8 @@ -1117,12 +1154,12 @@ END(device_not_available) /* runs on exception stack */ KPROBE_ENTRY(debug) - INTR_FRAME -/* pushq $0 +/* INTR_FRAME + pushq $0 CFI_ADJUST_CFA_OFFSET 8 */ zeroentry do_debug -/* paranoid_exit */ - CFI_ENDPROC +/* paranoidexit + CFI_ENDPROC */ END(debug) .previous .text @@ -1144,12 +1181,12 @@ END(nmi) #endif KPROBE_ENTRY(int3) - INTR_FRAME -/* pushq $0 +/* INTR_FRAME + pushq $0 CFI_ADJUST_CFA_OFFSET 8 */ zeroentry do_int3 -/* jmp paranoid_exit1 */ - CFI_ENDPROC +/* jmp paranoid_exit1 + CFI_ENDPROC */ END(int3) .previous .text @@ -1193,9 +1230,11 @@ END(segment_not_present) /* runs on exception stack */ ENTRY(stack_segment) - XCPT_FRAME +/* XCPT_FRAME + paranoidentry do_stack_segment */ errorentry do_stack_segment - CFI_ENDPROC +/* jmp paranoid_exit1 + CFI_ENDPROC */ END(stack_segment) KPROBE_ENTRY(general_protection) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/genapic_xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/genapic_xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/genapic_xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -10,7 +10,6 @@ * * Hacked to pieces for Xen by Chris Wright. */ -#include <linux/config.h> #include <linux/threads.h> #include <linux/cpumask.h> #include <linux/string.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Wed Mar 07 12:38:28 2007 -0700 @@ -22,10 +22,8 @@ #include <asm/page.h> #include <asm/msr.h> #include <asm/cache.h> - +#include <asm/dwarf2.h> #include <xen/interface/elfnote.h> - -#define _PAGE_PRESENT 0x1 .section .bootstrap.text, "ax", @progbits .code64 @@ -42,6 +40,7 @@ ENTRY(_start) /* rsi is pointer to startup info structure. pass it to C */ movq %rsi,%rdi + pushq $0 # fake return address jmp x86_64_start_kernel ENTRY(stext) @@ -82,7 +81,25 @@ NEXT_PAGE(level2_kernel_pgt) .fill 512,8,0 NEXT_PAGE(hypercall_page) - .fill 512,8,0 + CFI_STARTPROC + .rept 0x1000 / 0x20 + .skip 1 /* push %rcx */ + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rcx,0 + .skip 2 /* push %r11 */ + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rcx,0 + .skip 5 /* mov $#,%eax */ + .skip 2 /* syscall */ + .skip 2 /* pop %r11 */ + CFI_ADJUST_CFA_OFFSET -8 + CFI_RESTORE r11 + .skip 1 /* pop %rcx */ + CFI_ADJUST_CFA_OFFSET -8 + CFI_RESTORE rcx + .align 0x20,0 /* ret */ + .endr + CFI_ENDPROC #undef NEXT_PAGE @@ -186,3 +203,4 @@ ENTRY(empty_zero_page) ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .quad, _PAGE_PRESENT,_PAGE_PRESENT) ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel") ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") + ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c Wed Mar 07 12:38:28 2007 -0700 @@ -47,11 +47,11 @@ EXPORT_SYMBOL(init_task); * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; -#endif /* Copies of the original ist values from the tss are only accessed during * debugging, no special alignment required. */ DEFINE_PER_CPU(struct orig_ist, orig_ist); +#endif #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) diff -r 8a58ea36e420 -r 50d5bf02e59e 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 Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -117,7 +117,7 @@ void exit_idle(void) * to poll the ->need_resched flag instead of waiting for the * cross-CPU IPI to arrive. Use this option with caution. */ -static void poll_idle(void) +static void poll_idle (void) { local_irq_enable(); @@ -179,9 +179,7 @@ void cpu_idle (void) if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; rmb(); - idle = pm_idle; - if (!idle) - idle = xen_idle; + idle = xen_idle; /* no alternatives */ if (cpu_is_offline(smp_processor_id())) play_dead(); enter_idle(); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -676,7 +676,8 @@ void __init setup_arch(char **cmdline_p) init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); - /* dmi_scan_machine(); */ + if (is_initial_xendomain()) + dmi_scan_machine(); #ifdef CONFIG_ACPI_NUMA /* @@ -691,6 +692,14 @@ void __init setup_arch(char **cmdline_p) contig_initmem_init(0, end_pfn); #endif +#ifdef CONFIG_XEN + /* + * Reserve kernel, physmap, start info, initial page tables, and + * direct mapping. + */ + reserve_bootmem_generic(__pa_symbol(&_text), + (table_end << PAGE_SHIFT) - __pa_symbol(&_text)); +#else /* Reserve direct mapping */ reserve_bootmem_generic(table_start << PAGE_SHIFT, (table_end - table_start) << PAGE_SHIFT); @@ -699,12 +708,6 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem_generic(__pa_symbol(&_text), __pa_symbol(&_end) - __pa_symbol(&_text)); -#ifdef CONFIG_XEN - /* reserve physmap, start info and initial page tables */ - reserve_bootmem_generic(__pa_symbol(&_end), - (table_start << PAGE_SHIFT) - - __pa_symbol(&_end)); -#else /* * reserve physical page 0 - it's a special BIOS page on many boxes, * enabling clean reboots, SMP operation, laptop functions. @@ -1625,13 +1628,6 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; -static int __init run_dmi_scan(void) -{ - dmi_scan_machine(); - return 0; -} -core_initcall(run_dmi_scan); - #if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE) #include <linux/platform_device.h> static __init int add_pcspkr(void) @@ -1639,6 +1635,9 @@ static __init int add_pcspkr(void) struct platform_device *pd; int ret; + if (!is_initial_xendomain()) + return 0; + pd = platform_device_alloc("pcspkr", -1); if (!pd) return -ENOMEM; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/x8664_ksyms-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* Exports for assembly files. - All C exports should go in the respective C files. */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/smp.h> - -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> - -EXPORT_SYMBOL(kernel_thread); - -EXPORT_SYMBOL(__down_failed); -EXPORT_SYMBOL(__down_failed_interruptible); -EXPORT_SYMBOL(__down_failed_trylock); -EXPORT_SYMBOL(__up_wakeup); - -EXPORT_SYMBOL(__get_user_1); -EXPORT_SYMBOL(__get_user_2); -EXPORT_SYMBOL(__get_user_4); -EXPORT_SYMBOL(__get_user_8); -EXPORT_SYMBOL(__put_user_1); -EXPORT_SYMBOL(__put_user_2); -EXPORT_SYMBOL(__put_user_4); -EXPORT_SYMBOL(__put_user_8); - -EXPORT_SYMBOL(copy_user_generic); -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(copy_to_user); - -EXPORT_SYMBOL(copy_page); -EXPORT_SYMBOL(clear_page); - -#ifdef CONFIG_SMP -extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); -extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); -EXPORT_SYMBOL(__write_lock_failed); -EXPORT_SYMBOL(__read_lock_failed); -#endif - -/* Export string functions. We normally rely on gcc builtin for most of these, - but gcc sometimes decides not to inline them. */ -#undef memcpy -#undef memset -#undef memmove - -extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * __memcpy(void *,const void *,__kernel_size_t); - -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(__memcpy); - -EXPORT_SYMBOL(empty_zero_page); - -EXPORT_SYMBOL(load_gs_index); - diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -102,13 +102,10 @@ static void __meminit early_make_page_re BUG(); } -void make_page_readonly(void *va, unsigned int feature) +static void __make_page_readonly(void *va) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep; unsigned long addr = (unsigned long) va; - - if (xen_feature(feature)) - return; pgd = pgd_offset_k(addr); pud = pud_offset(pgd, addr); @@ -120,16 +117,13 @@ void make_page_readonly(void *va, unsign xen_l1_entry_update(ptep, pte); /* fallback */ if ((addr >= VMALLOC_START) && (addr < VMALLOC_END)) - make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT), feature); -} - -void make_page_writable(void *va, unsigned int feature) + __make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT)); +} + +static void __make_page_writable(void *va) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep; unsigned long addr = (unsigned long) va; - - if (xen_feature(feature)) - return; pgd = pgd_offset_k(addr); pud = pud_offset(pgd, addr); @@ -141,7 +135,19 @@ void make_page_writable(void *va, unsign xen_l1_entry_update(ptep, pte); /* fallback */ if ((addr >= VMALLOC_START) && (addr < VMALLOC_END)) - make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT), feature); + __make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT)); +} + +void make_page_readonly(void *va, unsigned int feature) +{ + if (!xen_feature(feature)) + __make_page_readonly(va); +} + +void make_page_writable(void *va, unsigned int feature) +{ + if (!xen_feature(feature)) + __make_page_writable(va); } void make_pages_readonly(void *va, unsigned nr, unsigned int feature) @@ -150,7 +156,7 @@ void make_pages_readonly(void *va, unsig return; while (nr-- != 0) { - make_page_readonly(va, feature); + __make_page_readonly(va); va = (void*)((unsigned long)va + PAGE_SIZE); } } @@ -161,7 +167,7 @@ void make_pages_writable(void *va, unsig return; while (nr-- != 0) { - make_page_writable(va, feature); + __make_page_writable(va); va = (void*)((unsigned long)va + PAGE_SIZE); } } @@ -208,7 +214,11 @@ static __init void *spp_getpage(void) void *ptr; if (after_bootmem) ptr = (void *) get_zeroed_page(GFP_ATOMIC); - else + else if (start_pfn < table_end) { + ptr = __va(start_pfn << PAGE_SHIFT); + start_pfn++; + memset(ptr, 0, PAGE_SIZE); + } else ptr = alloc_bootmem_pages(PAGE_SIZE); if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":""); @@ -299,36 +309,26 @@ static __init void set_pte_phys_ma(unsig pmd = (pmd_t *) spp_getpage(); make_page_readonly(pmd, XENFEAT_writable_page_tables); - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); - if (pmd != pmd_offset(pud, 0)) { printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0)); return; } } pmd = pmd_offset(pud, vaddr); - if (pmd_none(*pmd)) { pte = (pte_t *) spp_getpage(); make_page_readonly(pte, XENFEAT_writable_page_tables); - set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); if (pte != pte_offset_kernel(pmd, 0)) { printk("PAGETABLE BUG #02!\n"); return; } } - new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot); + pte = pte_offset_kernel(pmd, vaddr); - - /* - * Note that the pte page is already RO, thus we want to use - * xen_l1_entry_update(), not set_pte(). - */ - xen_l1_entry_update(pte, - pfn_pte_ma(phys >> PAGE_SHIFT, prot)); + set_pte(pte, new_pte); /* * It's enough to flush this one mapping. @@ -404,6 +404,7 @@ static inline void __set_pte(pte_t *dst, static inline int make_readonly(unsigned long paddr) { + extern char __vsyscall_0; int readonly = 0; /* Make new page tables read-only. */ @@ -420,25 +421,45 @@ static inline int make_readonly(unsigned /* * No need for writable mapping of kernel image. This also ensures that * page and descriptor tables embedded inside don't have writable - * mappings. + * mappings. Exclude the vsyscall area here, allowing alternative + * instruction patching to work. */ - if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end))) + if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end)) + && !(paddr >= __pa_symbol(&__vsyscall_0) + && paddr < __pa_symbol(&__vsyscall_0) + PAGE_SIZE)) readonly = 1; return readonly; } +#ifndef CONFIG_XEN /* Must run before zap_low_mappings */ __init void *early_ioremap(unsigned long addr, unsigned long size) { - return ioremap(addr, size); + unsigned long map = round_down(addr, LARGE_PAGE_SIZE); + + /* actually usually some more */ + if (size >= LARGE_PAGE_SIZE) { + printk("SMBIOS area too long %lu\n", size); + return NULL; + } + set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); + map += LARGE_PAGE_SIZE; + set_pmd(temp_mappings[1].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); + __flush_tlb(); + return temp_mappings[0].address + (addr & (LARGE_PAGE_SIZE-1)); } /* To avoid virtual aliases later */ __init void early_iounmap(void *addr, unsigned long size) { - iounmap(addr); -} + if ((void *)round_down((unsigned long)addr, LARGE_PAGE_SIZE) != temp_mappings[0].address) + printk("early_iounmap: bad address %p\n", addr); + set_pmd(temp_mappings[0].pmd, __pmd(0)); + set_pmd(temp_mappings[1].pmd, __pmd(0)); + __flush_tlb(); +} +#endif static void __meminit phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) @@ -638,7 +659,7 @@ static void __init extend_init_mapping(u static void __init find_early_table_space(unsigned long end) { - unsigned long puds, pmds, ptes, tables; + unsigned long puds, pmds, ptes, tables; puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; @@ -656,6 +677,64 @@ static void __init find_early_table_spac early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n", end, table_start << PAGE_SHIFT, (table_start << PAGE_SHIFT) + tables); +} + +static void xen_finish_init_mapping(void) +{ + unsigned long i, start, end; + + /* Re-vector virtual addresses pointing into the initial + mapping to the just-established permanent ones. */ + xen_start_info = __va(__pa(xen_start_info)); + xen_start_info->pt_base = (unsigned long) + __va(__pa(xen_start_info->pt_base)); + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + phys_to_machine_mapping = + __va(__pa(xen_start_info->mfn_list)); + xen_start_info->mfn_list = (unsigned long) + phys_to_machine_mapping; + } + if (xen_start_info->mod_start) + xen_start_info->mod_start = (unsigned long) + __va(__pa(xen_start_info->mod_start)); + + /* Destroy the Xen-created mappings beyond the kernel image as + * well as the temporary mappings created above. Prevents + * overlap with modules area (if init mapping is very big). + */ + start = PAGE_ALIGN((unsigned long)_end); + end = __START_KERNEL_map + (table_end << PAGE_SHIFT); + for (; start < end; start += PAGE_SIZE) + WARN_ON(HYPERVISOR_update_va_mapping( + start, __pte_ma(0), 0)); + + /* Allocate pte's for initial fixmaps from 'start_pfn' allocator. */ + table_end = ~0UL; + + /* + * Prefetch pte's for the bt_ioremap() area. It gets used before the + * boot-time allocator is online, so allocate-on-demand would fail. + */ + for (i = FIX_BTMAP_END; i <= FIX_BTMAP_BEGIN; i++) + __set_fixmap(i, 0, __pgprot(0)); + + /* Switch to the real shared_info page, and clear the dummy page. */ + set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); + memset(empty_zero_page, 0, sizeof(empty_zero_page)); + + /* Set up mapping of lowest 1MB of physical memory. */ + for (i = 0; i < NR_FIX_ISAMAPS; i++) + if (is_initial_xendomain()) + set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE); + else + __set_fixmap(FIX_ISAMAP_BEGIN - i, + virt_to_mfn(empty_zero_page) + << PAGE_SHIFT, + PAGE_KERNEL_RO); + + /* Disable the 'start_pfn' allocator. */ + table_end = start_pfn; } /* Setup the direct mapping of the physical memory at PAGE_OFFSET. @@ -663,7 +742,7 @@ static void __init find_early_table_spac physical memory. To access them they are temporarily mapped. */ void __meminit init_memory_mapping(unsigned long start, unsigned long end) { - unsigned long next; + unsigned long next; Dprintk("init_memory_mapping\n"); @@ -702,31 +781,7 @@ void __meminit init_memory_mapping(unsig if (!after_bootmem) { BUG_ON(start_pfn != table_end); - - /* Re-vector virtual addresses pointing into the initial - mapping to the just-established permanent ones. */ - xen_start_info = __va(__pa(xen_start_info)); - xen_start_info->pt_base = (unsigned long) - __va(__pa(xen_start_info->pt_base)); - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - phys_to_machine_mapping = - __va(__pa(xen_start_info->mfn_list)); - xen_start_info->mfn_list = (unsigned long) - phys_to_machine_mapping; - } - if (xen_start_info->mod_start) - xen_start_info->mod_start = (unsigned long) - __va(__pa(xen_start_info->mod_start)); - - /* Destroy the Xen-created mappings beyond the kernel image as - * well as the temporary mappings created above. Prevents - * overlap with modules area (if init mapping is very big). - */ - start = PAGE_ALIGN((unsigned long)_end); - end = __START_KERNEL_map + (table_end << PAGE_SHIFT); - for (; start < end; start += PAGE_SIZE) - WARN_ON(HYPERVISOR_update_va_mapping( - start, __pte_ma(0), 0)); + xen_finish_init_mapping(); } __flush_tlb_all(); @@ -805,7 +860,6 @@ void __init paging_init(void) void __init paging_init(void) { unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; - int i; memory_present(0, 0, end_pfn); sparse_init(); @@ -813,22 +867,7 @@ void __init paging_init(void) free_area_init_node(0, NODE_DATA(0), zones, __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); - /* Switch to the real shared_info page, and clear the - * dummy page. */ - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); - HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); - memset(empty_zero_page, 0, sizeof(empty_zero_page)); - init_mm.context.pinned = 1; - - /* Setup mapping of lower 1st MB */ - for (i = 0; i < NR_FIX_ISAMAPS; i++) - if (is_initial_xendomain()) - set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE); - else - __set_fixmap(FIX_ISAMAP_BEGIN - i, - virt_to_mfn(empty_zero_page) << PAGE_SHIFT, - PAGE_KERNEL_RO); } #endif @@ -1028,11 +1067,6 @@ void __init mem_init(void) void free_init_pages(char *what, unsigned long begin, unsigned long end) { -#ifdef __DO_LATER__ - /* - * Some pages can be pinned, but some are not. Unpinning such pages - * triggers BUG(). - */ unsigned long addr; if (begin >= end) @@ -1044,25 +1078,27 @@ void free_init_pages(char *what, unsigne init_page_count(virt_to_page(addr)); memset((void *)(addr & ~(PAGE_SIZE-1)), POISON_FREE_INITMEM, PAGE_SIZE); - make_page_writable( - __va(__pa(addr)), XENFEAT_writable_page_tables); - /* - * Make pages from __PAGE_OFFSET address as well - */ - make_page_writable( - (void *)addr, XENFEAT_writable_page_tables); + if (addr >= __START_KERNEL_map) { + /* make_readonly() reports all kernel addresses. */ + __make_page_writable(__va(__pa(addr))); + if (HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) { + pgd_t *pgd = pgd_offset_k(addr); + pud_t *pud = pud_offset(pgd, addr); + pmd_t *pmd = pmd_offset(pud, addr); + pte_t *pte = pte_offset_kernel(pmd, addr); + + xen_l1_entry_update(pte, __pte(0)); /* fallback */ + } + } free_page(addr); totalram_pages++; } -#endif } void free_initmem(void) { -#ifdef __DO_LATER__ memset(__initdata_begin, POISON_FREE_INITDATA, __initdata_end - __initdata_begin); -#endif free_init_pages("unused kernel memory", (unsigned long)(&__init_begin), (unsigned long)(&__init_end)); @@ -1125,7 +1161,7 @@ int kern_addr_valid(unsigned long addr) if (pgd_none(*pgd)) return 0; - pud = pud_offset_k(pgd, addr); + pud = pud_offset(pgd, addr); if (pud_none(*pud)) return 0; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -24,10 +24,13 @@ static inline void mm_walk_set_prot(void { struct page *page = virt_to_page(pt); unsigned long pfn = page_to_pfn(page); - - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - pfn_pte(pfn, flags), 0)); + int rc; + + rc = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte(pfn, flags), 0); + if (rc) + BUG(); } static void mm_walk(struct mm_struct *mm, pgprot_t flags) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/char/mem.c --- a/linux-2.6-xen-sparse/drivers/char/mem.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/char/mem.c Wed Mar 07 12:38:28 2007 -0700 @@ -787,7 +787,7 @@ static const struct file_operations mem_ .open = open_mem, }; #else -extern struct file_operations mem_fops; +extern const struct file_operations mem_fops; #endif static const struct file_operations kmem_fops = { diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Wed Mar 07 12:38:28 2007 -0700 @@ -113,14 +113,13 @@ void __exit tpmif_exit(void); static inline int -tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len, +tx_buffer_copy(struct tx_buffer *txb, const u8 *src, int len, int isuserbuffer) { int copied = len; - if (len > txb->size) { + if (len > txb->size) copied = txb->size; - } if (isuserbuffer) { if (copy_from_user(txb->data, src, copied)) return -EFAULT; @@ -133,18 +132,20 @@ tx_buffer_copy(struct tx_buffer *txb, co 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; - } - } + struct tx_buffer *txb; + + txb = kzalloc(sizeof(struct tx_buffer), GFP_KERNEL); + if (!txb) + return NULL; + + 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; } @@ -160,37 +161,41 @@ static inline void tx_buffer_free(struct /************************************************************** Utility function for the tpm_private structure **************************************************************/ -static inline void tpm_private_init(struct tpm_private *tp) +static 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 void tpm_private_put(void) +{ + if (!atomic_dec_and_test(&my_priv->refcnt)) + return; + + 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 { + + if (my_priv) { atomic_inc(&my_priv->refcnt); - } + return my_priv; + } + + my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL); + if (!my_priv) + return NULL; + + tpm_private_init(my_priv); + err = tpmif_allocate_tx_buffers(my_priv); + if (err < 0) + tpm_private_put(); + return my_priv; } @@ -379,10 +384,8 @@ static int tpmfront_probe(struct xenbus_ return -ENOMEM; tp->chip = init_vtpm(&dev->dev, &tvd, tp); - - if (IS_ERR(tp->chip)) { + if (IS_ERR(tp->chip)) return PTR_ERR(tp->chip); - } err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%i", &handle); @@ -401,6 +404,7 @@ static int tpmfront_probe(struct xenbus_ tpm_private_put(); return err; } + return 0; } @@ -417,30 +421,34 @@ static int tpmfront_suspend(struct xenbu { struct tpm_private *tp = tpm_private_from_dev(&dev->dev); u32 ctr; - /* lock, so no app can send */ + + /* Take the lock, preventing any application from sending. */ mutex_lock(&suspend_lock); tp->is_suspended = 1; - for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 300; ctr++) { + for (ctr = 0; atomic_read(&tp->tx_busy); ctr++) { if ((ctr % 10) == 0) printk("TPM-FE [INFO]: Waiting for outstanding " "request.\n"); - /* - * Wait for a request to be responded to. - */ + /* Wait for a request to be responded to. */ interruptible_sleep_on_timeout(&tp->wait_q, 100); } - xenbus_switch_state(dev, XenbusStateClosing); - - 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; + + return 0; +} + +static int tpmfront_suspend_finish(struct tpm_private *tp) +{ + tp->is_suspended = 0; + /* Allow applications to send again. */ + mutex_unlock(&suspend_lock); + return 0; +} + +static int tpmfront_suspend_cancel(struct xenbus_device *dev) +{ + struct tpm_private *tp = tpm_private_from_dev(&dev->dev); + return tpmfront_suspend_finish(tp); } static int tpmfront_resume(struct xenbus_device *dev) @@ -484,6 +492,7 @@ static struct xenbus_driver tpmfront = { .resume = tpmfront_resume, .otherend_changed = backend_changed, .suspend = tpmfront_suspend, + .suspend_cancel = tpmfront_suspend_cancel, }; static void __init init_tpm_xenbus(void) @@ -514,9 +523,8 @@ static void tpmif_free_tx_buffers(struct { unsigned int i; - for (i = 0; i < TPMIF_TX_RING_SIZE; 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) @@ -536,9 +544,8 @@ static void tpmif_rx_action(unsigned lon received = tx->size; buffer = kmalloc(received, GFP_ATOMIC); - if (NULL == buffer) { + if (!buffer) goto exit; - } for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) { struct tx_buffer *txb = tp->tx_buffers[i]; @@ -547,9 +554,8 @@ static void tpmif_rx_action(unsigned lon tx = &tp->tx->ring[i].req; tocopy = tx->size; - if (tocopy > PAGE_SIZE) { + if (tocopy > PAGE_SIZE) tocopy = PAGE_SIZE; - } memcpy(&buffer[offset], txb->data, tocopy); @@ -607,12 +613,13 @@ static int tpm_xmit(struct tpm_private * struct tx_buffer *txb = tp->tx_buffers[i]; int copied; - if (NULL == txb) { + if (!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) { @@ -624,25 +631,26 @@ static int tpm_xmit(struct tpm_private * 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", + 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 */ + /* Get the granttable reference for this page. */ tx->ref = gnttab_claim_grant_reference(&gref_head); - - if (-ENOSPC == tx->ref) { + if (tx->ref == -ENOSPC) { spin_unlock_irq(&tp->tx_lock); - DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__); + 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*/); + gnttab_grant_foreign_access_ref(tx->ref, + tp->backend_id, + virt_to_mfn(txb->data), + 0 /*RW*/); wmb(); } @@ -660,15 +668,10 @@ static int tpm_xmit(struct tpm_private * 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(tp->chip, TPM_VD_STATUS_CONNECTED); - } else { - vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED); - } + /* Notify upper layer about the state of the connection to the BE. */ + vtpm_vd_status(tp->chip, (tp->is_connected + ? TPM_VD_STATUS_CONNECTED + : TPM_VD_STATUS_DISCONNECTED)); } @@ -679,20 +682,16 @@ static void tpmif_set_connected_state(st * should disconnect - assumption is that we will resume * The mutex keeps apps from sending. */ - if (is_connected == 0 && tp->is_suspended == 1) { + 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 == 1 && tp->is_suspended == 1) + tpmfront_suspend_finish(tp); if (is_connected != tp->is_connected) { tp->is_connected = is_connected; @@ -710,33 +709,24 @@ static void tpmif_set_connected_state(st static int __init tpmif_init(void) { - long rc = 0; struct tpm_private *tp; if (is_initial_xendomain()) return -EPERM; tp = tpm_private_get(); - if (!tp) { - rc = -ENOMEM; - goto failexit; - } + if (!tp) + return -ENOMEM; IPRINTK("Initialising the vTPM driver.\n"); - if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE, - &gref_head ) < 0) { - rc = -EFAULT; - goto gnttab_alloc_failed; + if (gnttab_alloc_grant_references(TPMIF_TX_RING_SIZE, + &gref_head) < 0) { + tpm_private_put(); + return -EFAULT; } init_tpm_xenbus(); return 0; - -gnttab_alloc_failed: - tpm_private_put(); -failexit: - - return (int)rc; } diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Mar 07 12:38:28 2007 -0700 @@ -32,7 +32,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c Wed Mar 07 12:38:28 2007 -0700 @@ -28,7 +28,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/capability.h> #include <linux/stat.h> #include <linux/sysdev.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/blkback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Mar 07 12:38:28 2007 -0700 @@ -27,7 +27,6 @@ #ifndef __BLKIF__BACKEND__COMMON_H__ #define __BLKIF__BACKEND__COMMON_H__ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/interrupt.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/blkfront/block.h --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Wed Mar 07 12:38:28 2007 -0700 @@ -35,7 +35,6 @@ #ifndef __XEN_DRIVERS_BLOCK_H__ #define __XEN_DRIVERS_BLOCK_H__ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Mar 07 12:38:28 2007 -0700 @@ -335,7 +335,7 @@ static int blktap_ioctl(struct inode *in unsigned int cmd, unsigned long arg); static unsigned int blktap_poll(struct file *file, poll_table *wait); -static struct file_operations blktap_fops = { +static const struct file_operations blktap_fops = { .owner = THIS_MODULE, .poll = blktap_poll, .ioctl = blktap_ioctl, diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/blktap/common.h --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Wed Mar 07 12:38:28 2007 -0700 @@ -27,7 +27,6 @@ #ifndef __BLKIF__BACKEND__COMMON_H__ #define __BLKIF__BACKEND__COMMON_H__ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/interrupt.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/char/mem.c --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Wed Mar 07 12:38:28 2007 -0700 @@ -8,7 +8,6 @@ * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@xxxxxxx> */ -#include <linux/config.h> #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/slab.h> @@ -195,7 +194,7 @@ static int open_mem(struct inode * inode return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } -struct file_operations mem_fops = { +const struct file_operations mem_fops = { .llseek = memory_lseek, .read = read_mem, .write = write_mem, diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Mar 07 12:38:28 2007 -0700 @@ -30,7 +30,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/errno.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c --- a/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Wed Mar 07 12:38:28 2007 -0700 @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -122,29 +121,19 @@ arch_initcall(setup_vcpu_hotplug_event); int smp_suspend(void) { - int i, err; + int cpu, err; - lock_cpu_hotplug(); - - /* - * Take all other CPUs offline. We hold the hotplug mutex to - * avoid other processes bringing up CPUs under our feet. - */ - while (num_online_cpus() > 1) { - unlock_cpu_hotplug(); - for_each_online_cpu(i) { - if (i == 0) - continue; - err = cpu_down(i); - if (err) { - printk(KERN_CRIT "Failed to take all CPUs " - "down: %d.\n", err); - for_each_possible_cpu(i) - vcpu_hotplug(i); - return err; - } + for_each_online_cpu(cpu) { + if (cpu == 0) + continue; + err = cpu_down(cpu); + if (err) { + printk(KERN_CRIT "Failed to take all CPUs " + "down: %d.\n", err); + for_each_possible_cpu(cpu) + vcpu_hotplug(cpu); + return err; } - lock_cpu_hotplug(); } return 0; @@ -153,11 +142,6 @@ void smp_resume(void) void smp_resume(void) { int cpu; - - for_each_possible_cpu(cpu) - cpu_initialize_context(cpu); - - unlock_cpu_hotplug(); for_each_possible_cpu(cpu) vcpu_hotplug(cpu); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Wed Mar 07 12:38:28 2007 -0700 @@ -30,7 +30,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/irq.h> #include <linux/interrupt.h> @@ -889,11 +888,67 @@ void unmask_evtchn(int port) } EXPORT_SYMBOL_GPL(unmask_evtchn); +static void restore_cpu_virqs(int cpu) +{ + struct evtchn_bind_virq bind_virq; + int virq, irq, evtchn; + + for (virq = 0; virq < NR_VIRQS; virq++) { + if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) + continue; + + BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0)); + + /* Get a new binding from Xen. */ + bind_virq.virq = virq; + bind_virq.vcpu = cpu; + 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; + irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn); + bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); + } +} + +static void restore_cpu_ipis(int cpu) +{ + struct evtchn_bind_ipi bind_ipi; + int ipi, irq, evtchn; + + for (ipi = 0; ipi < NR_IPIS; ipi++) { + if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) + continue; + + BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0)); + + /* Get a new binding from Xen. */ + bind_ipi.vcpu = cpu; + 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; + irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn); + bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); + + } +} + void irq_resume(void) { - struct evtchn_bind_virq bind_virq; - struct evtchn_bind_ipi bind_ipi; - int cpu, pirq, virq, ipi, irq, evtchn; + int cpu, pirq, irq, evtchn; init_evtchn_cpu_bindings(); @@ -904,16 +959,6 @@ void irq_resume(void) /* Check that no PIRQs are still bound. */ for (pirq = 0; pirq < NR_PIRQS; pirq++) BUG_ON(irq_info[pirq_to_irq(pirq)] != IRQ_UNBOUND); - - /* Secondary CPUs must have no VIRQ or IPI bindings. */ - for_each_possible_cpu(cpu) { - if (cpu == 0) - continue; - for (virq = 0; virq < NR_VIRQS; virq++) - BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1); - for (ipi = 0; ipi < NR_IPIS; ipi++) - BUG_ON(per_cpu(ipi_to_irq, cpu)[ipi] != -1); - } /* No IRQ <-> event-channel mappings. */ for (irq = 0; irq < NR_IRQS; irq++) @@ -921,50 +966,11 @@ void irq_resume(void) for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) evtchn_to_irq[evtchn] = -1; - /* Primary CPU: rebind VIRQs automatically. */ - for (virq = 0; virq < NR_VIRQS; virq++) { - if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1) - continue; - - BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0)); - - /* Get a new binding from Xen. */ - 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; - irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn); - - /* Ready for use. */ - unmask_evtchn(evtchn); - } - - /* Primary CPU: rebind IPIs automatically. */ - for (ipi = 0; ipi < NR_IPIS; ipi++) { - if ((irq = per_cpu(ipi_to_irq, 0)[ipi]) == -1) - continue; - - BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0)); - - /* Get a new binding from Xen. */ - 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; - irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn); - - /* Ready for use. */ - unmask_evtchn(evtchn); - } + for_each_possible_cpu(cpu) { + restore_cpu_virqs(cpu); + restore_cpu_ipis(cpu); + } + } void __init xen_init_IRQ(void) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/gnttab.c --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Mar 07 12:38:28 2007 -0700 @@ -31,7 +31,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/mm.h> @@ -518,25 +517,26 @@ static int gnttab_map(unsigned int start static int gnttab_map(unsigned int start_idx, unsigned int end_idx) { struct xen_add_to_physmap xatp; - unsigned int i; + unsigned int i = end_idx; /* Loop backwards, so that the first hypercall has the largest index, * ensuring that the table will grow only once. */ - for (i = end_idx; i >= start_idx; i--) { + do { xatp.domid = DOMID_SELF; xatp.idx = i; xatp.space = XENMAPSPACE_grant_table; xatp.gpfn = (resume_frames >> PAGE_SHIFT) + i; if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) BUG(); - } + } while (i-- > start_idx); + + return 0; } int gnttab_resume(void) { - struct xen_add_to_physmap xatp; - unsigned int i, max_nr_gframes, nr_gframes; + unsigned int max_nr_gframes, nr_gframes; nr_gframes = nr_grant_frames; max_nr_gframes = max_nr_grant_frames(); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c --- a/linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/hypervisor_sysfs.c Wed Mar 07 12:38:28 2007 -0700 @@ -7,7 +7,6 @@ * published by the Free Software Foundation. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/kobject.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Wed Mar 07 12:38:28 2007 -0700 @@ -1,4 +1,3 @@ -#define __KERNEL_SYSCALLS__ #include <linux/version.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -7,6 +6,7 @@ #include <linux/reboot.h> #include <linux/sysrq.h> #include <linux/stringify.h> +#include <linux/stop_machine.h> #include <asm/irq.h> #include <asm/mmu_context.h> #include <xen/evtchn.h> @@ -18,6 +18,7 @@ #include <xen/gnttab.h> #include <xen/xencons.h> #include <xen/cpu_hotplug.h> +#include <xen/interface/vcpu.h> #if defined(__i386__) || defined(__x86_64__) @@ -58,27 +59,11 @@ EXPORT_SYMBOL(machine_halt); EXPORT_SYMBOL(machine_halt); EXPORT_SYMBOL(machine_power_off); -/* Ensure we run on the idle task page tables so that we will - switch page tables before running user space. This is needed - on architectures with separate kernel and user page tables - because the user page table pointer is not saved/restored. */ -static void switch_idle_mm(void) -{ - struct mm_struct *mm = current->active_mm; - - if (mm == &init_mm) - return; - - atomic_inc(&init_mm.mm_count); - switch_mm(mm, &init_mm, current); - current->active_mm = &init_mm; - mmdrop(mm); -} - static void pre_suspend(void) { HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; - clear_fixmap(FIX_SHARED_INFO); + HYPERVISOR_update_va_mapping(fix_to_virt(FIX_SHARED_INFO), + __pte_ma(0), 0); xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = @@ -88,6 +73,7 @@ static void post_suspend(int suspend_can static void post_suspend(int suspend_cancelled) { int i, j, k, fpp; + unsigned long shinfo_mfn; extern unsigned long max_pfn; extern unsigned long *pfn_to_mfn_frame_list_list; extern unsigned long *pfn_to_mfn_frame_list[]; @@ -97,10 +83,15 @@ static void post_suspend(int suspend_can pfn_to_mfn(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = pfn_to_mfn(xen_start_info->console.domU.mfn); - } - - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); - + } else { +#ifdef CONFIG_SMP + cpu_initialized_map = cpumask_of_cpu(0); +#endif + } + + shinfo_mfn = xen_start_info->shared_info >> PAGE_SHIFT; + HYPERVISOR_update_va_mapping(fix_to_virt(FIX_SHARED_INFO), + pfn_pte_ma(shinfo_mfn, PAGE_KERNEL), 0); HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); memset(empty_zero_page, 0, PAGE_SIZE); @@ -130,11 +121,86 @@ static void post_suspend(int suspend_can #endif -int __xen_suspend(void) +static int take_machine_down(void *p_fast_suspend) +{ + int fast_suspend = *(int *)p_fast_suspend; + int suspend_cancelled, err, cpu; + extern void time_resume(void); + + if (fast_suspend) { + preempt_disable(); + } else { + for (;;) { + err = smp_suspend(); + if (err) + return err; + + xenbus_suspend(); + preempt_disable(); + + if (num_online_cpus() == 1) + break; + + preempt_enable(); + xenbus_suspend_cancel(); + } + } + + mm_pin_all(); + local_irq_disable(); + preempt_enable(); + gnttab_suspend(); + pre_suspend(); + + /* + * This hypercall returns 1 if suspend was cancelled or the domain was + * merely checkpointed, and 0 if it is resuming in a new domain. + */ + suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); + + post_suspend(suspend_cancelled); + gnttab_resume(); + if (!suspend_cancelled) { + irq_resume(); +#ifdef __x86_64__ + /* + * Older versions of Xen do not save/restore the user %cr3. + * We do it here just in case, but there's no need if we are + * in fast-suspend mode as that implies a new enough Xen. + */ + if (!fast_suspend) { + struct mmuext_op op; + op.cmd = MMUEXT_NEW_USER_BASEPTR; + op.arg1.mfn = pfn_to_mfn(__pa(__user_pgd( + current->active_mm->pgd)) >> PAGE_SHIFT); + if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) + BUG(); + } +#endif + } + time_resume(); + local_irq_enable(); + + if (fast_suspend && !suspend_cancelled) { + /* + * In fast-suspend mode the APs may not be brought back online + * when we resume. In that case we do it here. + */ + for_each_online_cpu(cpu) { + if (cpu == 0) + continue; + cpu_set_initialized(cpu); + err = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); + BUG_ON(err); + } + } + + return suspend_cancelled; +} + +int __xen_suspend(int fast_suspend) { int err, suspend_cancelled; - - extern void time_resume(void); BUG_ON(smp_processor_id() != 0); BUG_ON(in_interrupt()); @@ -147,41 +213,21 @@ int __xen_suspend(void) } #endif - err = smp_suspend(); - if (err) + /* If we are definitely UP then 'slow mode' is actually faster. */ + if (num_possible_cpus() == 1) + fast_suspend = 0; + + if (fast_suspend) { + xenbus_suspend(); + err = stop_machine_run(take_machine_down, &fast_suspend, 0); + } else { + err = take_machine_down(&fast_suspend); + } + + if (err < 0) return err; - xenbus_suspend(); - - preempt_disable(); - - mm_pin_all(); - local_irq_disable(); - preempt_enable(); - - gnttab_suspend(); - - pre_suspend(); - - /* - * This hypercall returns 1 if suspend was cancelled or the domain was - * merely checkpointed, and 0 if it is resuming in a new domain. - */ - suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); - - post_suspend(suspend_cancelled); - - gnttab_resume(); - - if (!suspend_cancelled) - irq_resume(); - - time_resume(); - - switch_idle_mm(); - - local_irq_enable(); - + suspend_cancelled = err; if (!suspend_cancelled) { xencons_resume(); xenbus_resume(); @@ -189,7 +235,8 @@ int __xen_suspend(void) xenbus_suspend_cancel(); } - smp_resume(); - - return err; -} + if (!fast_suspend) + smp_resume(); + + return 0; +} diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/reboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Wed Mar 07 12:38:28 2007 -0700 @@ -24,13 +24,16 @@ MODULE_LICENSE("Dual BSD/GPL"); /* Ignore multiple shutdown requests. */ static int shutting_down = SHUTDOWN_INVALID; +/* Can we leave APs online when we suspend? */ +static int fast_suspend; + static void __shutdown_handler(void *unused); static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); #ifdef CONFIG_XEN -int __xen_suspend(void); +int __xen_suspend(int fast_suspend); #else -#define __xen_suspend() (void)0 +#define __xen_suspend(fast_suspend) 0 #endif static int shutdown_process(void *__unused) @@ -44,7 +47,8 @@ static int shutdown_process(void *__unus if ((shutting_down == SHUTDOWN_POWEROFF) || (shutting_down == SHUTDOWN_HALT)) { - if (call_usermodehelper("/sbin/poweroff", poweroff_argv, envp, 0) < 0) { + if (call_usermodehelper("/sbin/poweroff", poweroff_argv, + envp, 0) < 0) { #ifdef CONFIG_XEN sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, @@ -61,7 +65,9 @@ static int shutdown_process(void *__unus static int xen_suspend(void *__unused) { - __xen_suspend(); + int err = __xen_suspend(fast_suspend); + if (err) + printk(KERN_ERR "Xen suspend failed (%d)\n", err); shutting_down = SHUTDOWN_INVALID; return 0; } @@ -193,6 +199,10 @@ static int setup_shutdown_watcher(struct { int err; + xenbus_scanf(XBT_NIL, "control", + "platform-feature-multiprocessor-suspend", + "%d", &fast_suspend); + err = register_xenbus_watch(&shutdown_watch); if (err) printk(KERN_ERR "Failed to set shutdown watcher\n"); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/smpboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Wed Mar 07 12:38:28 2007 -0700 @@ -6,7 +6,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -48,7 +47,7 @@ EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_online_map); cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); -static cpumask_t cpu_initialized_map; +cpumask_t cpu_initialized_map; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_data); @@ -186,7 +185,7 @@ static void cpu_bringup_and_idle(void) cpu_idle(); } -void cpu_initialize_context(unsigned int cpu) +static void cpu_initialize_context(unsigned int cpu) { vcpu_guest_context_t ctxt; struct task_struct *idle = idle_task(cpu); @@ -196,7 +195,7 @@ void cpu_initialize_context(unsigned int struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, cpu); #endif - if (cpu == 0) + if (cpu_test_and_set(cpu, cpu_initialized_map)) return; memset(&ctxt, 0, sizeof(ctxt)); @@ -418,10 +417,7 @@ int __devinit __cpu_up(unsigned int cpu) if (rc) return rc; - if (!cpu_isset(cpu, cpu_initialized_map)) { - cpu_set(cpu, cpu_initialized_map); - cpu_initialize_context(cpu); - } + cpu_initialize_context(cpu); if (num_online_cpus() == 1) alternatives_smp_switch(1); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Wed Mar 07 12:38:28 2007 -0700 @@ -1,5 +1,4 @@ -#include <linux/config.h> #include <linux/proc_fs.h> #include <xen/xen_proc.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Mar 07 12:38:28 2007 -0700 @@ -7,7 +7,6 @@ * published by the Free Software Foundation. */ -#include <linux/config.h> #include <linux/err.h> #include <linux/kernel.h> #include <linux/module.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Wed Mar 07 12:38:28 2007 -0700 @@ -31,7 +31,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -407,7 +406,7 @@ static int evtchn_release(struct inode * return 0; } -static struct file_operations evtchn_fops = { +static const struct file_operations evtchn_fops = { .owner = THIS_MODULE, .read = evtchn_read, .write = evtchn_write, diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Mar 07 12:38:28 2007 -0700 @@ -29,7 +29,6 @@ #ifndef __NETIF__BACKEND__COMMON_H__ #define __NETIF__BACKEND__COMMON_H__ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -100,8 +99,20 @@ typedef struct netif_st { struct net_device *dev; struct net_device_stats stats; + unsigned int carrier; + wait_queue_head_t waiting_to_free; } netif_t; + +/* + * Implement our own carrier flag: the network stack's version causes delays + * when the carrier is re-enabled (in particular, dev_activate() may not + * immediately be called, which can cause packet loss; also the etherbridge + * can be rather lazy in activating its port). + */ +#define netback_carrier_on(netif) ((netif)->carrier = 1) +#define netback_carrier_off(netif) ((netif)->carrier = 0) +#define netback_carrier_ok(netif) ((netif)->carrier) #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) @@ -121,7 +132,8 @@ int netif_map(netif_t *netif, unsigned l void netif_xenbus_init(void); -#define netif_schedulable(dev) (netif_running(dev) && netif_carrier_ok(dev)) +#define netif_schedulable(netif) \ + (netif_running((netif)->dev) && netback_carrier_ok(netif)) void netif_schedule_work(netif_t *netif); void netif_deschedule_work(netif_t *netif); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Mar 07 12:38:28 2007 -0700 @@ -66,16 +66,19 @@ static int net_open(struct net_device *d static int net_open(struct net_device *dev) { netif_t *netif = netdev_priv(dev); - if (netif_carrier_ok(dev)) + if (netback_carrier_ok(netif)) { __netif_up(netif); + netif_start_queue(dev); + } return 0; } static int net_close(struct net_device *dev) { netif_t *netif = netdev_priv(dev); - if (netif_carrier_ok(dev)) + if (netback_carrier_ok(netif)) __netif_down(netif); + netif_stop_queue(dev); return 0; } @@ -138,8 +141,6 @@ netif_t *netif_alloc(domid_t domid, unsi return ERR_PTR(-ENOMEM); } - netif_carrier_off(dev); - netif = netdev_priv(dev); memset(netif, 0, sizeof(*netif)); netif->domid = domid; @@ -147,6 +148,8 @@ netif_t *netif_alloc(domid_t domid, unsi atomic_set(&netif->refcnt, 1); init_waitqueue_head(&netif->waiting_to_free); netif->dev = dev; + + netback_carrier_off(netif); netif->credit_bytes = netif->remaining_credit = ~0UL; netif->credit_usec = 0UL; @@ -285,7 +288,7 @@ int netif_map(netif_t *netif, unsigned l netif_get(netif); rtnl_lock(); - netif_carrier_on(netif->dev); + netback_carrier_on(netif); if (netif_running(netif->dev)) __netif_up(netif); rtnl_unlock(); @@ -302,9 +305,10 @@ err_rx: void netif_disconnect(netif_t *netif) { - if (netif_carrier_ok(netif->dev)) { + if (netback_carrier_ok(netif)) { rtnl_lock(); - netif_carrier_off(netif->dev); + netback_carrier_off(netif); + netif_carrier_off(netif->dev); /* discard queued packets */ if (netif_running(netif->dev)) __netif_down(netif); rtnl_unlock(); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netback/loopback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Mar 07 12:38:28 2007 -0700 @@ -45,7 +45,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/netdevice.h> #include <linux/inetdevice.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Mar 07 12:38:28 2007 -0700 @@ -38,7 +38,10 @@ #include <xen/balloon.h> #include <xen/interface/memory.h> -/*#define NETBE_DEBUG_INTERRUPT*/ +/*define NETBE_DEBUG_INTERRUPT*/ + +/* extra field used in struct page */ +#define netif_page_index(pg) (*(long *)&(pg)->mapping) struct netbk_rx_meta { skb_frag_t frag; @@ -231,7 +234,7 @@ static void tx_queue_callback(unsigned l static void tx_queue_callback(unsigned long data) { netif_t *netif = (netif_t *)data; - if (netif_schedulable(netif->dev)) + if (netif_schedulable(netif)) netif_wake_queue(netif->dev); } @@ -242,7 +245,7 @@ int netif_be_start_xmit(struct sk_buff * BUG_ON(skb->dev != dev); /* Drop the packet if the target domain has no receive buffers. */ - if (unlikely(!netif_schedulable(dev) || netbk_queue_full(netif))) + if (unlikely(!netif_schedulable(netif) || netbk_queue_full(netif))) goto drop; /* @@ -352,7 +355,7 @@ static u16 netbk_gop_frag(netif_t *netif copy_gop->flags = GNTCOPY_dest_gref; if (PageForeign(page)) { struct pending_tx_info *src_pend = - &pending_tx_info[page->index]; + &pending_tx_info[netif_page_index(page)]; copy_gop->source.domid = src_pend->netif->domid; copy_gop->source.u.ref = src_pend->req.gref; copy_gop->flags |= GNTCOPY_source_gref; @@ -681,7 +684,7 @@ static void net_rx_action(unsigned long } if (netif_queue_stopped(netif->dev) && - netif_schedulable(netif->dev) && + netif_schedulable(netif) && !netbk_queue_full(netif)) netif_wake_queue(netif->dev); @@ -739,7 +742,7 @@ static void add_to_net_schedule_list_tai spin_lock_irq(&net_schedule_list_lock); if (!__on_net_schedule_list(netif) && - likely(netif_schedulable(netif->dev))) { + likely(netif_schedulable(netif))) { list_add_tail(&netif->list, &net_schedule_list); netif_get(netif); } @@ -1327,7 +1330,7 @@ static void netif_page_release(struct pa /* Ready for next use. */ init_page_count(page); - netif_idx_release(page->index); + netif_idx_release(netif_page_index(page)); } irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) @@ -1337,7 +1340,7 @@ irqreturn_t netif_be_int(int irq, void * add_to_net_schedule_list_tail(netif); maybe_schedule_tx_action(); - if (netif_schedulable(netif->dev) && !netbk_queue_full(netif)) + if (netif_schedulable(netif) && !netbk_queue_full(netif)) netif_wake_queue(netif->dev); return IRQ_HANDLED; @@ -1457,7 +1460,7 @@ static int __init netback_init(void) for (i = 0; i < MAX_PENDING_REQS; i++) { page = mmap_pages[i]; SetPageForeign(page, netif_page_release); - page->index = i; + netif_page_index(page) = i; } pending_cons = 0; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Mar 07 12:38:28 2007 -0700 @@ -338,9 +338,7 @@ static void connect(struct backend_info xenbus_switch_state(dev, XenbusStateConnected); - /* May not get a kick from the frontend, so start the tx_queue now. */ - if (!netbk_can_queue(be->netif->dev)) - netif_wake_queue(be->netif->dev); + netif_wake_queue(be->netif->dev); } diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Mar 07 12:38:28 2007 -0700 @@ -29,7 +29,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/version.h> #include <linux/kernel.h> @@ -155,6 +154,7 @@ struct netfront_info { unsigned int irq; unsigned int copying_receiver; + unsigned int carrier; /* Receive-ring batched refills. */ #define RX_MIN_TARGET 8 @@ -192,6 +192,15 @@ struct netfront_rx_info { struct netif_rx_response rx; struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; }; + +/* + * Implement our own carrier flag: the network stack's version causes delays + * when the carrier is re-enabled (in particular, dev_activate() may not + * immediately be called, which can cause packet loss). + */ +#define netfront_carrier_on(netif) ((netif)->carrier = 1) +#define netfront_carrier_off(netif) ((netif)->carrier = 0) +#define netfront_carrier_ok(netif) ((netif)->carrier) /* * Access macros for acquiring freeing slots in tx_skbs[]. @@ -591,6 +600,22 @@ static int send_fake_arp(struct net_devi return dev_queue_xmit(skb); } +static inline int netfront_tx_slot_available(struct netfront_info *np) +{ + return ((np->tx.req_prod_pvt - np->tx.rsp_cons) < + (TX_MAX_TARGET - MAX_SKB_FRAGS - 2)); +} + +static inline void network_maybe_wake_tx(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + + if (unlikely(netif_queue_stopped(dev)) && + netfront_tx_slot_available(np) && + likely(netif_running(dev))) + netif_wake_queue(dev); +} + static int network_open(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); @@ -598,7 +623,7 @@ static int network_open(struct net_devic memset(&np->stats, 0, sizeof(np->stats)); spin_lock(&np->rx_lock); - if (netif_carrier_ok(dev)) { + if (netfront_carrier_ok(np)) { network_alloc_rx_buffers(dev); np->rx.sring->rsp_event = np->rx.rsp_cons + 1; if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) @@ -606,25 +631,9 @@ static int network_open(struct net_devic } spin_unlock(&np->rx_lock); - netif_start_queue(dev); + network_maybe_wake_tx(dev); return 0; -} - -static inline int netfront_tx_slot_available(struct netfront_info *np) -{ - return ((np->tx.req_prod_pvt - np->tx.rsp_cons) < - (TX_MAX_TARGET - MAX_SKB_FRAGS - 2)); -} - -static inline void network_maybe_wake_tx(struct net_device *dev) -{ - struct netfront_info *np = netdev_priv(dev); - - if (unlikely(netif_queue_stopped(dev)) && - netfront_tx_slot_available(np) && - likely(netif_running(dev))) - netif_wake_queue(dev); } static void network_tx_buf_gc(struct net_device *dev) @@ -634,7 +643,7 @@ static void network_tx_buf_gc(struct net struct netfront_info *np = netdev_priv(dev); struct sk_buff *skb; - BUG_ON(!netif_carrier_ok(dev)); + BUG_ON(!netfront_carrier_ok(np)); do { prod = np->tx.sring->rsp_prod; @@ -704,7 +713,7 @@ static void network_alloc_rx_buffers(str int nr_flips; netif_rx_request_t *req; - if (unlikely(!netif_carrier_ok(dev))) + if (unlikely(!netfront_carrier_ok(np))) return; /* @@ -935,7 +944,7 @@ static int network_start_xmit(struct sk_ spin_lock_irq(&np->tx_lock); - if (unlikely(!netif_carrier_ok(dev) || + if (unlikely(!netfront_carrier_ok(np) || (frags > 1 && !xennet_can_sg(dev)) || netif_needs_gso(dev, skb))) { spin_unlock_irq(&np->tx_lock); @@ -1025,7 +1034,7 @@ static irqreturn_t netif_int(int irq, vo spin_lock_irqsave(&np->tx_lock, flags); - if (likely(netif_carrier_ok(dev))) { + if (likely(netfront_carrier_ok(np))) { network_tx_buf_gc(dev); /* Under tx_lock: protects access to rx shared-ring indexes. */ if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) @@ -1300,7 +1309,7 @@ static int netif_poll(struct net_device spin_lock(&np->rx_lock); - if (unlikely(!netif_carrier_ok(dev))) { + if (unlikely(!netfront_carrier_ok(np))) { spin_unlock(&np->rx_lock); return 0; } @@ -1318,7 +1327,7 @@ static int netif_poll(struct net_device work_done = 0; while ((i != rp) && (work_done < budget)) { memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx)); - memset(extras, 0, sizeof(extras)); + memset(extras, 0, sizeof(rinfo.extras)); err = xennet_get_responses(np, &rinfo, rp, &tmpq, &pages_flipped); @@ -1745,7 +1754,7 @@ static int network_connect(struct net_de * domain a kick because we've probably just requeued some * packets. */ - netif_carrier_on(dev); + netfront_carrier_on(np); notify_remote_via_irq(np->irq); network_tx_buf_gc(dev); network_alloc_rx_buffers(dev); @@ -1990,7 +1999,7 @@ static struct net_device * __devinit cre np->netdev = netdev; - netif_carrier_off(netdev); + netfront_carrier_off(np); return netdev; @@ -2024,7 +2033,7 @@ static void netif_disconnect_backend(str /* Stop old i/f to prevent errors whilst we rebuild the state. */ spin_lock_irq(&info->tx_lock); spin_lock(&info->rx_lock); - netif_carrier_off(info->netdev); + netfront_carrier_off(info); spin_unlock(&info->rx_lock); spin_unlock_irq(&info->tx_lock); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Wed Mar 07 12:38:28 2007 -0700 @@ -239,17 +239,12 @@ static void free_root_bus_devs(struct pc { struct pci_dev *dev; - down_write(&pci_bus_sem); while (!list_empty(&bus->devices)) { - dev = container_of(bus->devices.next, struct pci_dev, bus_list); - up_write(&pci_bus_sem); - + dev = container_of(bus->devices.next, struct pci_dev, + bus_list); dev_dbg(&dev->dev, "removing device\n"); pci_remove_bus_device(dev); - - down_write(&pci_bus_sem); - } - up_write(&pci_bus_sem); + } } void pcifront_free_roots(struct pcifront_device *pdev) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Wed Mar 07 12:38:28 2007 -0700 @@ -6,7 +6,6 @@ * Copyright (c) 2002-2004, K A Fraser, B Dragovic */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/slab.h> @@ -249,7 +248,7 @@ static int privcmd_enforce_singleshot_ma } #endif -static struct file_operations privcmd_file_ops = { +static const struct file_operations privcmd_file_ops = { .ioctl = privcmd_ioctl, .mmap = privcmd_mmap, }; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/tpmback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Mar 07 12:38:28 2007 -0700 @@ -2,10 +2,9 @@ * drivers/xen/tpmback/common.h */ -#ifndef __NETIF__BACKEND__COMMON_H__ -#define __NETIF__BACKEND__COMMON_H__ +#ifndef __TPM__BACKEND__COMMON_H__ +#define __TPM__BACKEND__COMMON_H__ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/interrupt.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Mar 07 12:38:28 2007 -0700 @@ -629,7 +629,7 @@ static unsigned int vtpm_op_poll(struct return flags; } -static struct file_operations vtpm_ops = { +static const struct file_operations vtpm_ops = { .owner = THIS_MODULE, .llseek = no_llseek, .open = vtpm_op_open, diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/util.c --- a/linux-2.6-xen-sparse/drivers/xen/util.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/util.c Wed Mar 07 12:38:28 2007 -0700 @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Mar 07 12:38:28 2007 -0700 @@ -137,6 +137,17 @@ int xb_write(const void *data, unsigned return 0; } +int xb_data_to_read(void) +{ + struct xenstore_domain_interface *intf = xen_store_interface; + return (intf->rsp_cons != intf->rsp_prod); +} + +int xb_wait_for_data_to_read(void) +{ + return wait_event_interruptible(xb_waitq, xb_data_to_read()); +} + int xb_read(void *data, unsigned len) { struct xenstore_domain_interface *intf = xen_store_interface; @@ -147,9 +158,7 @@ int xb_read(void *data, unsigned len) unsigned int avail; const char *src; - rc = wait_event_interruptible( - xb_waitq, - intf->rsp_cons != intf->rsp_prod); + rc = xb_wait_for_data_to_read(); if (rc < 0) return rc; @@ -191,7 +200,19 @@ int xb_read(void *data, unsigned len) /* Set up interrupt handler off store event channel. */ int xb_init_comms(void) { + struct xenstore_domain_interface *intf = xen_store_interface; int err; + + if (intf->req_prod != intf->req_cons) + printk(KERN_ERR "XENBUS request ring is not quiescent " + "(%08x:%08x)!\n", intf->req_cons, intf->req_prod); + + if (intf->rsp_prod != intf->rsp_cons) { + printk(KERN_WARNING "XENBUS response ring is not quiescent " + "(%08x:%08x): fixing up\n", + intf->rsp_cons, intf->rsp_prod); + intf->rsp_cons = intf->rsp_prod; + } if (xenbus_irq) unbind_from_irqhandler(xenbus_irq, &xb_waitq); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Wed Mar 07 12:38:28 2007 -0700 @@ -37,6 +37,8 @@ int xb_init_comms(void); /* Low level routines. */ int xb_write(const void *data, unsigned len); int xb_read(void *data, unsigned len); +int xb_data_to_read(void); +int xb_wait_for_data_to_read(void); int xs_input_avail(void); extern struct xenstore_domain_interface *xen_store_interface; extern int xen_store_evtchn; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Mar 07 12:38:28 2007 -0700 @@ -32,7 +32,6 @@ * IN THE SOFTWARE. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/uio.h> @@ -174,17 +173,22 @@ static ssize_t xenbus_dev_write(struct f void *reply; char *path, *token; struct watch_adapter *watch, *tmp_watch; - int err; - - if ((len + u->len) > sizeof(u->u.buffer)) - return -EINVAL; - - if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) - return -EFAULT; + int err, rc = len; + + if ((len + u->len) > sizeof(u->u.buffer)) { + rc = -EINVAL; + goto out; + } + + if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) { + rc = -EFAULT; + goto out; + } u->len += len; - if (u->len < (sizeof(u->u.msg) + u->u.msg.len)) - return len; + if ((u->len < sizeof(u->u.msg)) || + (u->len < (sizeof(u->u.msg) + u->u.msg.len))) + return rc; msg_type = u->u.msg.type; @@ -202,14 +206,17 @@ static ssize_t xenbus_dev_write(struct f case XS_SET_PERMS: if (msg_type == XS_TRANSACTION_START) { trans = kmalloc(sizeof(*trans), GFP_KERNEL); - if (!trans) - return -ENOMEM; + if (!trans) { + rc = -ENOMEM; + goto out; + } } reply = xenbus_dev_request_and_reply(&u->u.msg); if (IS_ERR(reply)) { kfree(trans); - return PTR_ERR(reply); + rc = PTR_ERR(reply); + goto out; } if (msg_type == XS_TRANSACTION_START) { @@ -232,8 +239,10 @@ static ssize_t xenbus_dev_write(struct f case XS_UNWATCH: path = u->u.buffer + sizeof(u->u.msg); token = memchr(path, 0, u->u.msg.len); - if (token == NULL) - return -EILSEQ; + if (token == NULL) { + rc = -EILSEQ; + goto out; + } token++; if (msg_type == XS_WATCH) { @@ -252,7 +261,8 @@ static ssize_t xenbus_dev_write(struct f err = register_xenbus_watch(&watch->watch); if (err) { free_watch_adapter(watch); - return err; + rc = err; + goto out; } list_add(&watch->list, &u->watches); @@ -266,7 +276,6 @@ static ssize_t xenbus_dev_write(struct f &u->watches, list) { if (!strcmp(watch->token, token) && !strcmp(watch->watch.node, path)) - break; { unregister_xenbus_watch(&watch->watch); list_del(&watch->list); @@ -279,11 +288,13 @@ static ssize_t xenbus_dev_write(struct f break; default: - return -EINVAL; - } - + rc = -EINVAL; + break; + } + + out: u->len = 0; - return len; + return rc; } static int xenbus_dev_open(struct inode *inode, struct file *filp) @@ -343,7 +354,7 @@ static unsigned int xenbus_dev_poll(stru return 0; } -static struct file_operations xenbus_dev_file_ops = { +static const struct file_operations xenbus_dev_file_ops = { .read = xenbus_dev_read, .write = xenbus_dev_write, .open = xenbus_dev_open, diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Mar 07 12:38:28 2007 -0700 @@ -77,11 +77,22 @@ struct xs_handle { spinlock_t reply_lock; wait_queue_head_t reply_waitq; + /* + * Mutex ordering: transaction_mutex -> watch_mutex -> request_mutex. + * response_mutex is never taken simultaneously with the other three. + */ + /* One request at a time. */ struct mutex request_mutex; + /* Protect xenbus reader thread against save/restore. */ + struct mutex response_mutex; + /* Protect transactions against save/restore. */ - struct rw_semaphore suspend_mutex; + struct rw_semaphore transaction_mutex; + + /* Protect watch (de)register against save/restore. */ + struct rw_semaphore watch_mutex; }; static struct xs_handle xs_state; @@ -150,22 +161,6 @@ static void *read_reply(enum xsd_sockmsg return body; } -/* Emergency write. */ -void xenbus_debug_write(const char *str, unsigned int count) -{ - struct xsd_sockmsg msg = { 0 }; - - msg.type = XS_DEBUG; - msg.len = sizeof("print") + count + 1; - - mutex_lock(&xs_state.request_mutex); - xb_write(&msg, sizeof(msg)); - xb_write("print", sizeof("print")); - xb_write(str, count); - xb_write("", 1); - mutex_unlock(&xs_state.request_mutex); -} - void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) { void *ret; @@ -173,7 +168,7 @@ void *xenbus_dev_request_and_reply(struc int err; if (req_msg.type == XS_TRANSACTION_START) - down_read(&xs_state.suspend_mutex); + down_read(&xs_state.transaction_mutex); mutex_lock(&xs_state.request_mutex); @@ -189,7 +184,7 @@ void *xenbus_dev_request_and_reply(struc if ((req_msg.type == XS_TRANSACTION_END) || ((req_msg.type == XS_TRANSACTION_START) && (msg->type == XS_ERROR))) - up_read(&xs_state.suspend_mutex); + up_read(&xs_state.transaction_mutex); return ret; } @@ -440,11 +435,11 @@ int xenbus_transaction_start(struct xenb { char *id_str; - down_read(&xs_state.suspend_mutex); + down_read(&xs_state.transaction_mutex); id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL); if (IS_ERR(id_str)) { - up_read(&xs_state.suspend_mutex); + up_read(&xs_state.transaction_mutex); return PTR_ERR(id_str); } @@ -469,7 +464,7 @@ int xenbus_transaction_end(struct xenbus err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL)); - up_read(&xs_state.suspend_mutex); + up_read(&xs_state.transaction_mutex); return err; } @@ -602,7 +597,7 @@ int register_xenbus_watch(struct xenbus_ sprintf(token, "%lX", (long)watch); - down_read(&xs_state.suspend_mutex); + down_read(&xs_state.watch_mutex); spin_lock(&watches_lock); BUG_ON(find_watch(token)); @@ -618,7 +613,7 @@ int register_xenbus_watch(struct xenbus_ spin_unlock(&watches_lock); } - up_read(&xs_state.suspend_mutex); + up_read(&xs_state.watch_mutex); return err; } @@ -632,7 +627,7 @@ void unregister_xenbus_watch(struct xenb sprintf(token, "%lX", (long)watch); - down_read(&xs_state.suspend_mutex); + down_read(&xs_state.watch_mutex); spin_lock(&watches_lock); BUG_ON(!find_watch(token)); @@ -645,7 +640,7 @@ void unregister_xenbus_watch(struct xenb "XENBUS Failed to release watch %s: %i\n", watch->node, err); - up_read(&xs_state.suspend_mutex); + up_read(&xs_state.watch_mutex); /* Cancel pending watch events. */ spin_lock(&watch_events_lock); @@ -668,8 +663,10 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watc void xs_suspend(void) { - down_write(&xs_state.suspend_mutex); + down_write(&xs_state.transaction_mutex); + down_write(&xs_state.watch_mutex); mutex_lock(&xs_state.request_mutex); + mutex_lock(&xs_state.response_mutex); } void xs_resume(void) @@ -677,21 +674,25 @@ void xs_resume(void) struct xenbus_watch *watch; char token[sizeof(watch) * 2 + 1]; + mutex_unlock(&xs_state.response_mutex); mutex_unlock(&xs_state.request_mutex); - - /* No need for watches_lock: the suspend_mutex is sufficient. */ + up_write(&xs_state.transaction_mutex); + + /* No need for watches_lock: the watch_mutex is sufficient. */ list_for_each_entry(watch, &watches, list) { sprintf(token, "%lX", (long)watch); xs_watch(watch->node, token); } - up_write(&xs_state.suspend_mutex); + up_write(&xs_state.watch_mutex); } void xs_suspend_cancel(void) { + mutex_unlock(&xs_state.response_mutex); mutex_unlock(&xs_state.request_mutex); - up_write(&xs_state.suspend_mutex); + up_write(&xs_state.watch_mutex); + up_write(&xs_state.transaction_mutex); } static int xenwatch_handle_callback(void *data) @@ -753,27 +754,46 @@ static int process_msg(void) char *body; int err; + /* + * We must disallow save/restore while reading a xenstore message. + * A partial read across s/r leaves us out of sync with xenstored. + */ + for (;;) { + err = xb_wait_for_data_to_read(); + if (err) + return err; + mutex_lock(&xs_state.response_mutex); + if (xb_data_to_read()) + break; + /* We raced with save/restore: pending data 'disappeared'. */ + mutex_unlock(&xs_state.response_mutex); + } + + msg = kmalloc(sizeof(*msg), GFP_KERNEL); - if (msg == NULL) - return -ENOMEM; + if (msg == NULL) { + err = -ENOMEM; + goto out; + } err = xb_read(&msg->hdr, sizeof(msg->hdr)); if (err) { kfree(msg); - return err; + goto out; } body = kmalloc(msg->hdr.len + 1, GFP_KERNEL); if (body == NULL) { kfree(msg); - return -ENOMEM; + err = -ENOMEM; + goto out; } err = xb_read(body, msg->hdr.len); if (err) { kfree(body); kfree(msg); - return err; + goto out; } body[msg->hdr.len] = '\0'; @@ -782,7 +802,8 @@ static int process_msg(void) &msg->u.watch.vec_size); if (IS_ERR(msg->u.watch.vec)) { kfree(msg); - return PTR_ERR(msg->u.watch.vec); + err = PTR_ERR(msg->u.watch.vec); + goto out; } spin_lock(&watches_lock); @@ -806,7 +827,9 @@ static int process_msg(void) wake_up(&xs_state.reply_waitq); } - return 0; + out: + mutex_unlock(&xs_state.response_mutex); + return err; } static int xenbus_thread(void *unused) @@ -835,7 +858,9 @@ int xs_init(void) init_waitqueue_head(&xs_state.reply_waitq); mutex_init(&xs_state.request_mutex); - init_rwsem(&xs_state.suspend_mutex); + mutex_init(&xs_state.response_mutex); + init_rwsem(&xs_state.transaction_mutex); + init_rwsem(&xs_state.watch_mutex); /* Initialize the shared memory rings to talk to xenstored */ err = xb_init_comms(); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Wed Mar 07 12:38:28 2007 -0700 @@ -6,7 +6,6 @@ * documentation. */ -#include <linux/config.h> #include <linux/mm.h> #include <asm/cache.h> #include <asm/io.h> diff -r 8a58ea36e420 -r 50d5bf02e59e 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 Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Wed Mar 07 12:38:28 2007 -0700 @@ -33,7 +33,6 @@ #ifndef __HYPERVISOR_H__ #define __HYPERVISOR_H__ -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/version.h> @@ -57,7 +56,11 @@ extern shared_info_t *HYPERVISOR_shared_ extern shared_info_t *HYPERVISOR_shared_info; #define vcpu_info(cpu) (HYPERVISOR_shared_info->vcpu_info + (cpu)) +#ifdef CONFIG_SMP #define current_vcpu_info() vcpu_info(smp_processor_id()) +#else +#define current_vcpu_info() vcpu_info(0) +#endif #ifdef CONFIG_X86_32 extern unsigned long hypervisor_virt_start; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Wed Mar 07 12:38:28 2007 -0700 @@ -20,6 +20,14 @@ #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT) #ifdef __KERNEL__ + +/* + * Need to repeat this here in order to not include pgtable.h (which in turn + * depends on definitions made here), but to be able to use the symbolic + * below. The preprocessor will warn if the two definitions aren't identical. + */ +#define _PAGE_PRESENT 0x001 + #ifndef __ASSEMBLY__ #include <linux/string.h> @@ -28,13 +36,6 @@ #include <asm/bug.h> #include <xen/interface/xen.h> #include <xen/features.h> - -/* - * Need to repeat this here in order to not include pgtable.h (which in turn - * depends on definitions made here), but to be able to use the symbolic - * below. The preprocessor will warn if the two definitions aren't identical. - */ -#define _PAGE_PRESENT 0x001 #define arch_free_page(_page,_order) \ ({ int foreign = PageForeign(_page); \ @@ -139,7 +140,11 @@ static inline unsigned long pgd_val(pgd_ static inline unsigned long pgd_val(pgd_t x) { unsigned long ret = x.pgd; +#ifdef CONFIG_XEN_COMPAT_030002 + if (ret) ret = machine_to_phys(ret) | _PAGE_PRESENT; +#else if (ret & _PAGE_PRESENT) ret = machine_to_phys(ret); +#endif return ret; } #define HPAGE_SHIFT 22 @@ -221,8 +226,6 @@ extern int page_is_ram(unsigned long pag ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define __HAVE_ARCH_GATE_AREA 1 - #include <asm-generic/memory_model.h> #include <asm-generic/page.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h Wed Mar 07 12:38:28 2007 -0700 @@ -1,7 +1,5 @@ #ifndef _ASM_SWIOTLB_H #define _ASM_SWIOTLB_H 1 - -#include <linux/config.h> /* SWIOTLB interface */ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Mar 07 12:38:28 2007 -0700 @@ -6,8 +6,6 @@ * Heavily modified to provide guaranteed strong synchronisation * when communicating with Xen or other guest OSes running on other CPUs. */ - -#include <linux/config.h> #ifdef HAVE_XEN_PLATFORM_COMPAT_H #include <xen/platform-compat.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Wed Mar 07 12:38:28 2007 -0700 @@ -137,7 +137,7 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" }) #define write_cr4(x) \ - __asm__ __volatile__("movl %0,%%cr4": :"r" (x)); + __asm__ __volatile__("movl %0,%%cr4": :"r" (x)) /* * Clear and set 'TS' bit respectively diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Wed Mar 07 12:38:28 2007 -0700 @@ -46,7 +46,6 @@ extern int running_on_xen; #endif /* CONFIG_XEN */ #if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST) -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/version.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-ia64/swiotlb.h --- a/linux-2.6-xen-sparse/include/asm-ia64/swiotlb.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-ia64/swiotlb.h Wed Mar 07 12:38:28 2007 -0700 @@ -1,7 +1,5 @@ #ifndef _ASM_SWIOTLB_H #define _ASM_SWIOTLB_H 1 - -#include <linux/config.h> /* SWIOTLB interface */ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h --- a/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h Wed Mar 07 12:38:28 2007 -0700 @@ -6,8 +6,6 @@ * Heavily modified to provide guaranteed strong synchronisation * when communicating with Xen or other guest OSes running on other CPUs. */ - -#include <linux/config.h> #define ADDR (*(volatile long *) addr) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h Wed Mar 07 12:38:28 2007 -0700 @@ -53,6 +53,11 @@ enum fixed_addresses { #define NR_FIX_ISAMAPS 256 FIX_ISAMAP_END, FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1, + __end_of_permanent_fixed_addresses, + /* temporary boot-time mappings, used before ioremap() is functional */ +#define NR_FIX_BTMAPS 16 + FIX_BTMAP_END = __end_of_permanent_fixed_addresses, + FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1, __end_of_fixed_addresses }; diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h Wed Mar 07 12:38:28 2007 -0700 @@ -150,8 +150,10 @@ static inline void __iomem * ioremap (un return __ioremap(offset, size, 0); } -extern void *early_ioremap(unsigned long addr, unsigned long size); -extern void early_iounmap(void *addr, unsigned long size); +extern void *bt_ioremap(unsigned long addr, unsigned long size); +extern void bt_iounmap(void *addr, unsigned long size); +#define early_ioremap bt_ioremap +#define early_iounmap bt_iounmap /* * This one maps high address device memory and turns off caching for that area. diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irq.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irq.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irq.h Wed Mar 07 12:38:28 2007 -0700 @@ -10,7 +10,6 @@ * <tomsoft@xxxxxxxxxxxxxxxxxxxxxxxxx> */ -#include <linux/config.h> #include <linux/sched.h> /* include comes from machine specific directory */ #include "irq_vectors.h" diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Wed Mar 07 12:38:28 2007 -0700 @@ -403,19 +403,6 @@ static inline int pmd_large(pmd_t pte) { /* to find an entry in a page-table-directory. */ #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) #define pud_offset(pgd, address) ((pud_t *) pgd_page(*(pgd)) + pud_index(address)) -static inline pud_t *__pud_offset_k(pud_t *pud, unsigned long address) -{ - return pud + pud_index(address); -} - -/* Find correct pud via the hidden fourth level page level: */ - -/* This accesses the reference page table of the boot cpu. - Other CPUs get synced lazily via the page fault handler. */ -static inline pud_t *pud_offset_k(pgd_t *pgd, unsigned long address) -{ - return pud_offset(pgd_offset_k(address), address); -} /* PMD - Level 2 access */ #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK)) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h Wed Mar 07 12:38:28 2007 -0700 @@ -246,11 +246,13 @@ DECLARE_PER_CPU(struct tss_struct,init_t extern struct cpuinfo_x86 boot_cpu_data; +#ifndef CONFIG_X86_NO_TSS /* Save the original ist values for checking stack pointers during debugging */ struct orig_ist { unsigned long ist[7]; }; DECLARE_PER_CPU(struct orig_ist, orig_ist); +#endif #ifdef CONFIG_X86_VSMP #define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT) diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/linux/page-flags.h --- a/linux-2.6-xen-sparse/include/linux/page-flags.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/linux/page-flags.h Wed Mar 07 12:38:28 2007 -0700 @@ -252,14 +252,14 @@ #define PageForeign(page) test_bit(PG_foreign, &(page)->flags) #define SetPageForeign(page, dtor) do { \ set_bit(PG_foreign, &(page)->flags); \ - (page)->mapping = (void *)dtor; \ + (page)->index = (long)(dtor); \ } while (0) #define ClearPageForeign(page) do { \ clear_bit(PG_foreign, &(page)->flags); \ - (page)->mapping = NULL; \ + (page)->index = 0; \ } while (0) #define PageForeignDestructor(page) \ - ( (void (*) (struct page *)) (page)->mapping )(page) + ( (void (*) (struct page *)) (page)->index )(page) struct page; /* forward declaration */ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/cpu_hotplug.h --- a/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h Wed Mar 07 12:38:28 2007 -0700 @@ -1,17 +1,17 @@ #ifndef __XEN_CPU_HOTPLUG_H__ #define __XEN_CPU_HOTPLUG_H__ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/cpumask.h> +#if defined(CONFIG_X86) && defined(CONFIG_SMP) +extern cpumask_t cpu_initialized_map; +#define cpu_set_initialized(cpu) cpu_set(cpu, cpu_initialized_map) +#else +#define cpu_set_initialized(cpu) ((void)0) +#endif + #if defined(CONFIG_HOTPLUG_CPU) - -#if defined(CONFIG_X86) -void cpu_initialize_context(unsigned int cpu); -#else -#define cpu_initialize_context(cpu) ((void)0) -#endif int cpu_up_check(unsigned int cpu); void init_xenbus_allowed_cpumask(void); diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/driver_util.h --- a/linux-2.6-xen-sparse/include/xen/driver_util.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/driver_util.h Wed Mar 07 12:38:28 2007 -0700 @@ -2,7 +2,6 @@ #ifndef __ASM_XEN_DRIVER_UTIL_H__ #define __ASM_XEN_DRIVER_UTIL_H__ -#include <linux/config.h> #include <linux/vmalloc.h> /* Allocate/destroy a 'vmalloc' VM area. */ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/evtchn.h --- a/linux-2.6-xen-sparse/include/xen/evtchn.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/evtchn.h Wed Mar 07 12:38:28 2007 -0700 @@ -34,7 +34,6 @@ #ifndef __ASM_EVTCHN_H__ #define __ASM_EVTCHN_H__ -#include <linux/config.h> #include <linux/interrupt.h> #include <asm/hypervisor.h> #include <asm/ptrace.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/gnttab.h --- a/linux-2.6-xen-sparse/include/xen/gnttab.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Wed Mar 07 12:38:28 2007 -0700 @@ -37,7 +37,6 @@ #ifndef __ASM_GNTTAB_H__ #define __ASM_GNTTAB_H__ -#include <linux/config.h> #include <asm/hypervisor.h> #include <asm/maddr.h> /* maddr_t */ #include <xen/interface/grant_table.h> diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/pcifront.h --- a/linux-2.6-xen-sparse/include/xen/pcifront.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/pcifront.h Wed Mar 07 12:38:28 2007 -0700 @@ -6,7 +6,6 @@ #ifndef __XEN_ASM_PCIFRONT_H__ #define __XEN_ASM_PCIFRONT_H__ -#include <linux/config.h> #include <linux/spinlock.h> #ifdef __KERNEL__ diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/include/xen/xen_proc.h --- a/linux-2.6-xen-sparse/include/xen/xen_proc.h Thu Mar 01 15:02:09 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/xen_proc.h Wed Mar 07 12:38:28 2007 -0700 @@ -2,7 +2,6 @@ #ifndef __ASM_XEN_PROC_H__ #define __ASM_XEN_PROC_H__ -#include <linux/config.h> #include <linux/proc_fs.h> extern struct proc_dir_entry *create_xen_proc_entry( diff -r 8a58ea36e420 -r 50d5bf02e59e linux-2.6-xen-sparse/mm/Kconfig --- a/linux-2.6-xen-sparse/mm/Kconfig Thu Mar 01 15:02:09 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -config SELECT_MEMORY_MODEL - def_bool y - depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL - -choice - prompt "Memory model" - depends on SELECT_MEMORY_MODEL - default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT - default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT - default FLATMEM_MANUAL - -config FLATMEM_MANUAL - bool "Flat Memory" - depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE - help - This option allows you to change some of the ways that - Linux manages its memory internally. Most users will - only have one option here: FLATMEM. This is normal - and a correct option. - - Some users of more advanced features like NUMA and - memory hotplug may have different options here. - DISCONTIGMEM is an more mature, better tested system, - but is incompatible with memory hotplug and may suffer - decreased performance over SPARSEMEM. If unsure between - "Sparse Memory" and "Discontiguous Memory", choose - "Discontiguous Memory". - - If unsure, choose this option (Flat Memory) over any other. - -config DISCONTIGMEM_MANUAL - bool "Discontiguous Memory" - depends on ARCH_DISCONTIGMEM_ENABLE - help - This option provides enhanced support for discontiguous - memory systems, over FLATMEM. These systems have holes - in their physical address spaces, and this option provides - more efficient handling of these holes. However, the vast - majority of hardware has quite flat address spaces, and - can have degraded performance from extra overhead that - this option imposes. - - Many NUMA configurations will have this as the only option. - - If unsure, choose "Flat Memory" over this option. - -config SPARSEMEM_MANUAL - bool "Sparse Memory" - depends on ARCH_SPARSEMEM_ENABLE - help - This will be the only option for some systems, including - memory hotplug systems. This is normal. - - For many other systems, this will be an alternative to - "Discontiguous Memory". This option provides some potential - performance benefits, along with decreased code complexity, - but it is newer, and more experimental. - - If unsure, choose "Discontiguous Memory" or "Flat Memory" - over this option. - -endchoice - -config DISCONTIGMEM - def_bool y - depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL - -config SPARSEMEM - def_bool y - depends on SPARSEMEM_MANUAL - -config FLATMEM - def_bool y - depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL - -config FLAT_NODE_MEM_MAP - def_bool y - depends on !SPARSEMEM - -# -# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's -# to represent different areas of memory. This variable allows -# those dependencies to exist individually. -# -config NEED_MULTIPLE_NODES - def_bool y - depends on DISCONTIGMEM || NUMA - -config HAVE_MEMORY_PRESENT - def_bool y - depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM - -# -# SPARSEMEM_EXTREME (which is the default) does some bootmem -# allocations when memory_present() is called. If this can not -# be done on your architecture, select this option. However, -# statically allocating the mem_section[] array can potentially -# consume vast quantities of .bss, so be careful. -# -# This option will also potentially produce smaller runtime code -# with gcc 3.4 and later. -# -config SPARSEMEM_STATIC - def_bool n - -# -# Architectecture platforms which require a two level mem_section in SPARSEMEM -# must select this option. This is usually for architecture platforms with -# an extremely sparse physical address space. -# -config SPARSEMEM_EXTREME - def_bool y - depends on SPARSEMEM && !SPARSEMEM_STATIC - -# eventually, we can have this option just 'select SPARSEMEM' -config MEMORY_HOTPLUG - bool "Allow for memory hot-add" - depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG - depends on (IA64 || X86 || PPC64) - -comment "Memory hotplug is currently incompatible with Software Suspend" - depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND - -# Heavily threaded applications may benefit from splitting the mm-wide -# page_table_lock, so that faults on different parts of the user address -# space can be handled with less contention: split it at this NR_CPUS. -# Default to 4 for wider testing, though 8 might be more appropriate. -# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock. -# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes. -# XEN on x86 architecture uses the mapping field on pagetable pages to store a -# pointer to the destructor. This conflicts with pte_lock_deinit(). -# -config SPLIT_PTLOCK_CPUS - int - default "4096" if ARM && !CPU_CACHE_VIPT - default "4096" if PARISC && !PA20 - default "4096" if X86_XEN || X86_64_XEN - default "4" - -# -# support for page migration -# -config MIGRATION - bool "Page migration" - def_bool y - depends on NUMA - help - Allows the migration of the physical location of pages of processes - while the virtual addresses are not changed. This is useful for - example on NUMA systems to put pages nearer to the processors accessing - the page. - -config RESOURCES_64BIT - bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL) - default 64BIT - help - This option allows memory and IO resources to be 64 bit. diff -r 8a58ea36e420 -r 50d5bf02e59e patches/linux-2.6.18/blktap-aio-16_03_06.patch --- a/patches/linux-2.6.18/blktap-aio-16_03_06.patch Thu Mar 01 15:02:09 2007 -0700 +++ b/patches/linux-2.6.18/blktap-aio-16_03_06.patch Wed Mar 07 12:38:28 2007 -0700 @@ -106,7 +106,7 @@ diff -pruN ../orig-linux-2.6.18/fs/aio.c + return pollflags; +} + -+static struct file_operations aioq_fops = { ++static const struct file_operations aioq_fops = { + .release = aio_queue_fd_close, + .poll = aio_queue_fd_poll +}; @@ -201,7 +201,7 @@ diff -pruN ../orig-linux-2.6.18/fs/event int maxevents, long timeout); static int eventpollfs_delete_dentry(struct dentry *dentry); -static struct inode *ep_eventpoll_inode(void); -+static struct inode *ep_eventpoll_inode(struct file_operations *fops); ++static struct inode *ep_eventpoll_inode(const struct file_operations *fops); static int eventpollfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt); @@ -221,7 +221,7 @@ diff -pruN ../orig-linux-2.6.18/fs/event -static int ep_getfd(int *efd, struct inode **einode, struct file **efile, - struct eventpoll *ep) +int ep_getfd(int *efd, struct inode **einode, struct file **efile, -+ struct eventpoll *ep, struct file_operations *fops) ++ struct eventpoll *ep, const struct file_operations *fops) { struct qstr this; char name[32]; @@ -248,7 +248,7 @@ diff -pruN ../orig-linux-2.6.18/fs/event -static struct inode *ep_eventpoll_inode(void) -+static struct inode *ep_eventpoll_inode(struct file_operations *fops) ++static struct inode *ep_eventpoll_inode(const struct file_operations *fops) { int error = -ENOMEM; struct inode *inode = new_inode(eventpoll_mnt->mnt_sb); @@ -288,7 +288,7 @@ diff -pruN ../orig-linux-2.6.18/include/ + */ +struct eventpoll; +int ep_getfd(int *efd, struct inode **einode, struct file **efile, -+ struct eventpoll *ep, struct file_operations *fops); ++ struct eventpoll *ep, const struct file_operations *fops); #else static inline void eventpoll_init_file(struct file *file) {} diff -r 8a58ea36e420 -r 50d5bf02e59e tools/Makefile --- a/tools/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -24,9 +24,8 @@ SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen # These don't cross-compile ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) -SUBDIRS-y += python -SUBDIRS-y += pygrub -SUBDIRS-y += ptsname +SUBDIRS-$(PYTHON_TOOLS) += python +SUBDIRS-$(PYTHON_TOOLS) += pygrub endif .PHONY: all @@ -42,8 +41,8 @@ install: check $(MAKE) -C $$subdir $@; \ done $(MAKE) ioemuinstall - $(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump - $(INSTALL_DIR) -p $(DESTDIR)/var/log/xen + $(INSTALL_DIR) $(DESTDIR)/var/xen/dump + $(INSTALL_DIR) $(DESTDIR)/var/log/xen .PHONY: clean clean: check_clean diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/blktapctrl.c --- a/tools/blktap/drivers/blktapctrl.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/blktapctrl.c Wed Mar 07 12:38:28 2007 -0700 @@ -303,6 +303,7 @@ static int write_msg(int fd, int msgtype msg->type = CTLMSG_PARAMS; msg->len = msglen; msg->drivertype = blkif->drivertype; + msg->readonly = blkif->readonly; gettimeofday(&timeout, NULL); msg->cookie = blkif->cookie; @@ -410,7 +411,6 @@ static int read_msg(int fd, int msgtype, if (select(fd+1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout) > 0) { ret = read(fd, buf, msglen); - } if (ret > 0) { msg = (msg_hdr_t *)buf; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/block-aio.c --- a/tools/blktap/drivers/block-aio.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/block-aio.c Wed Mar 07 12:38:28 2007 -0700 @@ -152,9 +152,9 @@ static inline void init_fds(struct disk_ } /* Open the disk file and initialize aio state. */ -int tdaio_open (struct disk_driver *dd, const char *name) -{ - int i, fd, ret = 0; +int tdaio_open (struct disk_driver *dd, const char *name, td_flag_t flags) +{ + int i, fd, ret = 0, o_flags; struct td_state *s = dd->td_state; struct tdaio_state *prv = (struct tdaio_state *)dd->private; @@ -187,12 +187,15 @@ int tdaio_open (struct disk_driver *dd, prv->iocb_free[i] = &prv->iocb_list[i]; /* Open the file */ - fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + fd = open(name, o_flags); if ( (fd == -1) && (errno == EINVAL) ) { /* Maybe O_DIRECT isn't supported. */ - fd = open(name, O_RDWR | O_LARGEFILE); + o_flags &= ~O_DIRECT; + fd = open(name, o_flags); if (fd != -1) DPRINTF("WARNING: Accessing image without" "O_DIRECT! (%s)\n", name); @@ -279,6 +282,9 @@ int tdaio_submit(struct disk_driver *dd) { int ret; struct tdaio_state *prv = (struct tdaio_state *)dd->private; + + if (!prv->iocb_queued) + return 0; ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue); @@ -324,12 +330,13 @@ int tdaio_do_callbacks(struct disk_drive return rsp; } -int tdaio_has_parent(struct disk_driver *dd) -{ - return 0; -} - -int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent) +int tdaio_get_parent_id(struct disk_driver *dd, struct disk_id *id) +{ + return TD_NO_PARENT; +} + +int tdaio_validate_parent(struct disk_driver *dd, + struct disk_driver *parent, td_flag_t flags) { return -EINVAL; } @@ -341,8 +348,8 @@ struct tap_disk tapdisk_aio = { .td_queue_read = tdaio_queue_read, .td_queue_write = tdaio_queue_write, .td_submit = tdaio_submit, - .td_has_parent = tdaio_has_parent, - .td_get_parent = tdaio_get_parent, .td_close = tdaio_close, .td_do_callbacks = tdaio_do_callbacks, + .td_get_parent_id = tdaio_get_parent_id, + .td_validate_parent = tdaio_validate_parent }; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/block-qcow.c Wed Mar 07 12:38:28 2007 -0700 @@ -209,23 +209,6 @@ static int init_aio_state(struct disk_dr return -1; } -/* - *Test if block is zero. - * Return: - * 1 for TRUE - * 0 for FALSE - */ -static inline int IS_ZERO(char *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) { - /*if not zero, return false*/ - if (ZERO_TEST(*(buf + i))) return 0; - } - return 1; -} - static uint32_t gen_cksum(char *ptr, int len) { unsigned char *md; @@ -439,7 +422,7 @@ static int qtruncate(int fd, off_t lengt return -1; if (S_ISBLK(st.st_mode)) return 0; - + sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE; current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE; rem = st.st_size % DEFAULT_SECTOR_SIZE; @@ -825,9 +808,9 @@ static inline void init_fds(struct disk_ } /* Open the disk file and initialize qcow state. */ -int tdqcow_open (struct disk_driver *dd, const char *name) -{ - int fd, len, i, shift, ret, size, l1_table_size; +int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags) +{ + int fd, len, i, shift, ret, size, l1_table_size, o_flags; struct td_state *bs = dd->td_state; struct tdqcow_state *s = (struct tdqcow_state *)dd->private; char *buf; @@ -838,7 +821,9 @@ int tdqcow_open (struct disk_driver *dd, DPRINTF("QCOW: Opening %s\n",name); - fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + fd = open(name, o_flags); if (fd < 0) { DPRINTF("Unable to open %s (%d)\n",name,0 - errno); return -1; @@ -1016,7 +1001,8 @@ int tdqcow_queue_read(struct disk_driver * as busy and try again later */ return cb(dd, -EBUSY, sector + n, nb_sectors - n, id, private); - } else rsp += ret; + } else + rsp += ret; } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { aio_unlock(s, sector); if (decompress_cluster(s, cluster_offset) < 0) { @@ -1403,21 +1389,15 @@ int qcow_compress_cluster(struct tdqcow_ return 0; } -int tdqcow_has_parent(struct disk_driver *dd) -{ - struct tdqcow_state *s = (struct tdqcow_state *)dd->private; - return (s->backing_file_offset ? 1 : 0); -} - -int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd) +int tdqcow_get_parent_id(struct disk_driver *dd, struct disk_id *id) { off_t off; char *buf, *filename; - int len, secs, ret = -1; - struct tdqcow_state *child = (struct tdqcow_state *)cdd->private; + int len, secs, err = -EINVAL; + struct tdqcow_state *child = (struct tdqcow_state *)dd->private; if (!child->backing_file_offset) - return -1; + return TD_NO_PARENT; /* read the backing file name */ len = child->backing_file_size; @@ -1432,14 +1412,39 @@ int tdqcow_get_parent(struct disk_driver if (read(child->fd, buf, secs << 9) != secs << 9) goto out; - filename = buf + (child->backing_file_offset - off); - filename[len] = '\0'; - - /*Open backing file*/ - ret = tdqcow_open(pdd, filename); + filename = buf + (child->backing_file_offset - off); + filename[len] = '\0'; + + id->name = strdup(filename); + id->drivertype = DISK_TYPE_QCOW; + err = 0; out: free(buf); - return ret; + return err; +} + +int tdqcow_validate_parent(struct disk_driver *child, + struct disk_driver *parent, td_flag_t flags) +{ + struct stat stats; + uint64_t psize, csize; + struct tdqcow_state *c = (struct tdqcow_state *)child->private; + struct tdqcow_state *p = (struct tdqcow_state *)parent->private; + + if (stat(p->name, &stats)) + return -EINVAL; + if (get_filesize(p->name, &psize, &stats)) + return -EINVAL; + + if (stat(c->name, &stats)) + return -EINVAL; + if (get_filesize(c->name, &csize, &stats)) + return -EINVAL; + + if (csize != psize) + return -EINVAL; + + return 0; } struct tap_disk tapdisk_qcow = { @@ -1449,8 +1454,8 @@ struct tap_disk tapdisk_qcow = { .td_queue_read = tdqcow_queue_read, .td_queue_write = tdqcow_queue_write, .td_submit = tdqcow_submit, - .td_has_parent = tdqcow_has_parent, - .td_get_parent = tdqcow_get_parent, .td_close = tdqcow_close, .td_do_callbacks = tdqcow_do_callbacks, + .td_get_parent_id = tdqcow_get_parent_id, + .td_validate_parent = tdqcow_validate_parent }; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/block-ram.c --- a/tools/blktap/drivers/block-ram.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/block-ram.c Wed Mar 07 12:38:28 2007 -0700 @@ -135,11 +135,11 @@ static inline void init_fds(struct disk_ } /* Open the disk file and initialize ram state. */ -int tdram_open (struct disk_driver *dd, const char *name) +int tdram_open (struct disk_driver *dd, const char *name, td_flag_t flags) { char *p; uint64_t size; - int i, fd, ret = 0, count = 0; + int i, fd, ret = 0, count = 0, o_flags; struct td_state *s = dd->td_state; struct tdram_state *prv = (struct tdram_state *)dd->private; @@ -167,12 +167,15 @@ int tdram_open (struct disk_driver *dd, } /* Open the file */ - fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + fd = open(name, o_flags); if ((fd == -1) && (errno == EINVAL)) { /* Maybe O_DIRECT isn't supported. */ - fd = open(name, O_RDWR | O_LARGEFILE); + o_flags &= ~O_DIRECT; + fd = open(name, o_flags); if (fd != -1) DPRINTF("WARNING: Accessing image without" "O_DIRECT! (%s)\n", name); @@ -275,12 +278,13 @@ int tdram_do_callbacks(struct disk_drive return 1; } -int tdram_has_parent(struct disk_driver *dd) -{ - return 0; -} - -int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent) +int tdram_get_parent_id(struct disk_driver *dd, struct disk_id *id) +{ + return TD_NO_PARENT; +} + +int tdram_validate_parent(struct disk_driver *dd, + struct disk_driver *parent, td_flag_t flags) { return -EINVAL; } @@ -292,8 +296,8 @@ struct tap_disk tapdisk_ram = { .td_queue_read = tdram_queue_read, .td_queue_write = tdram_queue_write, .td_submit = tdram_submit, - .td_has_parent = tdram_has_parent, - .td_get_parent = tdram_get_parent, .td_close = tdram_close, .td_do_callbacks = tdram_do_callbacks, + .td_get_parent_id = tdram_get_parent_id, + .td_validate_parent = tdram_validate_parent }; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/block-sync.c --- a/tools/blktap/drivers/block-sync.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/block-sync.c Wed Mar 07 12:38:28 2007 -0700 @@ -118,9 +118,9 @@ static inline void init_fds(struct disk_ } /* Open the disk file and initialize aio state. */ -int tdsync_open (struct disk_driver *dd, const char *name) -{ - int i, fd, ret = 0; +int tdsync_open (struct disk_driver *dd, const char *name, td_flag_t flags) +{ + int i, fd, ret = 0, o_flags; struct td_state *s = dd->td_state; struct tdsync_state *prv = (struct tdsync_state *)dd->private; @@ -130,11 +130,14 @@ int tdsync_open (struct disk_driver *dd, return (0 - errno); /* Open the file */ - fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + fd = open(name, o_flags); if ( (fd == -1) && (errno == EINVAL) ) { /* Maybe O_DIRECT isn't supported. */ + o_flags &= ~O_DIRECT; fd = open(name, O_RDWR | O_LARGEFILE); if (fd != -1) DPRINTF("WARNING: Accessing image without" "O_DIRECT! (%s)\n", name); @@ -223,12 +226,13 @@ int tdsync_do_callbacks(struct disk_driv return 1; } -int tdsync_has_parent(struct disk_driver *dd) -{ - return 0; -} - -int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent) +int tdsync_get_parent_id(struct disk_driver *dd, struct disk_id *id) +{ + return TD_NO_PARENT; +} + +int tdsync_validate_parent(struct disk_driver *dd, + struct disk_driver *parent, td_flag_t flags) { return -EINVAL; } @@ -240,8 +244,8 @@ struct tap_disk tapdisk_sync = { .td_queue_read = tdsync_queue_read, .td_queue_write = tdsync_queue_write, .td_submit = tdsync_submit, - .td_has_parent = tdsync_has_parent, - .td_get_parent = tdsync_get_parent, .td_close = tdsync_close, .td_do_callbacks = tdsync_do_callbacks, + .td_get_parent_id = tdsync_get_parent_id, + .td_validate_parent = tdsync_validate_parent }; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/block-vmdk.c --- a/tools/blktap/drivers/block-vmdk.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/block-vmdk.c Wed Mar 07 12:38:28 2007 -0700 @@ -119,10 +119,11 @@ static inline void init_fds(struct disk_ } /* Open the disk file and initialize aio state. */ -static int tdvmdk_open (struct disk_driver *dd, const char *name) +static int tdvmdk_open (struct disk_driver *dd, + const char *name, td_flag_t flags) { int ret, fd; - int l1_size, i; + int l1_size, i, o_flags; uint32_t magic; struct td_state *s = dd->td_state; struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private; @@ -133,12 +134,15 @@ static int tdvmdk_open (struct disk_driv return -1; /* Open the file */ - fd = open(name, O_RDWR | O_LARGEFILE); + o_flags = O_DIRECT | O_LARGEFILE | + ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + fd = open(name, o_flags); if ( (fd == -1) && (errno == EINVAL) ) { /* Maybe O_DIRECT isn't supported. */ - fd = open(name, O_RDWR | O_LARGEFILE); + o_flags &= ~O_DIRECT; + fd = open(name, o_flags); if (fd != -1) DPRINTF("WARNING: Accessing image without" "O_DIRECT! (%s)\n", name); @@ -394,12 +398,13 @@ static int tdvmdk_do_callbacks(struct di return 1; } -static int tdvmdk_has_parent(struct disk_driver *dd) -{ - return 0; -} - -static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver *parent) +static int tdvmdk_get_parent_id(struct disk_driver *dd, struct disk_id *id) +{ + return TD_NO_PARENT; +} + +static int tdvmdk_validate_parent(struct disk_driver *dd, + struct disk_driver *parent, td_flag_t flags) { return -EINVAL; } @@ -411,8 +416,8 @@ struct tap_disk tapdisk_vmdk = { .td_queue_read = tdvmdk_queue_read, .td_queue_write = tdvmdk_queue_write, .td_submit = tdvmdk_submit, - .td_has_parent = tdvmdk_has_parent, - .td_get_parent = tdvmdk_get_parent, .td_close = tdvmdk_close, .td_do_callbacks = tdvmdk_do_callbacks, + .td_get_parent_id = tdvmdk_get_parent_id, + .td_validate_parent = tdvmdk_validate_parent }; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/img2qcow.c --- a/tools/blktap/drivers/img2qcow.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/img2qcow.c Wed Mar 07 12:38:28 2007 -0700 @@ -201,7 +201,7 @@ int main(int argc, char *argv[]) dd.private = malloc(dd.drv->private_data_size); /*Open qcow file*/ - if (dd.drv->td_open(&dd, argv[1])!=0) { + if (dd.drv->td_open(&dd, argv[1], 0)!=0) { DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]); exit(-1); } diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/qcow2raw.c --- a/tools/blktap/drivers/qcow2raw.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/qcow2raw.c Wed Mar 07 12:38:28 2007 -0700 @@ -169,7 +169,7 @@ int main(int argc, char *argv[]) ddqcow.drv = &tapdisk_qcow; ddqcow.private = malloc(ddqcow.drv->private_data_size); - if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) { + if (ddqcow.drv->td_open(&ddqcow, argv[2], TD_RDONLY)!=0) { DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]); exit(-1); } else DFPRINTF("QCOW file opened, size %llu\n", @@ -270,7 +270,7 @@ int main(int argc, char *argv[]) ddaio.drv = &tapdisk_aio; ddaio.private = malloc(ddaio.drv->private_data_size); - if (ddaio.drv->td_open(&ddaio, argv[1])!=0) { + if (ddaio.drv->td_open(&ddaio, argv[1], 0)!=0) { DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]); exit(-1); } diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/tapdisk.c --- a/tools/blktap/drivers/tapdisk.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/tapdisk.c Wed Mar 07 12:38:28 2007 -0700 @@ -81,6 +81,15 @@ void daemonize(void) return; } +static void free_driver(struct disk_driver *d) +{ + if (d->name) + free(d->name); + if (d->private) + free(d->private); + free(d); +} + static void unmap_disk(struct td_state *s) { tapdev_info_t *info = s->ring_info; @@ -91,8 +100,7 @@ static void unmap_disk(struct td_state * while (dd) { tmp = dd->next; dd->drv->td_close(dd); - free(dd->private); - free(dd); + free_driver(dd); dd = tmp; } @@ -112,7 +120,6 @@ static void unmap_disk(struct td_state * free(s); return; - } void sig_handler(int sig) @@ -205,7 +212,64 @@ static struct td_state *state_init(void) return s; } -static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv) +static int map_new_dev(struct td_state *s, int minor) +{ + int tap_fd; + tapdev_info_t *info = s->ring_info; + char *devname; + fd_list_entry_t *ptr; + int page_size; + + asprintf(&devname,"%s/%s%d", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor); + tap_fd = open(devname, O_RDWR); + if (tap_fd == -1) + { + DPRINTF("open failed on dev %s!",devname); + goto fail; + } + info->fd = tap_fd; + + /*Map the shared memory*/ + page_size = getpagesize(); + info->mem = mmap(0, page_size * BLKTAP_MMAP_REGION_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0); + if ((long int)info->mem == -1) + { + DPRINTF("mmap failed on dev %s!\n",devname); + goto fail; + } + + /* assign the rings to the mapped memory */ + info->sring = (blkif_sring_t *)((unsigned long)info->mem); + BACK_RING_INIT(&info->fe_ring, info->sring, page_size); + + info->vstart = + (unsigned long)info->mem + (BLKTAP_RING_PAGES * page_size); + + ioctl(info->fd, BLKTAP_IOCTL_SENDPID, process ); + ioctl(info->fd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); + free(devname); + + /*Update the fd entry*/ + ptr = fd_start; + while (ptr != NULL) { + if (s == ptr->s) { + ptr->tap_fd = tap_fd; + break; + } + ptr = ptr->next; + } + + return minor; + + fail: + free(devname); + return -1; +} + +static struct disk_driver *disk_init(struct td_state *s, + struct tap_disk *drv, + char *name, td_flag_t flags) { struct disk_driver *dd; @@ -221,108 +285,86 @@ static struct disk_driver *disk_init(str dd->drv = drv; dd->td_state = s; + dd->name = name; + dd->flags = flags; return dd; } -static int map_new_dev(struct td_state *s, int minor) -{ - int tap_fd; - tapdev_info_t *info = s->ring_info; - char *devname; - fd_list_entry_t *ptr; - int page_size; - - asprintf(&devname,"%s/%s%d", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor); - tap_fd = open(devname, O_RDWR); - if (tap_fd == -1) - { - DPRINTF("open failed on dev %s!",devname); - goto fail; - } - info->fd = tap_fd; - - /*Map the shared memory*/ - page_size = getpagesize(); - info->mem = mmap(0, page_size * BLKTAP_MMAP_REGION_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0); - if ((long int)info->mem == -1) - { - DPRINTF("mmap failed on dev %s!\n",devname); - goto fail; - } - - /* assign the rings to the mapped memory */ - info->sring = (blkif_sring_t *)((unsigned long)info->mem); - BACK_RING_INIT(&info->fe_ring, info->sring, page_size); - - info->vstart = - (unsigned long)info->mem + (BLKTAP_RING_PAGES * page_size); - - ioctl(info->fd, BLKTAP_IOCTL_SENDPID, process ); - ioctl(info->fd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); - free(devname); - - /*Update the fd entry*/ - ptr = fd_start; - while (ptr != NULL) { - if (s == ptr->s) { - ptr->tap_fd = tap_fd; - break; - } - ptr = ptr->next; - } - - return minor; - - fail: - free(devname); - return -1; -} - -static int open_disk(struct td_state *s, struct disk_driver *dd, char *path) +static int open_disk(struct td_state *s, + struct tap_disk *drv, char *path, td_flag_t flags) { int err; - struct disk_driver *d = dd; - - err = dd->drv->td_open(dd, path); - if (err) - return err; + char *dup; + td_flag_t pflags; + struct disk_id id; + struct disk_driver *d; + + dup = strdup(path); + if (!dup) + return -ENOMEM; + + memset(&id, 0, sizeof(struct disk_id)); + s->disks = d = disk_init(s, drv, dup, flags); + if (!d) + return -ENOMEM; + + err = drv->td_open(d, path, flags); + if (err) { + free_driver(d); + s->disks = NULL; + return -ENOMEM; + } + pflags = flags | TD_RDONLY; /* load backing files as necessary */ - while (d->drv->td_has_parent(d)) { + while ((err = d->drv->td_get_parent_id(d, &id)) == 0) { struct disk_driver *new; - new = calloc(1, sizeof(struct disk_driver)); + if (id.drivertype > MAX_DISK_TYPES || + !get_driver(id.drivertype) || !id.name) + goto fail; + + dup = strdup(id.name); + if (!dup) + goto fail; + + new = disk_init(s, get_driver(id.drivertype), dup, pflags); if (!new) goto fail; - new->drv = d->drv; - new->td_state = s; - new->private = malloc(new->drv->private_data_size); - if (!new->private) { - free(new); - goto fail; - } - - err = d->drv->td_get_parent(d, new); + + err = new->drv->td_open(new, new->name, pflags); if (err) goto fail; + err = d->drv->td_validate_parent(d, new, 0); + if (err) { + d->next = new; + goto fail; + } + d = d->next = new; - } - - return 0; + free(id.name); + } + + s->info |= ((flags & TD_RDONLY) ? VDISK_READONLY : 0); + + if (err >= 0) + return 0; fail: DPRINTF("failed opening disk\n"); - while (dd) { - d = dd->next; - dd->drv->td_close(dd); - free(dd->private); - free(dd); - dd = d; - } - return err; + if (id.name) + free(id.name); + d = s->disks; + while (d) { + struct disk_driver *tmp = d->next; + d->drv->td_close(d); + free_driver(d); + d = tmp; + } + s->disks = NULL; + return -1; } static int read_msg(char *buf) @@ -334,7 +376,6 @@ static int read_msg(char *buf) msg_newdev_t *msg_dev; msg_pid_t *msg_pid; struct tap_disk *drv; - struct disk_driver *dd; int ret = -1; struct td_state *s = NULL; fd_list_entry_t *entry; @@ -369,14 +410,9 @@ static int read_msg(char *buf) if (s == NULL) goto params_done; - s->disks = dd = disk_init(s, drv); - if (!dd) { - free(s); - goto params_done; - } - /*Open file*/ - ret = open_disk(s, dd, path); + ret = open_disk(s, drv, path, + ((msg->readonly) ? TD_RDONLY : 0)); if (ret) goto params_done; @@ -482,7 +518,8 @@ void io_done(struct disk_driver *dd, int if (!run) return; /*We have received signal to close*/ - if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state); + if (sid > MAX_IOFD || drv->td_do_callbacks(dd, sid) > 0) + kick_responses(dd->td_state); return; } @@ -631,6 +668,12 @@ static void get_io_request(struct td_sta blkif->pending_list[idx].status = BLKIF_RSP_OKAY; blkif->pending_list[idx].submitting = 1; sector_nr = req->sector_number; + } + + if ((dd->flags & TD_RDONLY) && + (req->operation == BLKIF_OP_WRITE)) { + blkif->pending_list[idx].status = BLKIF_RSP_ERROR; + goto send_response; } for (i = start_seg; i < req->nr_segments; i++) { @@ -698,10 +741,12 @@ static void get_io_request(struct td_sta } sector_nr += nsects; } + send_response: blkif->pending_list[idx].submitting = 0; /* force write_rsp_to_ring for synchronous case */ if (blkif->pending_list[idx].secs_pending == 0) - dd->early += send_responses(dd, 0, 0, 0, idx, (void *)0); + dd->early += send_responses(dd, 0, 0, 0, idx, + (void *)(long)0); } out: @@ -709,7 +754,7 @@ static void get_io_request(struct td_sta td_for_each_disk(s, dd) { dd->early += dd->drv->td_submit(dd); if (dd->early > 0) { - io_done(dd, 10); + io_done(dd, MAX_IOFD + 1); dd->early = 0; } } @@ -785,6 +830,20 @@ int main(int argc, char *argv[]) } } + /* completed io from above may have + * queued new requests on chained disks */ + if (progress_made) { + td_for_each_disk(ptr->s, dd) { + dd->early += + dd->drv->td_submit(dd); + if (dd->early > 0) { + io_done(dd, + MAX_IOFD + 1); + dd->early = 0; + } + } + } + if (FD_ISSET(ptr->tap_fd, &readfds) || (info->busy.req && progress_made)) get_io_request(ptr->s); diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/drivers/tapdisk.h --- a/tools/blktap/drivers/tapdisk.h Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/drivers/tapdisk.h Wed Mar 07 12:38:28 2007 -0700 @@ -42,10 +42,15 @@ * * - The fd used for poll is an otherwise unused pipe, which allows poll to * be safely called without ever returning anything. - * + * * NOTE: tapdisk uses the number of sectors submitted per request as a * ref count. Plugins must use the callback function to communicate the * completion--or error--of every sector submitted to them. + * + * td_get_parent_id returns: + * 0 if parent id successfully retrieved + * TD_NO_PARENT if no parent exists + * -errno on error */ #ifndef TAPDISK_H_ @@ -71,13 +76,25 @@ #define MAX_IOFD 2 #define BLK_NOT_ALLOCATED 99 +#define TD_NO_PARENT 1 + +typedef uint32_t td_flag_t; + +#define TD_RDONLY 1 struct td_state; struct tap_disk; +struct disk_id { + char *name; + int drivertype; +}; + struct disk_driver { int early; + char *name; void *private; + td_flag_t flags; int io_fd[MAX_IOFD]; struct tap_disk *drv; struct td_state *td_state; @@ -105,18 +122,20 @@ struct tap_disk { struct tap_disk { const char *disk_type; int private_data_size; - int (*td_open) (struct disk_driver *dd, const char *name); - int (*td_queue_read) (struct disk_driver *dd, uint64_t sector, - int nb_sectors, char *buf, td_callback_t cb, - int id, void *prv); - int (*td_queue_write) (struct disk_driver *dd, uint64_t sector, - int nb_sectors, char *buf, td_callback_t cb, - int id, void *prv); - int (*td_submit) (struct disk_driver *dd); - int (*td_has_parent) (struct disk_driver *dd); - int (*td_get_parent) (struct disk_driver *dd, struct disk_driver *p); - int (*td_close) (struct disk_driver *dd); - int (*td_do_callbacks)(struct disk_driver *dd, int sid); + int (*td_open) (struct disk_driver *dd, + const char *name, td_flag_t flags); + int (*td_queue_read) (struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *prv); + int (*td_queue_write) (struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *prv); + int (*td_submit) (struct disk_driver *dd); + int (*td_close) (struct disk_driver *dd); + int (*td_do_callbacks) (struct disk_driver *dd, int sid); + int (*td_get_parent_id) (struct disk_driver *dd, struct disk_id *id); + int (*td_validate_parent)(struct disk_driver *dd, + struct disk_driver *p, td_flag_t flags); }; typedef struct disk_info { diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/lib/Makefile --- a/tools/blktap/lib/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/lib/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -40,8 +40,8 @@ libblktap: libblktap.a libblktap: libblktap.a install: all - $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) - $(INSTALL_DIR) -p $(DESTDIR)/usr/include + $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DIR) $(DESTDIR)/usr/include $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/$(LIBDIR) ln -sf libblktap.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libblktap.so.$(MAJOR) ln -sf libblktap.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libblktap.so diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/lib/blktaplib.h --- a/tools/blktap/lib/blktaplib.h Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/lib/blktaplib.h Wed Mar 07 12:38:28 2007 -0700 @@ -173,6 +173,7 @@ typedef struct msg_hdr { uint16_t len; uint16_t drivertype; uint16_t cookie; + uint8_t readonly; } msg_hdr_t; typedef struct msg_newdev { diff -r 8a58ea36e420 -r 50d5bf02e59e tools/blktap/lib/xenbus.c --- a/tools/blktap/lib/xenbus.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/blktap/lib/xenbus.c Wed Mar 07 12:38:28 2007 -0700 @@ -177,8 +177,11 @@ static void ueblktap_setup(struct xs_han } /* Check to see if device is to be opened read-only. */ - asprintf(&path, "%s/%s", bepath, "read-only"); - if (xs_exists(h, path)) + deverr = xs_gather(h, bepath, "mode", NULL, &path, NULL); + if (deverr) { + DPRINTF("ERROR: could not find read/write mode\n"); + goto fail; + } else if (path[0] == 'r') be->readonly = 1; if (be->blkif == NULL) { diff -r 8a58ea36e420 -r 50d5bf02e59e tools/console/Makefile --- a/tools/console/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/console/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -30,7 +30,7 @@ xenconsole: $(patsubst %.c,%.o,$(wildcar .PHONY: install install: $(BIN) - $(INSTALL_DIR) -p $(DESTDIR)/$(DAEMON_INSTALL_DIR) + $(INSTALL_DIR) $(DESTDIR)/$(DAEMON_INSTALL_DIR) $(INSTALL_PROG) xenconsoled $(DESTDIR)/$(DAEMON_INSTALL_DIR) - $(INSTALL_DIR) -p $(DESTDIR)/$(CLIENT_INSTALL_DIR) + $(INSTALL_DIR) $(DESTDIR)/$(CLIENT_INSTALL_DIR) $(INSTALL_PROG) xenconsole $(DESTDIR)/$(CLIENT_INSTALL_DIR) diff -r 8a58ea36e420 -r 50d5bf02e59e tools/examples/init.d/xendomains --- a/tools/examples/init.d/xendomains Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/examples/init.d/xendomains Wed Mar 07 12:38:28 2007 -0700 @@ -58,18 +58,7 @@ else _SMSG=(done failed failed missed failed skipped unused failed failed) _RC_UNUSED=6 fi - if test -e /lib/lsb/init-functions; then - # LSB - . /lib/lsb/init-functions - echo_rc() - { - if test ${_RC_RV} = 0; then - log_success_msg " [${_SMSG[${_RC_RV}]}] " - else - log_failure_msg " [${_SMSG[${_RC_RV}]}] " - fi - } - elif test -e /etc/init.d/functions; then + if test -e /etc/init.d/functions; then # REDHAT . /etc/init.d/functions echo_rc() @@ -81,6 +70,24 @@ else failure " [${_SMSG[${_RC_RV}]}] " fi } + elif test -e /lib/lsb/init-functions; then + # LSB + . /lib/lsb/init-functions + if alias log_success_msg >/dev/null 2>/dev/null; then + echo_rc() + { + echo " [${_SMSG[${_RC_RV}]}] " + } + else + echo_rc() + { + if test ${_RC_RV} = 0; then + log_success_msg " [${_SMSG[${_RC_RV}]}] " + else + log_failure_msg " [${_SMSG[${_RC_RV}]}] " + fi + } + fi else # emulate it echo_rc() diff -r 8a58ea36e420 -r 50d5bf02e59e tools/firmware/hvmloader/acpi/dsdt.asl --- a/tools/firmware/hvmloader/acpi/dsdt.asl Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Wed Mar 07 12:38:28 2007 -0700 @@ -123,7 +123,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, } Name(BUFA, ResourceTemplate() { - IRQ(Level, ActiveLow, Shared) { 5, 6, 10, 11 } + IRQ(Level, ActiveLow, Shared) { 5, 7, 10, 11 } }) Name(BUFB, Buffer() { @@ -643,22 +643,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, IRQNoFlags () {4} }) } - - Device (LTP1) - { - Name (_HID, EisaId ("PNP0400")) - Name (_UID, 0x02) - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - - Name (_CRS, ResourceTemplate() - { - IO (Decode16, 0x0378, 0x0378, 0x08, 0x08) - IRQNoFlags () {7} - }) - } } } } diff -r 8a58ea36e420 -r 50d5bf02e59e tools/firmware/hvmloader/acpi/dsdt.c --- a/tools/firmware/hvmloader/acpi/dsdt.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Wed Mar 07 12:38:28 2007 -0700 @@ -5,15 +5,15 @@ * Copyright (C) 2000 - 2006 Intel Corporation * Supports ACPI Specification Revision 3.0a * - * Compilation of "dsdt.asl" - Fri Feb 16 15:14:37 2007 + * Compilation of "dsdt.asl" - Mon Feb 26 11:09:49 2007 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00, /* 00000000 "DSDT...." */ - 0x02,0xEE,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x44,0x53,0x44,0x54,0x67,0x0D,0x00,0x00, /* 00000000 "DSDTg..." */ + 0x02,0xE0,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ @@ -27,7 +27,7 @@ unsigned char AmlCode[] = 0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08, /* 00000060 "........" */ 0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F, /* 00000068 "PICD..._" */ 0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49, /* 00000070 "PIC.phPI" */ - 0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42, /* 00000078 "CD.D._SB" */ + 0x43,0x44,0x10,0x4C,0xCE,0x5F,0x53,0x42, /* 00000078 "CD.L._SB" */ 0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D, /* 00000080 "_[.I.MEM" */ 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000088 "0._HID.A" */ 0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53, /* 00000090 "...._CRS" */ @@ -37,7 +37,7 @@ unsigned char AmlCode[] = 0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000000B0 "........" */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */ 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 000000C0 "........" */ - 0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD, /* 000000C8 "..y.[.A." */ + 0x00,0x00,0x79,0x00,0x5B,0x82,0x49,0xC9, /* 000000C8 "..y.[.I." */ 0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49, /* 000000D0 "PCI0._HI" */ 0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F, /* 000000D8 "D.A...._" */ 0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44, /* 000000E0 "UID.._AD" */ @@ -59,7 +59,7 @@ unsigned char AmlCode[] = 0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00, /* 00000160 "........" */ 0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00, /* 00000168 "......y." */ 0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55, /* 00000170 ".PRT0.BU" */ - 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x60, /* 00000178 "FA....#`" */ + 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0xA0, /* 00000178 "FA....#." */ 0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46, /* 00000180 "..y..BUF" */ 0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00, /* 00000188 "B....#.." */ 0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42, /* 00000190 ".y..BUFB" */ @@ -348,7 +348,7 @@ unsigned char AmlCode[] = 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000A68 "........" */ 0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C, /* 00000A70 ".../...." */ 0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A, /* 00000A78 "........" */ - 0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41, /* 00000A80 ".[.L1ISA" */ + 0x10,0x5B,0x82,0x44,0x2E,0x49,0x53,0x41, /* 00000A80 ".[.D.ISA" */ 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000A88 "_._ADR.." */ 0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52, /* 00000A90 "...[.PIR" */ 0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E, /* 00000A98 "Q..`...." */ @@ -440,13 +440,6 @@ unsigned char AmlCode[] = 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D48 "._STA..." */ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D50 ".._CRS.." */ 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000D58 "..G....." */ - 0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B, /* 00000D60 ".."..y.[" */ - 0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F, /* 00000D68 ".6LTP1._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00, /* 00000D70 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000D78 "._UID..." */ - 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D80 "._STA..." */ - 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D88 ".._CRS.." */ - 0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03, /* 00000D90 "..G.x.x." */ - 0x08,0x08,0x22,0x80,0x00,0x79,0x00, + 0x01,0x08,0x22,0x10,0x00,0x79,0x00, }; int DsdtLen=sizeof(AmlCode); diff -r 8a58ea36e420 -r 50d5bf02e59e tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/firmware/hvmloader/config.h Wed Mar 07 12:38:28 2007 -0700 @@ -9,7 +9,7 @@ #define LAPIC_ID(vcpu_id) ((vcpu_id) * 2) #define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ -#define PCI_ISA_IRQ_MASK 0x0c60U /* ISA IRQs 5,6,10,11 are PCI connected */ +#define PCI_ISA_IRQ_MASK 0x0ca0U /* ISA IRQs 5,7,10,11 are PCI connected */ #define ROMBIOS_SEG 0xF000 #define ROMBIOS_BEGIN 0x000F0000 diff -r 8a58ea36e420 -r 50d5bf02e59e tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/firmware/rombios/rombios.c Wed Mar 07 12:38:28 2007 -0700 @@ -890,7 +890,7 @@ static void int15_function(); static void int15_function(); static void int16_function(); static void int17_function(); -static void int19_function(); +static void int18_function(); static void int1a_function(); static void int70_function(); static void int74_function(); @@ -1837,6 +1837,38 @@ keyboard_panic(status) } //-------------------------------------------------------------------------- +// machine_reset +//-------------------------------------------------------------------------- + void +machine_reset() +{ + /* Frob the keyboard reset line to reset the processor */ + outb(0x64, 0x60); /* Map the flags register at data port (0x60) */ + outb(0x60, 0x14); /* Set the flags to system|disable */ + outb(0x64, 0xfe); /* Pulse output 0 (system reset) low */ + BX_PANIC("Couldn't reset the machine\n"); +} + +//-------------------------------------------------------------------------- +// clobber_entry_point +// Because PV drivers in HVM guests detach some of the emulated devices, +// it is not safe to do a soft reboot by just dropping to real mode and +// jumping at ffff:0000. -- the boot drives might have disappeared! +// This rather foul function overwrites(!) the BIOS entry point +// to point at machine-reset, which will cause the Xen tools to +// rebuild the whole machine from scratch. +//-------------------------------------------------------------------------- + void +clobber_entry_point() +{ + /* The instruction at the entry point is one byte (0xea) for the + * jump opcode, then two bytes of address, then two of segment. + * Overwrite the address bytes.*/ + write_word(0xffff, 0x0001, machine_reset); +} + + +//-------------------------------------------------------------------------- // shutdown_status_panic // called when the shutdown statsu is not implemented, displays the status //-------------------------------------------------------------------------- @@ -7626,7 +7658,7 @@ int17_function(regs, ds, iret_addr) } void -int19_function(seq_nr) +int18_function(seq_nr) Bit16u seq_nr; { Bit16u ebda_seg=read_word(0x0040,0x000E); @@ -7702,8 +7734,8 @@ ASM_START push cx push dx - mov dl, _int19_function.bootdrv + 2[bp] - mov ax, _int19_function.bootseg + 2[bp] + mov dl, _int18_function.bootdrv + 2[bp] + mov ax, _int18_function.bootseg + 2[bp] mov es, ax ;; segment mov bx, #0x0000 ;; offset mov ah, #0x02 ;; function 2, read diskette sector @@ -7714,7 +7746,7 @@ ASM_START int #0x13 ;; read sector jnc int19_load_done mov ax, #0x0001 - mov _int19_function.status + 2[bp], ax + mov _int18_function.status + 2[bp], ax int19_load_done: pop dx @@ -7789,13 +7821,13 @@ ASM_START ;; Build an iret stack frame that will take us to the boot vector. ;; iret pops ip, then cs, then flags, so push them in the opposite order. pushf - mov ax, _int19_function.bootseg + 0[bp] + mov ax, _int18_function.bootseg + 0[bp] push ax - mov ax, _int19_function.bootip + 0[bp] + mov ax, _int18_function.bootip + 0[bp] push ax ;; Set the magic number in ax and the boot drive in dl. mov ax, #0xaa55 - mov dl, _int19_function.bootdrv + 0[bp] + mov dl, _int18_function.bootdrv + 0[bp] ;; Zero some of the other registers. xor bx, bx mov ds, bx @@ -8272,6 +8304,8 @@ int18_handler: ;; Boot Failure recovery: mov ss, ax ;; Get the boot sequence number out of the IPL memory + ;; The first time we do this it will have been set to -1 so + ;; we will start from device 0. mov bx, #IPL_SEG mov ds, bx ;; Set segment mov bx, IPL_SEQUENCE_OFFSET ;; BX is now the sequence number @@ -8279,43 +8313,33 @@ int18_handler: ;; Boot Failure recovery: mov IPL_SEQUENCE_OFFSET, bx ;; Write it back mov ds, ax ;; and reset the segment to zero. - ;; Carry on in the INT 19h handler, using the new sequence number + ;; Call the C code for the next boot device push bx - - jmp int19_next_boot + call _int18_function + + ;; Boot failed: invoke the boot recovery function... + int #0x18 ;---------- ;- INT19h - ;---------- int19_relocated: ;; Boot function, relocated - - ;; int19 was beginning to be really complex, so now it - ;; just calls a C function that does the work - - push bp - mov bp, sp - - ;; Reset SS and SP + ;; + ;; *** Warning: INT 19h resets the whole machine *** + ;; + ;; Because PV drivers in HVM guests detach some of the emulated devices, + ;; it is not safe to do a soft reboot by just dropping to real mode and + ;; invoking INT 19h -- the boot drives might have disappeared! + ;; If the user asks for a soft reboot, the only thing we can do is + ;; reset the whole machine. When it comes back up, the normal BIOS + ;; boot sequence will start, which is more or less the required behaviour. + ;; + ;; Reset SP and SS mov ax, #0xfffe mov sp, ax xor ax, ax mov ss, ax - - ;; Start from the first boot device (0, in AX) - mov bx, #IPL_SEG - mov ds, bx ;; Set segment to write to the IPL memory - mov IPL_SEQUENCE_OFFSET, ax ;; Save the sequence number - mov ds, ax ;; and reset the segment. - - push ax - -int19_next_boot: - - ;; Call the C code for the next boot device - call _int19_function - - ;; Boot failed: invoke the boot recovery function - int #0x18 + call _machine_reset ;---------- ;- INT1Ch - @@ -9214,218 +9238,80 @@ pci_routing_table_structure: db 0 ;; pci bus number db 0x08 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA#: pointer into PCI2ISA config space - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 0 ;; physical slot (0 = embedded) db 0 ;; reserved ;; second slot entry: 1st PCI slot db 0 ;; pci bus number db 0x10 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 1 ;; physical slot (0 = embedded) db 0 ;; reserved ;; third slot entry: 2nd PCI slot db 0 ;; pci bus number db 0x18 ;; pci device number (bit 7-3) db 0x63 ;; link value INTA# - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x60 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x61 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x62 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 2 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 4th slot entry: 3rd PCI slot db 0 ;; pci bus number db 0x20 ;; pci device number (bit 7-3) db 0x60 ;; link value INTA# - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x61 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x62 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x63 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 3 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 5th slot entry: 4rd PCI slot db 0 ;; pci bus number db 0x28 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA# - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 4 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 6th slot entry: 5rd PCI slot db 0 ;; pci bus number db 0x30 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0x0c60 ;; IRQ bitmap INTA# + dw 0x0ca0 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0x0c60 ;; IRQ bitmap INTB# + dw 0x0ca0 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0x0c60 ;; IRQ bitmap INTC# + dw 0x0ca0 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0x0c60 ;; IRQ bitmap INTD# + dw 0x0ca0 ;; IRQ bitmap INTD# db 5 ;; physical slot (0 = embedded) db 0 ;; reserved - -pci_irq_list: - db 11, 10, 9, 5; - -pcibios_init_sel_reg: - push eax - mov eax, #0x800000 - mov ax, bx - shl eax, #8 - and dl, #0xfc - or al, dl - mov dx, #0x0cf8 - out dx, eax - pop eax - ret - -pcibios_init_set_elcr: - push ax - push cx - mov dx, #0x04d0 - test al, #0x08 - jz is_master_pic - inc dx - and al, #0x07 -is_master_pic: - mov cl, al - mov bl, #0x01 - shl bl, cl - in al, dx - or al, bl - out dx, al - pop cx - pop ax - ret - -pcibios_init: - push ds - push bp - mov ax, #0xf000 - mov ds, ax - mov dx, #0x04d0 ;; reset ELCR1 + ELCR2 - mov al, #0x00 - out dx, al - inc dx - out dx, al - mov si, #pci_routing_table_structure - mov bh, [si+8] - mov bl, [si+9] - mov dl, #0x00 - call pcibios_init_sel_reg - mov dx, #0x0cfc - in eax, dx - cmp eax, [si+12] ;; check irq router - jne pci_init_end - mov dl, [si+34] - call pcibios_init_sel_reg - push bx ;; save irq router bus + devfunc - mov dx, #0x0cfc - mov ax, #0x8080 - out dx, ax ;; reset PIRQ route control - inc dx - inc dx - out dx, ax - mov ax, [si+6] - sub ax, #0x20 - shr ax, #4 - mov cx, ax - add si, #0x20 ;; set pointer to 1st entry - mov bp, sp - mov ax, #pci_irq_list - push ax - xor ax, ax - push ax -pci_init_loop1: - mov bh, [si] - mov bl, [si+1] -pci_init_loop2: - mov dl, #0x00 - call pcibios_init_sel_reg - mov dx, #0x0cfc - in ax, dx - cmp ax, #0xffff - jnz pci_test_int_pin - test bl, #0x07 - jz next_pir_entry - jmp next_pci_func -pci_test_int_pin: - mov dl, #0x3c - call pcibios_init_sel_reg - mov dx, #0x0cfd - in al, dx - and al, #0x07 - jz next_pci_func - dec al ;; determine pirq reg - mov dl, #0x03 - mul al, dl - add al, #0x02 - xor ah, ah - mov bx, ax - mov al, [si+bx] - mov dl, al - mov bx, [bp] - call pcibios_init_sel_reg - mov dx, #0x0cfc - and al, #0x03 - add dl, al - in al, dx - cmp al, #0x80 - jb pirq_found - mov bx, [bp-2] ;; pci irq list pointer - mov al, [bx] - out dx, al - inc bx - mov [bp-2], bx - call pcibios_init_set_elcr -pirq_found: - mov bh, [si] - mov bl, [si+1] - add bl, [bp-3] ;; pci function number - mov dl, #0x3c - call pcibios_init_sel_reg - mov dx, #0x0cfc - out dx, al -next_pci_func: - inc byte ptr[bp-3] - inc bl - test bl, #0x07 - jnz pci_init_loop2 -next_pir_entry: - add si, #0x10 - mov byte ptr[bp-3], #0x00 - loop pci_init_loop1 - mov sp, bp - pop bx -pci_init_end: - pop bp - pop ds - ret #endif // BX_PCIBIOS ; parallel port detection: base address in DX, index in BX, timeout in CL @@ -9747,6 +9633,8 @@ normal_post: call _log_bios_start + call _clobber_entry_point + ;; set all interrupts to default handler mov bx, #0x0000 ;; offset index mov cx, #0x0100 ;; counter (256 interrupts) @@ -9995,8 +9883,10 @@ post_default_ints: call _tcpa_calling_int19h /* specs: 8.2.3 step 1 */ call _tcpa_add_event_separators /* specs: 8.2.3 step 2 */ #endif - int #0x19 - //JMP_EP(0x0064) ; INT 19h location + + ;; Start the boot sequence. See the comments in int19_relocated + ;; for why we use INT 18h instead of INT 19h here. + int #0x18 #if BX_TCGBIOS call _tcpa_returned_int19h /* specs: 8.2.3 step 3/7 */ diff -r 8a58ea36e420 -r 50d5bf02e59e tools/guest-headers/Makefile --- a/tools/guest-headers/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/guest-headers/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -13,7 +13,7 @@ check: install-Linux: mkdir -p $(DESTDIR)/usr/include/xen/linux - install -m0644 $(linuxsparsetree)/include/xen/public/*.h $(DESTDIR)/usr/include/xen/linux + $(INSTALL_DATA) $(linuxsparsetree)/include/xen/public/*.h $(DESTDIR)/usr/include/xen/linux install-SunOS: diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/Makefile --- a/tools/ioemu/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -65,10 +65,10 @@ common de-ch es fo fr-ca hu install-doc: $(DOCS) mkdir -p "$(DESTDIR)$(docdir)" - $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)" + $(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)" ifndef CONFIG_WIN32 mkdir -p "$(DESTDIR)$(mandir)/man1" - $(INSTALL) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1" + $(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1" endif install: all $(if $(BUILD_DOCS),install-doc) @@ -77,12 +77,12 @@ install: all $(if $(BUILD_DOCS),install- # mkdir -p "$(DESTDIR)$(datadir)" # for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ # video.x openbios-sparc32 linux_boot.bin; do \ -# $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \ +# $(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \ # done ifndef CONFIG_WIN32 mkdir -p "$(DESTDIR)$(datadir)/keymaps" for x in $(KEYMAPS); do \ - $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \ + $(INSTALL_DATA) $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \ done endif for d in $(TARGET_DIRS); do \ diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/hw/ide.c Wed Mar 07 12:38:28 2007 -0700 @@ -434,6 +434,121 @@ static void dma_create_thread(void) } #endif /* DMA_MULTI_THREAD */ +#if defined(__ia64__) +#include <xen/hvm/ioreq.h> + +struct buffered_piopage *buffered_pio_page; + +static inline struct pio_buffer * +piobuf_by_addr(uint32_t addr) +{ + if (addr == 0x1F0) + return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY]; + if (addr == 0x170) + return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY]; + return NULL; +} + +static void +buffered_pio_init(void) +{ + struct pio_buffer *p1, *p2; + uint32_t off1, off2; + + if (!buffered_pio_page) + return; + + p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY]; + p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY]; + off1 = offsetof(struct buffered_piopage, buffer); + off2 = (off1 + TARGET_PAGE_SIZE)/2; + + p1->buf_size = off2 - off1; + p1->page_offset = off1; + + p2->buf_size = TARGET_PAGE_SIZE - off2; + p2->page_offset = off2; +} + +static inline void +buffered_pio_flush(struct pio_buffer *piobuf) +{ + IDEState *s = piobuf->opaque; + uint32_t pointer = piobuf->pointer; + + if (s != NULL && pointer > 0) { + uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset; + memcpy(s->data_ptr, buf, pointer); + s->data_ptr += pointer; + } +} + +static inline void +buffered_pio_reset(IDEState *s) +{ + struct pio_buffer *piobuf; + + if ((unsigned)s->drive_serial - 1 < 2) /* 1,2 */ + piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY]; + else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */ + piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY]; + else + return; + buffered_pio_flush(piobuf); + piobuf->pointer = 0; + piobuf->data_end = 0; + piobuf->opaque = NULL; +} + +static inline void +buffered_pio_write(IDEState *s, uint32_t addr, int size) +{ + struct pio_buffer *piobuf = piobuf_by_addr(addr); + int data_end; + + if (!piobuf) + return; + buffered_pio_flush(piobuf); + data_end = s->data_end - s->data_ptr - size; + if (data_end <= 0) + data_end = 0; + else if (data_end > piobuf->buf_size) + data_end = piobuf->buf_size; + piobuf->pointer = 0; + piobuf->data_end = data_end; + piobuf->opaque = s; +} + +static inline void +buffered_pio_read(IDEState *s, uint32_t addr, int size) +{ + struct pio_buffer *piobuf = piobuf_by_addr(addr); + int data_end; + + if (!piobuf) + return; + s->data_ptr += piobuf->pointer; + data_end = s->data_end - s->data_ptr - size; + if (data_end <= 0) { + data_end = 0; + } else { + uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset; + if (data_end > piobuf->buf_size) + data_end = piobuf->buf_size; + memcpy(buf, s->data_ptr + size, data_end); + } + piobuf->pointer = 0; + piobuf->data_end = data_end; + piobuf->opaque = NULL; +} + +#else /* !__ia64__ */ +#define buffered_pio_init() do {} while (0) +#define buffered_pio_reset(I) do {} while (0) +#define buffered_pio_write(I,A,S) do {} while (0) +#define buffered_pio_read(I,A,S) do {} while (0) +#endif + static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); static void padstr(char *str, const char *src, int len) @@ -618,6 +733,7 @@ static void ide_transfer_start(IDEState s->data_ptr = buf; s->data_end = buf + size; s->status |= DRQ_STAT; + buffered_pio_reset(s); } static void ide_transfer_stop(IDEState *s) @@ -626,6 +742,7 @@ static void ide_transfer_stop(IDEState * s->data_ptr = s->io_buffer; s->data_end = s->io_buffer; s->status &= ~DRQ_STAT; + buffered_pio_reset(s); } static int64_t ide_get_sector(IDEState *s) @@ -1562,6 +1679,7 @@ static void ide_ioport_write(void *opaqu ide_if[0].select = (val & ~0x10) | 0xa0; ide_if[1].select = (val | 0x10) | 0xa0; /* select drive */ + buffered_pio_reset(ide_if->cur_drive); unit = (val >> 4) & 1; s = ide_if + unit; ide_if->cur_drive = s; @@ -1928,6 +2046,7 @@ static void ide_data_writew(void *opaque IDEState *s = ((IDEState *)opaque)->cur_drive; uint8_t *p; + buffered_pio_write(s, addr, 2); p = s->data_ptr; *(uint16_t *)p = le16_to_cpu(val); p += 2; @@ -1941,6 +2060,8 @@ static uint32_t ide_data_readw(void *opa IDEState *s = ((IDEState *)opaque)->cur_drive; uint8_t *p; int ret; + + buffered_pio_read(s, addr, 2); p = s->data_ptr; ret = cpu_to_le16(*(uint16_t *)p); p += 2; @@ -1955,6 +2076,7 @@ static void ide_data_writel(void *opaque IDEState *s = ((IDEState *)opaque)->cur_drive; uint8_t *p; + buffered_pio_write(s, addr, 4); p = s->data_ptr; *(uint32_t *)p = le32_to_cpu(val); p += 4; @@ -1969,6 +2091,7 @@ static uint32_t ide_data_readl(void *opa uint8_t *p; int ret; + buffered_pio_read(s, addr, 4); p = s->data_ptr; ret = cpu_to_le32(*(uint32_t *)p); p += 4; @@ -2517,6 +2640,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[2], 0x170, 0x376); + buffered_pio_init(); + register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d); #ifdef DMA_MULTI_THREAD diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/target-i386-dm/qemu-ifup --- a/tools/ioemu/target-i386-dm/qemu-ifup Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/target-i386-dm/qemu-ifup Wed Mar 07 12:38:28 2007 -0700 @@ -3,8 +3,7 @@ #. /etc/rc.d/init.d/functions #ulimit -c unlimited -echo -c 'config qemu network with xen bridge for ' -echo $* +echo 'config qemu network with xen bridge for ' $* ifconfig $1 0.0.0.0 up brctl addif $2 $1 diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/vl.c --- a/tools/ioemu/vl.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/vl.c Wed Mar 07 12:38:28 2007 -0700 @@ -1565,12 +1565,51 @@ CharDriverState *qemu_chr_open_stdio(voi return chr; } -int store_console_dev(int domid, char *pts) +/* + * Create a store entry for a device (e.g., monitor, serial/parallel lines). + * The entry is <domain-path><storeString>/tty and the value is the name + * of the pty associated with the device. + */ +static int store_dev_info(char *devName, int domid, + CharDriverState *cState, char *storeString) { int xc_handle; struct xs_handle *xs; char *path; - + char *newpath; + FDCharDriver *s; + char *pts; + + /* Check for valid arguments (at least, prevent segfaults). */ + if ((devName == NULL) || (cState == NULL) || (storeString == NULL)) { + fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__); + return EINVAL; + } + + /* + * Only continue if we're talking to a pty + * Actually, the following code works for any CharDriverState using + * FDCharDriver, but we really only care about pty's here + */ + if (strcmp(devName, "pty")) + return 0; + + s = cState->opaque; + if (s == NULL) { + fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n", + __FUNCTION__, storeString, devName); + return EBADF; + } + + pts = ptsname(s->fd_in); + if (pts == NULL) { + fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', " + "error %d (%s)\n", + __FUNCTION__, storeString, devName, errno, strerror(errno)); + return errno; + } + + /* We now have everything we need to set the xenstore entry. */ xs = xs_daemon_open(); if (xs == NULL) { fprintf(logfile, "Could not contact XenStore\n"); @@ -1588,14 +1627,19 @@ int store_console_dev(int domid, char *p fprintf(logfile, "xs_get_domain_path() error\n"); return -1; } - path = realloc(path, strlen(path) + strlen("/console/tty") + 1); - if (path == NULL) { + newpath = realloc(path, (strlen(path) + strlen(storeString) + + strlen("/tty") + 1)); + if (newpath == NULL) { + free(path); /* realloc errors leave old block */ fprintf(logfile, "realloc error\n"); return -1; } - strcat(path, "/console/tty"); + path = newpath; + + strcat(path, storeString); + strcat(path, "/tty"); if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) { - fprintf(logfile, "xs_write for console fail"); + fprintf(logfile, "xs_write for '%s' fail", storeString); return -1; } @@ -1622,7 +1666,6 @@ CharDriverState *qemu_chr_open_pty(void) tcsetattr(slave_fd, TCSAFLUSH, &tty); fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd)); - store_console_dev(domid, ptsname(master_fd)); return qemu_chr_open_fd(master_fd, master_fd); } @@ -3207,6 +3250,14 @@ static int net_tap_init(VLANState *vlan, pid = fork(); if (pid >= 0) { if (pid == 0) { + int open_max = sysconf(_SC_OPEN_MAX), i; + for (i = 0; i < open_max; i++) + if (i != STDIN_FILENO && + i != STDOUT_FILENO && + i != STDERR_FILENO && + i != fd) + close(i); + parg = args; *parg++ = (char *)setup_script; *parg++ = ifname; @@ -5768,17 +5819,17 @@ int unset_mm_mapping(int xc_handle, uint int err = 0; xc_dominfo_t info; + xc_domain_getinfo(xc_handle, domid, 1, &info); + if ((info.nr_pages - nr_pages) <= 0) { + fprintf(stderr, "unset_mm_mapping: error nr_pages\n"); + err = -1; + } + err = xc_domain_memory_decrease_reservation(xc_handle, domid, nr_pages, 0, extent_start); if (err) fprintf(stderr, "Failed to decrease physmap\n"); - xc_domain_getinfo(xc_handle, domid, 1, &info); - - if ((info.nr_pages - nr_pages) <= 0) { - fprintf(stderr, "unset_mm_mapping: error nr_pages\n"); - err = -1; - } if (xc_domain_setmaxmem(xc_handle, domid, (info.nr_pages - nr_pages) * PAGE_SIZE/1024) != 0) { @@ -5972,6 +6023,7 @@ int main(int argc, char **argv) xen_pfn_t *page_array; extern void *shared_page; extern void *buffered_io_page; + extern void *buffered_pio_page; char qemu_dm_logfilename[64]; @@ -6044,9 +6096,14 @@ int main(int argc, char **argv) for(i = 1; i < MAX_SERIAL_PORTS; i++) serial_devices[i][0] = '\0'; serial_device_index = 0; - + +#ifndef CONFIG_DM pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc"); for(i = 1; i < MAX_PARALLEL_PORTS; i++) +#else + /* Xen steals IRQ7 for PCI. Disable LPT1 by default. */ + for(i = 0; i < MAX_PARALLEL_PORTS; i++) +#endif parallel_devices[i][0] = '\0'; parallel_device_index = 0; @@ -6571,6 +6628,10 @@ int main(int argc, char **argv) PROT_READ|PROT_WRITE, BUFFER_IO_PAGE_START >> PAGE_SHIFT); + buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ|PROT_WRITE, + BUFFER_PIO_PAGE_START >> PAGE_SHIFT); + for (i = 0; i < tmp_nr_pages; i++) page_array[i] = i; @@ -6684,16 +6745,23 @@ int main(int argc, char **argv) fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device); exit(1); } + store_dev_info(monitor_device, domid, monitor_hd, "/monitor"); monitor_init(monitor_hd, !nographic); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_devices[i][0] != '\0') { + char buf[16]; serial_hds[i] = qemu_chr_open(serial_devices[i]); if (!serial_hds[i]) { fprintf(stderr, "qemu: could not open serial device '%s'\n", serial_devices[i]); exit(1); } + snprintf(buf, sizeof(buf), "/serial/%d", i); + store_dev_info(serial_devices[i], domid, serial_hds[i], buf); + if (i == 0) /* serial 0 is also called the console */ + store_dev_info(serial_devices[i], domid, + serial_hds[i], "/console"); if (!strcmp(serial_devices[i], "vc")) qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i); } @@ -6701,12 +6769,15 @@ int main(int argc, char **argv) for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_devices[i][0] != '\0') { + char buf[16]; parallel_hds[i] = qemu_chr_open(parallel_devices[i]); if (!parallel_hds[i]) { fprintf(stderr, "qemu: could not open parallel device '%s'\n", parallel_devices[i]); exit(1); } + snprintf(buf, sizeof(buf), "/parallel/%d", i); + store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf); if (!strcmp(parallel_devices[i], "vc")) qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i); } diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/vnc.c Wed Mar 07 12:38:28 2007 -0700 @@ -1445,7 +1445,7 @@ int vnc_display_init(DisplayState *ds, i int vnc_start_viewer(int port) { - int pid; + int pid, i, open_max; char s[16]; sprintf(s, ":%d", port); @@ -1456,6 +1456,12 @@ int vnc_start_viewer(int port) exit(1); case 0: /* child */ + open_max = sysconf(_SC_OPEN_MAX); + for (i = 0; i < open_max; i++) + if (i != STDIN_FILENO && + i != STDOUT_FILENO && + i != STDERR_FILENO) + close(i); execlp("vncviewer", "vncviewer", s, NULL); fprintf(stderr, "vncviewer execlp failed\n"); exit(1); diff -r 8a58ea36e420 -r 50d5bf02e59e tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/ioemu/xenstore.c Wed Mar 07 12:38:28 2007 -0700 @@ -16,6 +16,9 @@ static char *hd_filename[MAX_DISKS]; static char *hd_filename[MAX_DISKS]; static QEMUTimer *insert_timer = NULL; +#define UWAIT_MAX (30*1000000) /* thirty seconds */ +#define UWAIT (100000) /* 1/10th second */ + static int pasprintf(char **buf, const char *fmt, ...) { va_list ap; @@ -53,32 +56,20 @@ void xenstore_check_new_media_present(in qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout); } -static int waitForDevice(char *path, char *field, char *desired) +static void waitForDevice(char *fn) { - char *buf = NULL, *stat = NULL; - unsigned int len; - int val = 1; - - /* loop until we find a value in xenstore, return - * if it was what we wanted, or not - */ - while (1) { - if (pasprintf(&buf, "%s/%s", path, field) == -1) - goto done; - free(stat); - stat = xs_read(xsh, XBT_NULL, buf, &len); - if (stat == NULL) { - usleep(100000); /* 1/10th second, no path found */ - } else { - val = strcmp(stat, desired); - goto done; - } - } - -done: - free(stat); - free(buf); - return val; + struct stat sbuf; + int status; + int uwait = UWAIT_MAX; + + do { + status = stat(fn, &sbuf); + if (!status) break; + usleep(UWAIT); + uwait -= UWAIT; + } while (uwait > 0); + + return; } void xenstore_parse_domain_config(int domid) @@ -161,11 +152,6 @@ void xenstore_parse_domain_config(int do free(fpath); fpath = xs_read(xsh, XBT_NULL, buf, &len); if (fpath != NULL) { - - if (waitForDevice(fpath, "hotplug-status", "connected")) { - continue; - } - if (pasprintf(&buf, "%s/dev", fpath) == -1) continue; params = xs_read(xsh, XBT_NULL, buf , &len); @@ -173,6 +159,11 @@ void xenstore_parse_domain_config(int do free(hd_filename[hd_index]); hd_filename[hd_index] = params; params = NULL; /* don't free params on re-use */ + /* + * wait for device, on timeout silently fail because we will + * fail to open below + */ + waitForDevice(hd_filename[hd_index]); } } bs_table[hd_index] = bdrv_new(dev); diff -r 8a58ea36e420 -r 50d5bf02e59e tools/libxc/Makefile --- a/tools/libxc/Makefile Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/libxc/Makefile Wed Mar 07 12:38:28 2007 -0700 @@ -6,6 +6,8 @@ MINOR = 0 CTRL_SRCS-y := CTRL_SRCS-y += xc_core.c +CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c +CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c CTRL_SRCS-y += xc_domain.c CTRL_SRCS-y += xc_evtchn.c CTRL_SRCS-y += xc_misc.c @@ -56,6 +58,9 @@ CFLAGS += -Werror -Wmissing-prototypes CFLAGS += -Werror -Wmissing-prototypes CFLAGS += -fno-strict-aliasing CFLAGS += $(INCLUDES) -I. + +# Needed for posix_fadvise64() in xc_linux.c +CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE # Define this to make it possible to run valgrind on code linked with these # libraries. diff -r 8a58ea36e420 -r 50d5bf02e59e tools/libxc/ia64/xc_ia64_hvm_build.c --- a/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Wed Mar 07 12:38:28 2007 -0700 @@ -569,6 +569,7 @@ setup_guest(int xc_handle, uint32_t dom, xen_pfn_t *pfn_list; shared_iopage_t *sp; void *ioreq_buffer_page; + void *pio_buffer_page; unsigned long dom_memsize = memsize << 20; unsigned long nr_pages = memsize << (20 - PAGE_SHIFT); unsigned long vcpus; @@ -628,9 +629,10 @@ setup_guest(int xc_handle, uint32_t dom, pfn_list[0] = IO_PAGE_START >> PAGE_SHIFT; pfn_list[1] = STORE_PAGE_START >> PAGE_SHIFT; - pfn_list[2] = BUFFER_IO_PAGE_START >> PAGE_SHIFT; - - rc = xc_domain_memory_populate_physmap(xc_handle, dom, 3, + pfn_list[2] = BUFFER_IO_PAGE_START >> PAGE_SHIFT; + pfn_list[3] = BUFFER_PIO_PAGE_START >> PAGE_SHIFT; + + rc = xc_domain_memory_populate_physmap(xc_handle, dom, 4, 0, 0, &pfn_list[0]); if (rc != 0) { PERROR("Could not allocate IO page or store page or buffer io page.\n"); @@ -684,6 +686,12 @@ setup_guest(int xc_handle, uint32_t dom, pfn_list[2]); memset(ioreq_buffer_page,0,PAGE_SIZE); munmap(ioreq_buffer_page, PAGE_SIZE); + + pio_buffer_page = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, + pfn_list[3]); + memset(pio_buffer_page,0,PAGE_SIZE); + munmap(pio_buffer_page, PAGE_SIZE); free(pfn_list); return 0; diff -r 8a58ea36e420 -r 50d5bf02e59e tools/libxc/powerpc64/mk_flatdevtree.c --- a/tools/libxc/powerpc64/mk_flatdevtree.c Thu Mar 01 15:02:09 2007 -0700 +++ b/tools/libxc/powerpc64/mk_flatdevtree.c Wed Mar 07 12:38:28 2007 -0700 @@ -618,7 +618,7 @@ int make_devtree(struct ft_cxt *root, } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |