ia64/xen-unstable

changeset 6547:cc5f88b719d0

Merge.
author adsharma@los-vmm.sc.intel.com
date Tue Aug 23 12:03:21 2005 -0700 (2005-08-23)
parents cd984b3478f6 522bc50588ed
children fa0754a9f64f
files .hgignore Config.mk Makefile buildconfigs/Rules.mk buildconfigs/mk.linux-2.6-xen buildconfigs/mk.linux-2.6-xen0 buildconfigs/mk.linux-2.6-xenU docs/src/user.tex extras/mini-os/include/time.h extras/mini-os/kernel.c extras/mini-os/time.c linux-2.4-xen-sparse/arch/xen/Makefile linux-2.4-xen-sparse/arch/xen/config.in linux-2.4-xen-sparse/arch/xen/kernel/time.c linux-2.4-xen-sparse/include/asm-xen/bugs.h linux-2.4-xen-sparse/include/asm-xen/fixmap.h linux-2.4-xen-sparse/include/asm-xen/highmem.h linux-2.4-xen-sparse/include/asm-xen/hw_irq.h linux-2.4-xen-sparse/include/asm-xen/io.h linux-2.4-xen-sparse/include/asm-xen/irq.h linux-2.4-xen-sparse/include/asm-xen/mmu_context.h linux-2.4-xen-sparse/include/asm-xen/page.h linux-2.4-xen-sparse/include/asm-xen/pci.h linux-2.4-xen-sparse/include/asm-xen/pgalloc.h linux-2.4-xen-sparse/include/asm-xen/pgtable.h linux-2.4-xen-sparse/include/asm-xen/processor.h linux-2.4-xen-sparse/include/asm-xen/segment.h linux-2.4-xen-sparse/include/asm-xen/smp.h linux-2.4-xen-sparse/include/asm-xen/system.h linux-2.4-xen-sparse/include/asm-xen/vga.h linux-2.4-xen-sparse/include/linux/blk.h linux-2.4-xen-sparse/include/linux/highmem.h linux-2.4-xen-sparse/include/linux/irq.h linux-2.4-xen-sparse/include/linux/mm.h linux-2.4-xen-sparse/include/linux/sched.h linux-2.4-xen-sparse/include/linux/skbuff.h linux-2.4-xen-sparse/include/linux/timer.h linux-2.4-xen-sparse/mkbuildtree linux-2.6-xen-sparse/arch/xen/Kconfig linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/i386/Kconfig linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c linux-2.6-xen-sparse/arch/xen/i386/kernel/init_task.c linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c linux-2.6-xen-sparse/arch/xen/i386/kernel/irq.c linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6-xen-sparse/arch/xen/i386/kernel/mpparse.c linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6-xen-sparse/arch/xen/i386/mm/highmem.c linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/xen/i386/mm/init.c linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile linux-2.6-xen-sparse/arch/xen/i386/pci/irq.c linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig linux-2.6-xen-sparse/arch/xen/x86_64/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/kernel/apic.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/pci-nommu.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S linux-2.6-xen-sparse/arch/xen/x86_64/mm/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile linux-2.6-xen-sparse/drivers/xen/Makefile linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/blkback/Makefile linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/interface.c linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap_datapath.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c linux-2.6-xen-sparse/drivers/xen/console/console.c linux-2.6-xen-sparse/drivers/xen/netback/common.h linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/drivers/xen/usbback/common.h linux-2.6-xen-sparse/drivers/xen/usbback/interface.c linux-2.6-xen-sparse/drivers/xen/usbback/usbback.c linux-2.6-xen-sparse/drivers/xen/usbfront/usbfront.c linux-2.6-xen-sparse/drivers/xen/usbfront/xhci.h linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-generic/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/kmap_types.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pci.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/scatterlist.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/swiotlb.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/desc.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/io.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pci.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/processor.h linux-2.6-xen-sparse/include/asm-xen/balloon.h linux-2.6-xen-sparse/include/asm-xen/ctrl_if.h linux-2.6-xen-sparse/include/asm-xen/evtchn.h linux-2.6-xen-sparse/include/asm-xen/gnttab.h linux-2.6-xen-sparse/include/asm-xen/hypervisor.h linux-2.6-xen-sparse/include/asm-xen/xenbus.h linux-2.6-xen-sparse/include/linux/highmem.h linux-2.6-xen-sparse/include/linux/mm.h linux-2.6-xen-sparse/kernel/irq/manage.c linux-2.6-xen-sparse/mkbuildtree linux-2.6-xen-sparse/mm/highmem.c linux-2.6-xen-sparse/mm/memory.c patches/linux-2.6.12/patch-2.6.12.5 patches/linux-2.6.12/smp-alts.patch patches/linux-2.6.12/workaround_double_br_del_if.patch tools/Makefile tools/Rules.mk tools/blktap/blktaplib.c tools/console/client/main.c tools/console/daemon/io.c tools/console/daemon/utils.c tools/debugger/gdb/gdbbuild tools/debugger/libxendebug/xendebug.c tools/debugger/libxendebug/xendebug.h tools/debugger/pdb/Domain.ml tools/debugger/pdb/Domain.mli tools/debugger/pdb/Makefile tools/debugger/pdb/PDB.ml tools/debugger/pdb/Process.ml tools/debugger/pdb/Process.mli tools/debugger/pdb/Util.ml tools/debugger/pdb/Xen_domain.ml tools/debugger/pdb/Xen_domain.mli tools/debugger/pdb/debugger.ml tools/debugger/pdb/linux-2.6-module/Makefile tools/debugger/pdb/linux-2.6-module/debug.c tools/debugger/pdb/linux-2.6-module/module.c tools/debugger/pdb/linux-2.6-module/pdb_debug.h tools/debugger/pdb/linux-2.6-module/pdb_module.h tools/debugger/pdb/linux-2.6-patches/Makefile tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch tools/debugger/pdb/linux-2.6-patches/kdebug.patch tools/debugger/pdb/linux-2.6-patches/makefile.patch tools/debugger/pdb/linux-2.6-patches/ptrace.patch tools/debugger/pdb/linux-2.6-patches/traps.patch tools/debugger/pdb/pdb_caml_domain.c tools/debugger/pdb/pdb_caml_process.c tools/debugger/pdb/pdb_caml_xcs.c tools/debugger/pdb/pdb_caml_xen.h tools/debugger/pdb/readme tools/debugger/pdb/server.ml tools/examples/Makefile tools/examples/network-bridge tools/examples/xend-config.sxp tools/examples/xmexample.vmx tools/firmware/rombios/rombios.c tools/firmware/vmxassist/vm86.c tools/ioemu/cpu-all.h tools/ioemu/exec.c tools/ioemu/hw/ide.c tools/ioemu/hw/pc.c tools/ioemu/hw/pckbd.c tools/ioemu/hw/vga.c tools/ioemu/monitor.c tools/ioemu/target-i386-dm/Makefile tools/ioemu/target-i386-dm/helper2.c tools/ioemu/target-i386-dm/qemu-dm.debug tools/ioemu/vl.c tools/ioemu/vl.h tools/ioemu/vnc.c tools/libxc/Makefile tools/libxc/linux_boot_params.h tools/libxc/xc.h tools/libxc/xc_core.c tools/libxc/xc_domain.c tools/libxc/xc_gnttab.c tools/libxc/xc_linux_build.c tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xc_ptrace.c tools/libxc/xc_vmx_build.c tools/misc/Makefile tools/misc/xend tools/python/setup.py tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/lowlevel/xu/xu.c tools/python/xen/sv/CreateDomain.py tools/python/xen/sv/DomInfo.py tools/python/xen/sv/GenTabbed.py tools/python/xen/sv/HTMLBase.py tools/python/xen/sv/Main.py tools/python/xen/sv/NodeInfo.py tools/python/xen/sv/RestoreDomain.py tools/python/xen/sv/Wizard.py tools/python/xen/sv/__init__.py tools/python/xen/sv/util.py tools/python/xen/web/SrvBase.py tools/python/xen/web/SrvDir.py tools/python/xen/web/__init__.py tools/python/xen/web/connection.py tools/python/xen/web/httpserver.py tools/python/xen/web/protocol.py tools/python/xen/web/reactor.py tools/python/xen/web/resource.py tools/python/xen/web/static.py tools/python/xen/web/tcp.py tools/python/xen/web/unix.py tools/python/xen/xend/Args.py tools/python/xen/xend/EventServer.py tools/python/xen/xend/PrettyPrint.py tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDB.py tools/python/xen/xend/XendDmesg.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendError.py tools/python/xen/xend/XendLogging.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/XendProtocol.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/XendVnet.py tools/python/xen/xend/encode.py tools/python/xen/xend/image.py tools/python/xen/xend/scheduler.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDmesg.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/SrvNode.py tools/python/xen/xend/server/SrvRoot.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/SrvVnetDir.py tools/python/xen/xend/server/SrvXendLog.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/event.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py tools/python/xen/xend/server/params.py tools/python/xen/xend/server/pciif.py tools/python/xen/xend/server/relocate.py tools/python/xen/xend/sxp.py tools/python/xen/xend/uuid.py tools/python/xen/xend/xenstore/__init__.py tools/python/xen/xend/xenstore/xsnode.py tools/python/xen/xend/xenstore/xsobj.py tools/python/xen/xend/xenstore/xsresource.py tools/python/xen/xm/create.py tools/python/xen/xm/destroy.py tools/python/xen/xm/help.py tools/python/xen/xm/main.py tools/python/xen/xm/migrate.py tools/python/xen/xm/opts.py tools/python/xen/xm/shutdown.py tools/python/xen/xm/sysrq.py tools/security/Makefile tools/security/example.txt tools/security/install.txt tools/security/policies/chwall/chwall-security_label_template.xml tools/security/policies/chwall/chwall-security_policy.xml tools/security/policies/chwall_ste/chwall_ste-security_label_template.xml tools/security/policies/chwall_ste/chwall_ste-security_policy.xml tools/security/policies/null/null-security_label_template.xml tools/security/policies/null/null-security_policy.xml tools/security/policies/security_policy.xsd tools/security/policies/ste/ste-security_label_template.xml tools/security/policies/ste/ste-security_policy.xml tools/security/policy.txt tools/security/readme.txt tools/security/secpol_compat.h tools/security/secpol_tool.c tools/security/secpol_xml2bin.c tools/security/secpol_xml2bin.h tools/security/setlabel.sh tools/security/updategrub.sh tools/sv/Makefile tools/sv/images/destroy.png tools/sv/images/finish.png tools/sv/images/next.png tools/sv/images/pause.png tools/sv/images/previous.png tools/sv/images/reboot.png tools/sv/images/shutdown.png tools/sv/images/small-destroy.png tools/sv/images/small-pause.png tools/sv/images/small-unpause.png tools/sv/images/unpause.png tools/sv/images/xen.png tools/sv/inc/script.js tools/sv/inc/style.css tools/sv/index.psp tools/xcs/xcs.h tools/xcutils/xc_restore.c tools/xenstat/Makefile tools/xenstat/libxenstat/COPYING tools/xenstat/libxenstat/Makefile tools/xenstat/libxenstat/bindings/swig/perl/.empty tools/xenstat/libxenstat/bindings/swig/python/.empty tools/xenstat/libxenstat/bindings/swig/xenstat.i tools/xenstat/libxenstat/src/xen-interface.c tools/xenstat/libxenstat/src/xen-interface.h tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat.h tools/xenstat/xentop/Makefile tools/xenstat/xentop/TODO tools/xenstat/xentop/xentop.1 tools/xenstat/xentop/xentop.c tools/xenstore/Makefile tools/xenstore/TODO tools/xenstore/testsuite/test.sh tools/xenstore/utils.c tools/xenstore/utils.h tools/xenstore/xenstored.h tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h tools/xenstore/xenstored_transaction.c tools/xenstore/xenstored_transaction.h tools/xenstore/xenstored_watch.c tools/xenstore/xenstored_watch.h tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_lib.c tools/xenstore/xs_lib.h tools/xenstore/xs_random.c tools/xenstore/xs_test.c tools/xentrace/xentrace.c xen/Makefile xen/Rules.mk xen/acm/acm_core.c xen/acm/acm_policy.c xen/arch/ia64/Makefile xen/arch/ia64/Rules.mk xen/arch/ia64/asm-offsets.c xen/arch/ia64/asm-xsi-offsets.c xen/arch/ia64/dom_fw.c xen/arch/ia64/domain.c xen/arch/ia64/grant_table.c xen/arch/ia64/hypercall.c xen/arch/ia64/hyperprivop.S xen/arch/ia64/mmio.c xen/arch/ia64/pal_emul.c xen/arch/ia64/patch/linux-2.6.11/irq_ia64.c xen/arch/ia64/patch/linux-2.6.11/kregs.h xen/arch/ia64/pcdp.c xen/arch/ia64/process.c xen/arch/ia64/regionreg.c xen/arch/ia64/tools/mkbuildtree xen/arch/ia64/vcpu.c xen/arch/ia64/vlsapic.c xen/arch/ia64/vmmu.c xen/arch/ia64/vmx_hypercall.c xen/arch/ia64/vmx_ivt.S xen/arch/ia64/vmx_support.c xen/arch/ia64/vmx_vcpu.c xen/arch/ia64/vmx_virt.c xen/arch/ia64/vtlb.c xen/arch/ia64/xenasm.S xen/arch/ia64/xenmem.c xen/arch/ia64/xenmisc.c xen/arch/ia64/xensetup.c xen/arch/ia64/xentime.c xen/arch/x86/Makefile xen/arch/x86/acpi/boot.c xen/arch/x86/apic.c xen/arch/x86/audit.c xen/arch/x86/cpu/common.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/genapic/es7000plat.c xen/arch/x86/i8259.c xen/arch/x86/io_apic.c xen/arch/x86/mm.c xen/arch/x86/mpparse.c xen/arch/x86/physdev.c xen/arch/x86/setup.c xen/arch/x86/shadow.c xen/arch/x86/shadow32.c xen/arch/x86/shadow_public.c xen/arch/x86/smpboot.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/arch/x86/x86_64/traps.c xen/common/ac_timer.c xen/common/dom0_ops.c xen/common/dom_mem_ops.c xen/common/domain.c xen/common/event_channel.c xen/common/grant_table.c xen/common/lib.c xen/common/page_alloc.c xen/common/perfc.c xen/common/sched_sedf.c xen/common/schedule.c xen/common/symbols.c xen/common/trace.c xen/common/xmalloc.c xen/drivers/char/console.c xen/drivers/char/ns16550.c xen/include/acm/acm_core.h xen/include/acm/acm_hooks.h xen/include/asm-ia64/config.h xen/include/asm-ia64/domain.h xen/include/asm-ia64/event.h xen/include/asm-ia64/ia64_int.h xen/include/asm-ia64/privop.h xen/include/asm-ia64/regionreg.h xen/include/asm-ia64/regs.h xen/include/asm-ia64/vcpu.h xen/include/asm-ia64/vmx.h xen/include/asm-ia64/vmx_uaccess.h xen/include/asm-ia64/vmx_vcpu.h xen/include/asm-ia64/vmx_vpd.h xen/include/asm-ia64/xensystem.h xen/include/asm-x86/apicdef.h xen/include/asm-x86/config.h xen/include/asm-x86/e820.h xen/include/asm-x86/event.h xen/include/asm-x86/fixmap.h xen/include/asm-x86/genapic.h xen/include/asm-x86/hpet.h xen/include/asm-x86/io.h xen/include/asm-x86/mach-bigsmp/mach_apic.h xen/include/asm-x86/mach-default/mach_apic.h xen/include/asm-x86/mach-es7000/mach_apic.h xen/include/asm-x86/mach-generic/mach_apic.h xen/include/asm-x86/mach-summit/mach_apic.h xen/include/asm-x86/mach-summit/mach_mpparse.h xen/include/asm-x86/mm.h xen/include/asm-x86/page.h xen/include/asm-x86/shadow.h xen/include/asm-x86/shadow_64.h xen/include/asm-x86/shadow_public.h xen/include/asm-x86/time.h xen/include/asm-x86/types.h xen/include/asm-x86/uaccess.h xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_virpit.h xen/include/asm-x86/vmx_vmcs.h xen/include/asm-x86/x86_32/page-3level.h xen/include/asm-x86/x86_32/uaccess.h xen/include/asm-x86/x86_64/page.h xen/include/public/arch-ia64.h xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h xen/include/public/dom0_ops.h xen/include/public/grant_table.h xen/include/public/io/blkif.h xen/include/public/io/domain_controller.h xen/include/public/io/netif.h xen/include/public/physdev.h xen/include/public/trace.h xen/include/public/xen.h xen/include/xen/ac_timer.h xen/include/xen/domain.h xen/include/xen/event.h xen/include/xen/grant_table.h xen/include/xen/mm.h xen/include/xen/perfc_defn.h xen/include/xen/sched.h xen/include/xen/serial.h xen/include/xen/symbols.h xen/include/xen/time.h xen/include/xen/trace.h xen/tools/Makefile xen/tools/symbols.c
line diff
     1.1 --- a/.hgignore	Mon Aug 22 11:37:48 2005 -0700
     1.2 +++ b/.hgignore	Tue Aug 23 12:03:21 2005 -0700
     1.3 @@ -147,6 +147,7 @@
     1.4  ^tools/xcs/xcsdump$
     1.5  ^tools/xcutils/xc_restore$
     1.6  ^tools/xcutils/xc_save$
     1.7 +^tools/xenstat/xentop/xentop$
     1.8  ^tools/xenstore/testsuite/tmp/.*$
     1.9  ^tools/xenstore/xen$
    1.10  ^tools/xenstore/xenstored$
     2.1 --- a/Config.mk	Mon Aug 22 11:37:48 2005 -0700
     2.2 +++ b/Config.mk	Tue Aug 23 12:03:21 2005 -0700
     2.3 @@ -14,6 +14,7 @@ LD         = $(CROSS_COMPILE)ld
     2.4  CC         = $(CROSS_COMPILE)gcc
     2.5  CPP        = $(CROSS_COMPILE)gcc -E
     2.6  AR         = $(CROSS_COMPILE)ar
     2.7 +RANLIB     = $(CROSS_COMPILE)ranlib
     2.8  NM         = $(CROSS_COMPILE)nm
     2.9  STRIP      = $(CROSS_COMPILE)strip
    2.10  OBJCOPY    = $(CROSS_COMPILE)objcopy
    2.11 @@ -43,3 +44,7 @@ KERNEL_REPO = http://www.kernel.org
    2.12  #	ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
    2.13  #	ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
    2.14  ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
    2.15 +
    2.16 +# Optional components
    2.17 +XENSTAT_XENTOP ?= y
    2.18 +
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Mon Aug 22 11:37:48 2005 -0700
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Tue Aug 23 12:03:21 2005 -0700
     3.3 @@ -807,7 +807,107 @@ CONFIG_DUMMY_CONSOLE=y
     3.4  #
     3.5  CONFIG_USB_ARCH_HAS_HCD=y
     3.6  CONFIG_USB_ARCH_HAS_OHCI=y
     3.7 -# CONFIG_USB is not set
     3.8 +CONFIG_USB=y
     3.9 +# CONFIG_USB_DEBUG is not set
    3.10 +
    3.11 +#
    3.12 +# Miscellaneous USB options
    3.13 +#
    3.14 +# CONFIG_USB_DEVICEFS is not set
    3.15 +# CONFIG_USB_BANDWIDTH is not set
    3.16 +# CONFIG_USB_DYNAMIC_MINORS is not set
    3.17 +# CONFIG_USB_OTG is not set
    3.18 +
    3.19 +#
    3.20 +# USB Host Controller Drivers
    3.21 +#
    3.22 +# CONFIG_USB_EHCI_HCD is not set
    3.23 +CONFIG_USB_OHCI_HCD=y
    3.24 +# CONFIG_USB_OHCI_BIG_ENDIAN is not set
    3.25 +CONFIG_USB_OHCI_LITTLE_ENDIAN=y
    3.26 +CONFIG_USB_UHCI_HCD=y
    3.27 +# CONFIG_USB_SL811_HCD is not set
    3.28 +
    3.29 +#
    3.30 +# USB Device Class drivers
    3.31 +#
    3.32 +# CONFIG_USB_BLUETOOTH_TTY is not set
    3.33 +# CONFIG_USB_ACM is not set
    3.34 +# CONFIG_USB_PRINTER is not set
    3.35 +
    3.36 +#
    3.37 +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
    3.38 +#
    3.39 +# CONFIG_USB_STORAGE is not set
    3.40 +
    3.41 +#
    3.42 +# USB Input Devices
    3.43 +#
    3.44 +CONFIG_USB_HID=y
    3.45 +CONFIG_USB_HIDINPUT=y
    3.46 +# CONFIG_HID_FF is not set
    3.47 +# CONFIG_USB_HIDDEV is not set
    3.48 +# CONFIG_USB_AIPTEK is not set
    3.49 +# CONFIG_USB_WACOM is not set
    3.50 +# CONFIG_USB_KBTAB is not set
    3.51 +# CONFIG_USB_POWERMATE is not set
    3.52 +# CONFIG_USB_MTOUCH is not set
    3.53 +# CONFIG_USB_EGALAX is not set
    3.54 +# CONFIG_USB_XPAD is not set
    3.55 +# CONFIG_USB_ATI_REMOTE is not set
    3.56 +
    3.57 +#
    3.58 +# USB Imaging devices
    3.59 +#
    3.60 +# CONFIG_USB_MDC800 is not set
    3.61 +# CONFIG_USB_MICROTEK is not set
    3.62 +
    3.63 +#
    3.64 +# USB Multimedia devices
    3.65 +#
    3.66 +# CONFIG_USB_DABUSB is not set
    3.67 +
    3.68 +#
    3.69 +# Video4Linux support is needed for USB Multimedia device support
    3.70 +#
    3.71 +
    3.72 +#
    3.73 +# USB Network Adapters
    3.74 +#
    3.75 +# CONFIG_USB_CATC is not set
    3.76 +# CONFIG_USB_KAWETH is not set
    3.77 +# CONFIG_USB_PEGASUS is not set
    3.78 +# CONFIG_USB_RTL8150 is not set
    3.79 +# CONFIG_USB_USBNET is not set
    3.80 +CONFIG_USB_MON=y
    3.81 +
    3.82 +#
    3.83 +# USB port drivers
    3.84 +#
    3.85 +
    3.86 +#
    3.87 +# USB Serial Converter support
    3.88 +#
    3.89 +# CONFIG_USB_SERIAL is not set
    3.90 +
    3.91 +#
    3.92 +# USB Miscellaneous drivers
    3.93 +#
    3.94 +# CONFIG_USB_EMI62 is not set
    3.95 +# CONFIG_USB_EMI26 is not set
    3.96 +# CONFIG_USB_AUERSWALD is not set
    3.97 +# CONFIG_USB_RIO500 is not set
    3.98 +# CONFIG_USB_LEGOTOWER is not set
    3.99 +# CONFIG_USB_LCD is not set
   3.100 +# CONFIG_USB_LED is not set
   3.101 +# CONFIG_USB_CYTHERM is not set
   3.102 +# CONFIG_USB_PHIDGETKIT is not set
   3.103 +# CONFIG_USB_PHIDGETSERVO is not set
   3.104 +# CONFIG_USB_IDMOUSE is not set
   3.105 +
   3.106 +#
   3.107 +# USB ATM/DSL drivers
   3.108 +#
   3.109  
   3.110  #
   3.111  # USB Gadget Support
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/mpparse.c	Mon Aug 22 11:37:48 2005 -0700
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/mpparse.c	Tue Aug 23 12:03:21 2005 -0700
     4.3 @@ -784,7 +784,9 @@ static int __init smp_scan_config (unsig
     4.4  
     4.5  void __init find_smp_config (void)
     4.6  {
     4.7 +#ifndef CONFIG_XEN
     4.8  	unsigned int address;
     4.9 +#endif
    4.10  
    4.11  	/*
    4.12  	 * FIXME: Linux assumes you have 640K of base ram..
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Mon Aug 22 11:37:48 2005 -0700
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Tue Aug 23 12:03:21 2005 -0700
     5.3 @@ -149,12 +149,12 @@ void cpu_idle (void)
     5.4  
     5.5  			if (cpu_is_offline(cpu)) {
     5.6  				local_irq_disable();
     5.7 +#if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
     5.8  				/* Ack it.  From this point on until
     5.9  				   we get woken up, we're not allowed
    5.10  				   to take any locks.  In particular,
    5.11  				   don't printk. */
    5.12  				__get_cpu_var(cpu_state) = CPU_DEAD;
    5.13 -#if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
    5.14  				/* Tell hypervisor to take vcpu down. */
    5.15  				HYPERVISOR_vcpu_down(cpu);
    5.16  #endif
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Mon Aug 22 11:37:48 2005 -0700
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Aug 23 12:03:21 2005 -0700
     6.3 @@ -1575,19 +1575,20 @@ void __init setup_arch(char **cmdline_p)
     6.4  	/* Make sure we have a correctly sized P->M table. */
     6.5  	if (max_pfn != xen_start_info.nr_pages) {
     6.6  		phys_to_machine_mapping = alloc_bootmem_low_pages(
     6.7 -			max_pfn * sizeof(unsigned long));
     6.8 +			max_pfn * sizeof(unsigned int));
     6.9  
    6.10  		if (max_pfn > xen_start_info.nr_pages) {
    6.11  			/* set to INVALID_P2M_ENTRY */
    6.12  			memset(phys_to_machine_mapping, ~0,
    6.13 -				max_pfn * sizeof(unsigned long));
    6.14 +				max_pfn * sizeof(unsigned int));
    6.15  			memcpy(phys_to_machine_mapping,
    6.16 -				(unsigned long *)xen_start_info.mfn_list,
    6.17 -				xen_start_info.nr_pages * sizeof(unsigned long));
    6.18 +				(unsigned int *)xen_start_info.mfn_list,
    6.19 +				xen_start_info.nr_pages * sizeof(unsigned int));
    6.20  		} else {
    6.21  			memcpy(phys_to_machine_mapping,
    6.22 -				(unsigned long *)xen_start_info.mfn_list,
    6.23 -				max_pfn * sizeof(unsigned long));
    6.24 +				(unsigned int *)xen_start_info.mfn_list,
    6.25 +				max_pfn * sizeof(unsigned int));
    6.26 +			/* N.B. below relies on sizeof(int) == sizeof(long). */
    6.27  			if (HYPERVISOR_dom_mem_op(
    6.28  				MEMOP_decrease_reservation,
    6.29  				(unsigned long *)xen_start_info.mfn_list + max_pfn,
    6.30 @@ -1597,11 +1598,11 @@ void __init setup_arch(char **cmdline_p)
    6.31  		free_bootmem(
    6.32  			__pa(xen_start_info.mfn_list), 
    6.33  			PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
    6.34 -			sizeof(unsigned long))));
    6.35 +			sizeof(unsigned int))));
    6.36  	}
    6.37  
    6.38  	pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
    6.39 -	for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    6.40 +	for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned int)), j++ )
    6.41  	{	
    6.42  	     pfn_to_mfn_frame_list[j] = 
    6.43  		  virt_to_mfn(&phys_to_machine_mapping[i]);
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Mon Aug 22 11:37:48 2005 -0700
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Tue Aug 23 12:03:21 2005 -0700
     7.3 @@ -1604,6 +1604,9 @@ static void smp_intr_exit(void)
     7.4  	unbind_ipi_from_irq(CALL_FUNCTION_VECTOR);
     7.5  }
     7.6  
     7.7 +extern void local_setup_timer_irq(void);
     7.8 +extern void local_teardown_timer_irq(void);
     7.9 +
    7.10  void smp_suspend(void)
    7.11  {
    7.12  	/* XXX todo: take down time and ipi's on all cpus */
     8.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Mon Aug 22 11:37:48 2005 -0700
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Tue Aug 23 12:03:21 2005 -0700
     8.3 @@ -281,7 +281,7 @@ fastcall void do_page_fault(struct pt_re
     8.4  	siginfo_t info;
     8.5  
     8.6  	/* Set the "privileged fault" bit to something sane. */
     8.7 -	error_code &= 3;
     8.8 +	error_code &= ~4;
     8.9  	error_code |= (regs->xcs & 2) << 1;
    8.10  	if (regs->eflags & X86_EFLAGS_VM)
    8.11  		error_code |= 4;
     9.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Mon Aug 22 11:37:48 2005 -0700
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Tue Aug 23 12:03:21 2005 -0700
     9.3 @@ -348,9 +348,12 @@ static void __init pagetable_init (void)
     9.4  {
     9.5  	unsigned long vaddr;
     9.6  	pgd_t *pgd_base = (pgd_t *)xen_start_info.pt_base;
     9.7 +	int i;
     9.8  
     9.9  	swapper_pg_dir = pgd_base;
    9.10  	init_mm.pgd    = pgd_base;
    9.11 +	for (i = 0; i < NR_CPUS; i++)
    9.12 +		per_cpu(cur_pgd, i) = pgd_base;
    9.13  
    9.14  	/* Enable PSE if available */
    9.15  	if (cpu_has_pse) {
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Mon Aug 22 11:37:48 2005 -0700
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Aug 23 12:03:21 2005 -0700
    10.3 @@ -36,6 +36,8 @@ void iounmap(volatile void __iomem *addr
    10.4  {
    10.5  }
    10.6  
    10.7 +#ifdef __i386__
    10.8 +
    10.9  void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
   10.10  {
   10.11  	return NULL;
   10.12 @@ -45,6 +47,8 @@ void __init bt_iounmap(void *addr, unsig
   10.13  {
   10.14  }
   10.15  
   10.16 +#endif /* __i386__ */
   10.17 +
   10.18  #else
   10.19  
   10.20  /*
   10.21 @@ -58,7 +62,7 @@ static inline int is_local_lowmem(unsign
   10.22  	extern unsigned long max_low_pfn;
   10.23  	unsigned long mfn = address >> PAGE_SHIFT;
   10.24  	unsigned long pfn = mfn_to_pfn(mfn);
   10.25 -	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
   10.26 +	return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
   10.27  }
   10.28  
   10.29  /*
   10.30 @@ -126,10 +130,12 @@ void __iomem * __ioremap(unsigned long p
   10.31  		return NULL;
   10.32  	area->phys_addr = phys_addr;
   10.33  	addr = (void __iomem *) area->addr;
   10.34 +	flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
   10.35 +#ifdef __x86_64__
   10.36 +	flags |= _PAGE_USER;
   10.37 +#endif
   10.38  	if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr,
   10.39 -				    size, __pgprot(_PAGE_PRESENT | _PAGE_RW |
   10.40 -						   _PAGE_DIRTY | _PAGE_ACCESSED
   10.41 -						   | flags), domid)) {
   10.42 +				    size, __pgprot(flags), domid)) {
   10.43  		vunmap((void __force *) addr);
   10.44  		return NULL;
   10.45  	}
   10.46 @@ -218,6 +224,8 @@ void iounmap(volatile void __iomem *addr
   10.47  	kfree(p); 
   10.48  }
   10.49  
   10.50 +#ifdef __i386__
   10.51 +
   10.52  void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
   10.53  {
   10.54  	unsigned long offset, last_addr;
   10.55 @@ -289,6 +297,8 @@ void __init bt_iounmap(void *addr, unsig
   10.56  	}
   10.57  }
   10.58  
   10.59 +#endif /* __i386__ */
   10.60 +
   10.61  #endif /* CONFIG_XEN_PHYSDEV_ACCESS */
   10.62  
   10.63  /* These hacky macros avoid phys->machine translations. */
   10.64 @@ -346,7 +356,7 @@ int direct_remap_area_pages(struct mm_st
   10.65  		 * Fill in the machine address: PTE ptr is done later by
   10.66  		 * __direct_remap_area_pages(). 
   10.67  		 */
   10.68 -		v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
   10.69 +		v->val = pte_val_ma(pfn_pte_ma(machine_addr >> PAGE_SHIFT, prot));
   10.70  
   10.71  		machine_addr += PAGE_SIZE;
   10.72  		address += PAGE_SIZE; 
   10.73 @@ -368,35 +378,37 @@ int direct_remap_area_pages(struct mm_st
   10.74  
   10.75  EXPORT_SYMBOL(direct_remap_area_pages);
   10.76  
   10.77 +static int lookup_pte_fn(
   10.78 +	pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
   10.79 +{
   10.80 +	unsigned long *ptep = (unsigned long *)data;
   10.81 +	if (ptep)
   10.82 +		*ptep = (pfn_to_mfn(page_to_pfn(pte_page)) <<
   10.83 +			 PAGE_SHIFT) |
   10.84 +			((unsigned long)pte & ~PAGE_MASK);
   10.85 +	return 0;
   10.86 +}
   10.87 +
   10.88  int create_lookup_pte_addr(struct mm_struct *mm, 
   10.89  			   unsigned long address,
   10.90  			   unsigned long *ptep)
   10.91  {
   10.92 -	int f(pte_t *pte, struct page *pte_page, unsigned long addr,
   10.93 -	      void *data) {
   10.94 -		unsigned long *ptep = (unsigned long *)data;
   10.95 -		if (ptep)
   10.96 -			*ptep = (pfn_to_mfn(page_to_pfn(pte_page)) <<
   10.97 -				 PAGE_SHIFT) |
   10.98 -				((unsigned long)pte & ~PAGE_MASK);
   10.99 -		return 0;
  10.100 -	}
  10.101 -
  10.102 -	return generic_page_range(mm, address, PAGE_SIZE, f, ptep);
  10.103 +	return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
  10.104  }
  10.105  
  10.106  EXPORT_SYMBOL(create_lookup_pte_addr);
  10.107  
  10.108 +static int noop_fn(
  10.109 +	pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
  10.110 +{
  10.111 +	return 0;
  10.112 +}
  10.113 +
  10.114  int touch_pte_range(struct mm_struct *mm,
  10.115  		    unsigned long address,
  10.116  		    unsigned long size)
  10.117  {
  10.118 -	int f(pte_t *pte, struct page *pte_page, unsigned long addr,
  10.119 -	      void *data) {
  10.120 -		return 0;
  10.121 -	}
  10.122 -
  10.123 -	return generic_page_range(mm, address, size, f, NULL);
  10.124 +	return generic_page_range(mm, address, size, noop_fn, NULL);
  10.125  } 
  10.126  
  10.127  EXPORT_SYMBOL(touch_pte_range);
    11.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Mon Aug 22 11:37:48 2005 -0700
    11.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Tue Aug 23 12:03:21 2005 -0700
    11.3 @@ -435,9 +435,11 @@ void unbind_evtchn_from_irqhandler(unsig
    11.4      unbind_evtchn_from_irq(evtchn);
    11.5  }
    11.6  
    11.7 +#ifdef CONFIG_SMP
    11.8  static void do_nothing_function(void *ign)
    11.9  {
   11.10  }
   11.11 +#endif
   11.12  
   11.13  /* Rebind an evtchn so that it gets delivered to a specific cpu */
   11.14  static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Mon Aug 22 11:37:48 2005 -0700
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Tue Aug 23 12:03:21 2005 -0700
    12.3 @@ -40,38 +40,82 @@ EXPORT_SYMBOL(gnttab_grant_foreign_trans
    12.4  EXPORT_SYMBOL(gnttab_end_foreign_transfer);
    12.5  EXPORT_SYMBOL(gnttab_alloc_grant_references);
    12.6  EXPORT_SYMBOL(gnttab_free_grant_references);
    12.7 +EXPORT_SYMBOL(gnttab_free_grant_reference);
    12.8  EXPORT_SYMBOL(gnttab_claim_grant_reference);
    12.9  EXPORT_SYMBOL(gnttab_release_grant_reference);
   12.10  EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
   12.11  EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
   12.12  
   12.13 -static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES];
   12.14 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
   12.15 +#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
   12.16 +
   12.17 +static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
   12.18 +static int gnttab_free_count = NR_GRANT_ENTRIES;
   12.19  static grant_ref_t gnttab_free_head;
   12.20 +static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
   12.21  
   12.22  static grant_entry_t *shared;
   12.23  
   12.24 -/*
   12.25 - * Lock-free grant-entry allocator
   12.26 - */
   12.27 +static struct gnttab_free_callback *gnttab_free_callback_list = NULL;
   12.28  
   12.29 -static inline int
   12.30 -get_free_entry(
   12.31 -    void)
   12.32 +static int
   12.33 +get_free_entries(int count)
   12.34  {
   12.35 -    grant_ref_t fh, nfh = gnttab_free_head;
   12.36 -    do { if ( unlikely((fh = nfh) == NR_GRANT_ENTRIES) ) return -1; }
   12.37 -    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
   12.38 -                                    gnttab_free_list[fh])) != fh) );
   12.39 -    return fh;
   12.40 +    unsigned long flags;
   12.41 +    int ref;
   12.42 +    grant_ref_t head;
   12.43 +    spin_lock_irqsave(&gnttab_list_lock, flags);
   12.44 +    if (gnttab_free_count < count) {
   12.45 +	spin_unlock_irqrestore(&gnttab_list_lock, flags);
   12.46 +	return -1;
   12.47 +    }
   12.48 +    ref = head = gnttab_free_head;
   12.49 +    gnttab_free_count -= count;
   12.50 +    while (count-- > 1)
   12.51 +	head = gnttab_list[head];
   12.52 +    gnttab_free_head = gnttab_list[head];
   12.53 +    gnttab_list[head] = GNTTAB_LIST_END;
   12.54 +    spin_unlock_irqrestore(&gnttab_list_lock, flags);
   12.55 +    return ref;
   12.56 +}
   12.57 +
   12.58 +#define get_free_entry() get_free_entries(1)
   12.59 +
   12.60 +static void
   12.61 +do_free_callbacks(void)
   12.62 +{
   12.63 +    struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
   12.64 +    gnttab_free_callback_list = NULL;
   12.65 +    while (callback) {
   12.66 +	next = callback->next;
   12.67 +	if (gnttab_free_count >= callback->count) {
   12.68 +	    callback->next = NULL;
   12.69 +	    callback->fn(callback->arg);
   12.70 +	} else {
   12.71 +	    callback->next = gnttab_free_callback_list;
   12.72 +	    gnttab_free_callback_list = callback;
   12.73 +	}
   12.74 +	callback = next;
   12.75 +    }
   12.76  }
   12.77  
   12.78  static inline void
   12.79 -put_free_entry(
   12.80 -    grant_ref_t ref)
   12.81 +check_free_callbacks(void)
   12.82  {
   12.83 -    grant_ref_t fh, nfh = gnttab_free_head;
   12.84 -    do { gnttab_free_list[ref] = fh = nfh; wmb(); }
   12.85 -    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
   12.86 +    if (unlikely(gnttab_free_callback_list))
   12.87 +	do_free_callbacks();
   12.88 +}
   12.89 +
   12.90 +static void
   12.91 +put_free_entry(grant_ref_t ref)
   12.92 +{
   12.93 +    unsigned long flags;
   12.94 +    spin_lock_irqsave(&gnttab_list_lock, flags);
   12.95 +    gnttab_list[ref] = gnttab_free_head;
   12.96 +    gnttab_free_head = ref;
   12.97 +    gnttab_free_count++;
   12.98 +    check_free_callbacks();
   12.99 +    spin_unlock_irqrestore(&gnttab_list_lock, flags);
  12.100  }
  12.101  
  12.102  /*
  12.103 @@ -79,8 +123,7 @@ put_free_entry(
  12.104   */
  12.105  
  12.106  int
  12.107 -gnttab_grant_foreign_access(
  12.108 -    domid_t domid, unsigned long frame, int readonly)
  12.109 +gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
  12.110  {
  12.111      int ref;
  12.112      
  12.113 @@ -96,8 +139,8 @@ gnttab_grant_foreign_access(
  12.114  }
  12.115  
  12.116  void
  12.117 -gnttab_grant_foreign_access_ref(
  12.118 -    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly)
  12.119 +gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
  12.120 +				unsigned long frame, int readonly)
  12.121  {
  12.122      shared[ref].frame = frame;
  12.123      shared[ref].domid = domid;
  12.124 @@ -107,7 +150,7 @@ gnttab_grant_foreign_access_ref(
  12.125  
  12.126  
  12.127  int
  12.128 -gnttab_query_foreign_access( grant_ref_t ref )
  12.129 +gnttab_query_foreign_access(grant_ref_t ref)
  12.130  {
  12.131      u16 nflags;
  12.132  
  12.133 @@ -117,7 +160,7 @@ gnttab_query_foreign_access( grant_ref_t
  12.134  }
  12.135  
  12.136  void
  12.137 -gnttab_end_foreign_access( grant_ref_t ref, int readonly )
  12.138 +gnttab_end_foreign_access(grant_ref_t ref, int readonly)
  12.139  {
  12.140      u16 flags, nflags;
  12.141  
  12.142 @@ -132,8 +175,7 @@ gnttab_end_foreign_access( grant_ref_t r
  12.143  }
  12.144  
  12.145  int
  12.146 -gnttab_grant_foreign_transfer(
  12.147 -    domid_t domid, unsigned long pfn )
  12.148 +gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
  12.149  {
  12.150      int ref;
  12.151  
  12.152 @@ -149,8 +191,8 @@ gnttab_grant_foreign_transfer(
  12.153  }
  12.154  
  12.155  void
  12.156 -gnttab_grant_foreign_transfer_ref(
  12.157 -    grant_ref_t ref, domid_t domid, unsigned long pfn )
  12.158 +gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
  12.159 +				  unsigned long pfn)
  12.160  {
  12.161      shared[ref].frame = pfn;
  12.162      shared[ref].domid = domid;
  12.163 @@ -159,8 +201,7 @@ gnttab_grant_foreign_transfer_ref(
  12.164  }
  12.165  
  12.166  unsigned long
  12.167 -gnttab_end_foreign_transfer(
  12.168 -    grant_ref_t ref)
  12.169 +gnttab_end_foreign_transfer(grant_ref_t ref)
  12.170  {
  12.171      unsigned long frame = 0;
  12.172      u16           flags;
  12.173 @@ -189,61 +230,81 @@ gnttab_end_foreign_transfer(
  12.174  }
  12.175  
  12.176  void
  12.177 -gnttab_free_grant_references( u16 count, grant_ref_t head )
  12.178 +gnttab_free_grant_reference(grant_ref_t ref)
  12.179  {
  12.180 -    /* TODO: O(N)...? */
  12.181 -    grant_ref_t to_die = 0, next = head;
  12.182 -    int i;
  12.183  
  12.184 -    for ( i = 0; i < count; i++ )
  12.185 -    {
  12.186 -        to_die = next;
  12.187 -        next = gnttab_free_list[next];
  12.188 -        put_free_entry( to_die );
  12.189 +    put_free_entry(ref);
  12.190 +}
  12.191 +
  12.192 +void
  12.193 +gnttab_free_grant_references(grant_ref_t head)
  12.194 +{
  12.195 +    grant_ref_t ref;
  12.196 +    unsigned long flags;
  12.197 +    int count = 1;
  12.198 +    if (head == GNTTAB_LIST_END)
  12.199 +	return;
  12.200 +    spin_lock_irqsave(&gnttab_list_lock, flags);
  12.201 +    ref = head;
  12.202 +    while (gnttab_list[ref] != GNTTAB_LIST_END) {
  12.203 +	ref = gnttab_list[ref];
  12.204 +	count++;
  12.205      }
  12.206 +    gnttab_list[ref] = gnttab_free_head;
  12.207 +    gnttab_free_head = head;
  12.208 +    gnttab_free_count += count;
  12.209 +    check_free_callbacks();
  12.210 +    spin_unlock_irqrestore(&gnttab_list_lock, flags);
  12.211  }
  12.212  
  12.213  int
  12.214 -gnttab_alloc_grant_references( u16 count,
  12.215 -                               grant_ref_t *head,
  12.216 -                               grant_ref_t *terminal )
  12.217 +gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
  12.218  {
  12.219 -    int i;
  12.220 -    grant_ref_t h = gnttab_free_head;
  12.221 +    int h = get_free_entries(count);
  12.222  
  12.223 -    for ( i = 0; i < count; i++ )
  12.224 -        if ( unlikely(get_free_entry() == -1) )
  12.225 -            goto not_enough_refs;
  12.226 +    if (h == -1)
  12.227 +	return -ENOSPC;
  12.228  
  12.229      *head = h;
  12.230 -    *terminal = gnttab_free_head;
  12.231  
  12.232      return 0;
  12.233 -
  12.234 -not_enough_refs:
  12.235 -    gnttab_free_head = h;
  12.236 -    return -ENOSPC;
  12.237  }
  12.238  
  12.239  int
  12.240 -gnttab_claim_grant_reference( grant_ref_t *private_head,
  12.241 -                              grant_ref_t  terminal )
  12.242 +gnttab_claim_grant_reference(grant_ref_t *private_head)
  12.243  {
  12.244 -    grant_ref_t g;
  12.245 -    if ( unlikely((g = *private_head) == terminal) )
  12.246 +    grant_ref_t g = *private_head;
  12.247 +    if (unlikely(g == GNTTAB_LIST_END))
  12.248          return -ENOSPC;
  12.249 -    *private_head = gnttab_free_list[g];
  12.250 +    *private_head = gnttab_list[g];
  12.251      return g;
  12.252  }
  12.253  
  12.254  void
  12.255 -gnttab_release_grant_reference( grant_ref_t *private_head,
  12.256 -                                grant_ref_t  release )
  12.257 +gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t  release)
  12.258  {
  12.259 -    gnttab_free_list[release] = *private_head;
  12.260 +    gnttab_list[release] = *private_head;
  12.261      *private_head = release;
  12.262  }
  12.263  
  12.264 +void
  12.265 +gnttab_request_free_callback(struct gnttab_free_callback *callback,
  12.266 +			     void (*fn)(void *), void *arg, u16 count)
  12.267 +{
  12.268 +    unsigned long flags;
  12.269 +    spin_lock_irqsave(&gnttab_list_lock, flags);
  12.270 +    if (callback->next)
  12.271 +	goto out;
  12.272 +    callback->fn = fn;
  12.273 +    callback->arg = arg;
  12.274 +    callback->count = count;
  12.275 +    callback->next = gnttab_free_callback_list;
  12.276 +    gnttab_free_callback_list = callback;
  12.277 +    check_free_callbacks();
  12.278 + out:
  12.279 +    spin_unlock_irqrestore(&gnttab_list_lock, flags);
  12.280 +}
  12.281 +
  12.282  /*
  12.283   * ProcFS operations
  12.284   */
  12.285 @@ -252,8 +313,9 @@ gnttab_release_grant_reference( grant_re
  12.286  
  12.287  static struct proc_dir_entry *grant_pde;
  12.288  
  12.289 -static int grant_ioctl(struct inode *inode, struct file *file,
  12.290 -                       unsigned int cmd, unsigned long data)
  12.291 +static int
  12.292 +grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  12.293 +	    unsigned long data)
  12.294  {
  12.295      int                     ret;
  12.296      privcmd_hypercall_t     hypercall;
  12.297 @@ -291,8 +353,9 @@ static struct file_operations grant_file
  12.298      ioctl:  grant_ioctl,
  12.299  };
  12.300  
  12.301 -static int grant_read(char *page, char **start, off_t off,
  12.302 -                      int count, int *eof, void *data)
  12.303 +static int
  12.304 +grant_read(char *page, char **start, off_t off, int count, int *eof,
  12.305 +	   void *data)
  12.306  {
  12.307      int             len;
  12.308      unsigned int    i;
  12.309 @@ -321,8 +384,9 @@ static int grant_read(char *page, char *
  12.310      return len;
  12.311  }
  12.312  
  12.313 -static int grant_write(struct file *file, const char __user *buffer,
  12.314 -                       unsigned long count, void *data)
  12.315 +static int
  12.316 +grant_write(struct file *file, const char __user *buffer, unsigned long count,
  12.317 +	    void *data)
  12.318  {
  12.319      /* TODO: implement this */
  12.320      return -ENOSYS;
  12.321 @@ -330,7 +394,8 @@ static int grant_write(struct file *file
  12.322  
  12.323  #endif /* CONFIG_PROC_FS */
  12.324  
  12.325 -int gnttab_resume(void)
  12.326 +int
  12.327 +gnttab_resume(void)
  12.328  {
  12.329      gnttab_setup_table_t setup;
  12.330      unsigned long        frames[NR_GRANT_FRAMES];
  12.331 @@ -349,7 +414,8 @@ int gnttab_resume(void)
  12.332      return 0;
  12.333  }
  12.334  
  12.335 -int gnttab_suspend(void)
  12.336 +int
  12.337 +gnttab_suspend(void)
  12.338  {
  12.339      int i;
  12.340  
  12.341 @@ -359,7 +425,8 @@ int gnttab_suspend(void)
  12.342      return 0;
  12.343  }
  12.344  
  12.345 -static int __init gnttab_init(void)
  12.346 +static int __init
  12.347 +gnttab_init(void)
  12.348  {
  12.349      int i;
  12.350  
  12.351 @@ -368,7 +435,7 @@ static int __init gnttab_init(void)
  12.352      shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
  12.353  
  12.354      for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
  12.355 -        gnttab_free_list[i] = i + 1;
  12.356 +        gnttab_list[i] = i + 1;
  12.357      
  12.358  #ifdef CONFIG_PROC_FS
  12.359      /*
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Mon Aug 22 11:37:48 2005 -0700
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Tue Aug 23 12:03:21 2005 -0700
    13.3 @@ -44,7 +44,7 @@ obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer.o
    13.4  
    13.5  c-obj-$(CONFIG_MODULES)		+= module.o
    13.6  
    13.7 -#obj-y				+= topology.o
    13.8 +obj-y				+= topology.o
    13.9  c-obj-y				+= intel_cacheinfo.o
   13.10  
   13.11  bootflag-y			+= ../../../i386/kernel/bootflag.o
    14.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Mon Aug 22 11:37:48 2005 -0700
    14.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Aug 23 12:03:21 2005 -0700
    14.3 @@ -778,21 +778,21 @@ void __init setup_arch(char **cmdline_p)
    14.4  		/* Make sure we have a large enough P->M table. */
    14.5  		if (end_pfn > xen_start_info.nr_pages) {
    14.6  			phys_to_machine_mapping = alloc_bootmem(
    14.7 -				max_pfn * sizeof(unsigned long));
    14.8 +				max_pfn * sizeof(u32));
    14.9  			memset(phys_to_machine_mapping, ~0,
   14.10 -			       max_pfn * sizeof(unsigned long));
   14.11 +			       max_pfn * sizeof(u32));
   14.12  			memcpy(phys_to_machine_mapping,
   14.13 -			       (unsigned long *)xen_start_info.mfn_list,
   14.14 -			       xen_start_info.nr_pages * sizeof(unsigned long));
   14.15 +			       (u32 *)xen_start_info.mfn_list,
   14.16 +			       xen_start_info.nr_pages * sizeof(u32));
   14.17  			free_bootmem(
   14.18  				__pa(xen_start_info.mfn_list), 
   14.19  				PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
   14.20 -						sizeof(unsigned long))));
   14.21 +						sizeof(u32))));
   14.22  		}
   14.23  
   14.24  		pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE);
   14.25  
   14.26 -		for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
   14.27 +		for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(u32)), j++ )
   14.28  		{	
   14.29  			pfn_to_mfn_frame_list[j] = 
   14.30  				virt_to_mfn(&phys_to_machine_mapping[i]);
    15.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/Makefile	Mon Aug 22 11:37:48 2005 -0700
    15.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/Makefile	Tue Aug 23 12:03:21 2005 -0700
    15.3 @@ -6,10 +6,10 @@ XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
    15.4  
    15.5  CFLAGS	+= -Iarch/$(XENARCH)/mm
    15.6  
    15.7 -obj-y	:= init.o fault.o ioremap.o pageattr.o
    15.8 +obj-y	:= init.o fault.o pageattr.o
    15.9  c-obj-y	:= extable.o
   15.10  
   15.11 -i386-obj-y := hypervisor.o
   15.12 +i386-obj-y := hypervisor.o ioremap.o
   15.13  
   15.14  #obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
   15.15  #c-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
    16.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Mon Aug 22 11:37:48 2005 -0700
    16.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Tue Aug 23 12:03:21 2005 -0700
    16.3 @@ -559,6 +559,11 @@ static void xen_copy_pt(void)
    16.4  
    16.5  void __init xen_init_pt(void)
    16.6  {
    16.7 +	int i;
    16.8 +
    16.9 +	for (i = 0; i < NR_CPUS; i++)
   16.10 +		per_cpu(cur_pgd, i) = init_mm.pgd;
   16.11 +
   16.12  	memcpy((void *)init_level4_pgt, 
   16.13  	       (void *)xen_start_info.pt_base, PAGE_SIZE);
   16.14  
    17.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c	Mon Aug 22 11:37:48 2005 -0700
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,497 +0,0 @@
    17.4 -/*
    17.5 - * arch/x86_64/mm/ioremap.c
    17.6 - *
    17.7 - * Re-map IO memory to kernel address space so that we can access it.
    17.8 - * This is needed for high PCI addresses that aren't mapped in the
    17.9 - * 640k-1MB IO memory area on PC's
   17.10 - *
   17.11 - * (C) Copyright 1995 1996 Linus Torvalds
   17.12 - */
   17.13 -
   17.14 -#include <linux/vmalloc.h>
   17.15 -#include <linux/init.h>
   17.16 -#include <linux/slab.h>
   17.17 -#include <linux/module.h>
   17.18 -#include <asm/io.h>
   17.19 -#include <asm/fixmap.h>
   17.20 -#include <asm/cacheflush.h>
   17.21 -#include <asm/tlbflush.h>
   17.22 -#include <asm/pgtable.h>
   17.23 -#include <asm/pgalloc.h>
   17.24 -
   17.25 -/*
   17.26 - * Reuse arch/xen/i396/mm/ioremap.c. Need to merge later
   17.27 - */
   17.28 -#ifndef CONFIG_XEN_PHYSDEV_ACCESS
   17.29 -
   17.30 -void * __ioremap(unsigned long phys_addr, unsigned long size,
   17.31 -		 unsigned long flags)
   17.32 -{
   17.33 -	return NULL;
   17.34 -}
   17.35 -
   17.36 -void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
   17.37 -{
   17.38 -	return NULL;
   17.39 -}
   17.40 -
   17.41 -void iounmap(volatile void __iomem *addr)
   17.42 -{
   17.43 -}
   17.44 -
   17.45 -void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
   17.46 -{
   17.47 -	return NULL;
   17.48 -}
   17.49 -
   17.50 -void __init bt_iounmap(void *addr, unsigned long size)
   17.51 -{
   17.52 -}
   17.53 -
   17.54 -#else
   17.55 -
   17.56 -#if defined(__i386__)
   17.57 -/*
   17.58 - * Does @address reside within a non-highmem page that is local to this virtual
   17.59 - * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
   17.60 - * See the comment that accompanies pte_pfn() in pgtable-2level.h to understand
   17.61 - * why this works.
   17.62 - */
   17.63 -static inline int is_local_lowmem(unsigned long address)
   17.64 -{
   17.65 -	extern unsigned long max_low_pfn;
   17.66 -	unsigned long mfn = address >> PAGE_SHIFT;
   17.67 -	unsigned long pfn = mfn_to_pfn(mfn);
   17.68 -	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
   17.69 -}
   17.70 -#elif defined(__x86_64__)
   17.71 -/*
   17.72 - * 
   17.73 - */
   17.74 -static inline int is_local_lowmem(unsigned long address)
   17.75 -{
   17.76 -        return 0;
   17.77 -}
   17.78 -#endif
   17.79 -
   17.80 -/*
   17.81 - * Generic mapping function (not visible outside):
   17.82 - */
   17.83 -
   17.84 -/*
   17.85 - * Remap an arbitrary physical address space into the kernel virtual
   17.86 - * address space. Needed when the kernel wants to access high addresses
   17.87 - * directly.
   17.88 - *
   17.89 - * NOTE! We need to allow non-page-aligned mappings too: we will obviously
   17.90 - * have to convert them into an offset in a page-aligned mapping, but the
   17.91 - * caller shouldn't need to know that small detail.
   17.92 - */
   17.93 -void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
   17.94 -{
   17.95 -	void __iomem * addr;
   17.96 -	struct vm_struct * area;
   17.97 -	unsigned long offset, last_addr;
   17.98 -	domid_t domid = DOMID_IO;
   17.99 -
  17.100 -	/* Don't allow wraparound or zero size */
  17.101 -	last_addr = phys_addr + size - 1;
  17.102 -	if (!size || last_addr < phys_addr)
  17.103 -		return NULL;
  17.104 -
  17.105 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
  17.106 -	/*
  17.107 -	 * Don't remap the low PCI/ISA area, it's always mapped..
  17.108 -	 */
  17.109 -	if (phys_addr >= 0x0 && last_addr < 0x100000)
  17.110 -		return isa_bus_to_virt(phys_addr);
  17.111 -#endif
  17.112 -
  17.113 -	/*
  17.114 -	 * Don't allow anybody to remap normal RAM that we're using..
  17.115 -	 */
  17.116 -	if (is_local_lowmem(phys_addr)) {
  17.117 -		char *t_addr, *t_end;
  17.118 - 		struct page *page;
  17.119 -
  17.120 -		t_addr = bus_to_virt(phys_addr);
  17.121 -		t_end = t_addr + (size - 1);
  17.122 -	   
  17.123 -		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
  17.124 -			if(!PageReserved(page))
  17.125 -				return NULL;
  17.126 -
  17.127 -		domid = DOMID_LOCAL;
  17.128 -	}
  17.129 -
  17.130 -	/*
  17.131 -	 * Mappings have to be page-aligned
  17.132 -	 */
  17.133 -	offset = phys_addr & ~PAGE_MASK;
  17.134 -	phys_addr &= PAGE_MASK;
  17.135 -	size = PAGE_ALIGN(last_addr+1) - phys_addr;
  17.136 -
  17.137 -	/*
  17.138 -	 * Ok, go for it..
  17.139 -	 */
  17.140 -	area = get_vm_area(size, VM_IOREMAP | (flags << 20));
  17.141 -	if (!area)
  17.142 -		return NULL;
  17.143 -	area->phys_addr = phys_addr;
  17.144 -	addr = (void __iomem *) area->addr;
  17.145 -	if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr,
  17.146 -				    size, __pgprot(_PAGE_PRESENT | _PAGE_RW |
  17.147 -						   _PAGE_DIRTY | _PAGE_ACCESSED
  17.148 -#if defined(__x86_64__)
  17.149 -                                                   | _PAGE_USER
  17.150 -#endif
  17.151 -						   | flags), domid)) {
  17.152 -		vunmap((void __force *) addr);
  17.153 -		return NULL;
  17.154 -	}
  17.155 -	return (void __iomem *) (offset + (char __iomem *)addr);
  17.156 -}
  17.157 -
  17.158 -
  17.159 -/**
  17.160 - * ioremap_nocache     -   map bus memory into CPU space
  17.161 - * @offset:    bus address of the memory
  17.162 - * @size:      size of the resource to map
  17.163 - *
  17.164 - * ioremap_nocache performs a platform specific sequence of operations to
  17.165 - * make bus memory CPU accessible via the readb/readw/readl/writeb/
  17.166 - * writew/writel functions and the other mmio helpers. The returned
  17.167 - * address is not guaranteed to be usable directly as a virtual
  17.168 - * address. 
  17.169 - *
  17.170 - * This version of ioremap ensures that the memory is marked uncachable
  17.171 - * on the CPU as well as honouring existing caching rules from things like
  17.172 - * the PCI bus. Note that there are other caches and buffers on many 
  17.173 - * busses. In particular driver authors should read up on PCI writes
  17.174 - *
  17.175 - * It's useful if some control registers are in such an area and
  17.176 - * write combining or read caching is not desirable:
  17.177 - * 
  17.178 - * Must be freed with iounmap.
  17.179 - */
  17.180 -
  17.181 -void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
  17.182 -{
  17.183 -	unsigned long last_addr;
  17.184 -	void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
  17.185 -	if (!p) 
  17.186 -		return p; 
  17.187 -
  17.188 -	/* Guaranteed to be > phys_addr, as per __ioremap() */
  17.189 -	last_addr = phys_addr + size - 1;
  17.190 -
  17.191 -	if (is_local_lowmem(last_addr)) { 
  17.192 -		struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
  17.193 -		unsigned long npages;
  17.194 -
  17.195 -		phys_addr &= PAGE_MASK;
  17.196 -
  17.197 -		/* This might overflow and become zero.. */
  17.198 -		last_addr = PAGE_ALIGN(last_addr);
  17.199 -
  17.200 -		/* .. but that's ok, because modulo-2**n arithmetic will make
  17.201 -	 	* the page-aligned "last - first" come out right.
  17.202 -	 	*/
  17.203 -		npages = (last_addr - phys_addr) >> PAGE_SHIFT;
  17.204 -
  17.205 -		if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
  17.206 -			iounmap(p); 
  17.207 -			p = NULL;
  17.208 -		}
  17.209 -		global_flush_tlb();
  17.210 -	}
  17.211 -
  17.212 -	return p;					
  17.213 -}
  17.214 -
  17.215 -void iounmap(volatile void __iomem *addr)
  17.216 -{
  17.217 -	struct vm_struct *p;
  17.218 -	if ((void __force *) addr <= high_memory) 
  17.219 -		return; 
  17.220 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
  17.221 -	if ((unsigned long) addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
  17.222 -		return;
  17.223 -#endif
  17.224 -	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
  17.225 -	if (!p) { 
  17.226 -		printk("__iounmap: bad address %p\n", addr);
  17.227 -		return;
  17.228 -	}
  17.229 -
  17.230 -	if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
  17.231 -		/* p->size includes the guard page, but cpa doesn't like that */
  17.232 -		change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
  17.233 -				 (p->size - PAGE_SIZE) >> PAGE_SHIFT,
  17.234 -				 PAGE_KERNEL); 				 
  17.235 -		global_flush_tlb();
  17.236 -	} 
  17.237 -	kfree(p); 
  17.238 -}
  17.239 -
  17.240 -#if defined(__i386__)
  17.241 -void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
  17.242 -{
  17.243 -	unsigned long offset, last_addr;
  17.244 -	unsigned int nrpages;
  17.245 -	enum fixed_addresses idx;
  17.246 -
  17.247 -	/* Don't allow wraparound or zero size */
  17.248 -	last_addr = phys_addr + size - 1;
  17.249 -	if (!size || last_addr < phys_addr)
  17.250 -		return NULL;
  17.251 -
  17.252 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
  17.253 -	/*
  17.254 -	 * Don't remap the low PCI/ISA area, it's always mapped..
  17.255 -	 */
  17.256 -	if (phys_addr >= 0x0 && last_addr < 0x100000)
  17.257 -		return isa_bus_to_virt(phys_addr);
  17.258 -#endif
  17.259 -
  17.260 -	/*
  17.261 -	 * Mappings have to be page-aligned
  17.262 -	 */
  17.263 -	offset = phys_addr & ~PAGE_MASK;
  17.264 -	phys_addr &= PAGE_MASK;
  17.265 -	size = PAGE_ALIGN(last_addr) - phys_addr;
  17.266 -
  17.267 -	/*
  17.268 -	 * Mappings have to fit in the FIX_BTMAP area.
  17.269 -	 */
  17.270 -	nrpages = size >> PAGE_SHIFT;
  17.271 -	if (nrpages > NR_FIX_BTMAPS)
  17.272 -		return NULL;
  17.273 -
  17.274 -	/*
  17.275 -	 * Ok, go for it..
  17.276 -	 */
  17.277 -	idx = FIX_BTMAP_BEGIN;
  17.278 -	while (nrpages > 0) {
  17.279 -		set_fixmap(idx, phys_addr);
  17.280 -		phys_addr += PAGE_SIZE;
  17.281 -		--idx;
  17.282 -		--nrpages;
  17.283 -	}
  17.284 -	return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
  17.285 -}
  17.286 -
  17.287 -void __init bt_iounmap(void *addr, unsigned long size)
  17.288 -{
  17.289 -	unsigned long virt_addr;
  17.290 -	unsigned long offset;
  17.291 -	unsigned int nrpages;
  17.292 -	enum fixed_addresses idx;
  17.293 -
  17.294 -	virt_addr = (unsigned long)addr;
  17.295 -	if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
  17.296 -		return;
  17.297 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
  17.298 -	if (virt_addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
  17.299 -		return;
  17.300 -#endif
  17.301 -	offset = virt_addr & ~PAGE_MASK;
  17.302 -	nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
  17.303 -
  17.304 -	idx = FIX_BTMAP_BEGIN;
  17.305 -	while (nrpages > 0) {
  17.306 -		clear_fixmap(idx);
  17.307 -		--idx;
  17.308 -		--nrpages;
  17.309 -	}
  17.310 -}
  17.311 -#endif /* defined(__i386__) */
  17.312 -
  17.313 -#endif /* CONFIG_XEN_PHYSDEV_ACCESS */
  17.314 -
  17.315 -/* These hacky macros avoid phys->machine translations. */
  17.316 -#define __direct_pte(x) ((pte_t) { (x) } )
  17.317 -#define __direct_mk_pte(page_nr,pgprot) \
  17.318 -  __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
  17.319 -#define direct_mk_pte_phys(physpage, pgprot) \
  17.320 -  __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
  17.321 -
  17.322 -static inline void direct_remap_area_pte(pte_t *pte, 
  17.323 -					 unsigned long address, 
  17.324 -					 unsigned long size,
  17.325 -					 mmu_update_t **v)
  17.326 -{
  17.327 -	unsigned long end;
  17.328 -
  17.329 -	address &= ~PMD_MASK;
  17.330 -	end = address + size;
  17.331 -	if (end > PMD_SIZE)
  17.332 -		end = PMD_SIZE;
  17.333 -	if (address >= end)
  17.334 -		BUG();
  17.335 -
  17.336 -	do {
  17.337 -		(*v)->ptr = virt_to_machine(pte);
  17.338 -		(*v)++;
  17.339 -		address += PAGE_SIZE;
  17.340 -		pte++;
  17.341 -	} while (address && (address < end));
  17.342 -}
  17.343 -
  17.344 -static inline int direct_remap_area_pmd(struct mm_struct *mm,
  17.345 -					pmd_t *pmd, 
  17.346 -					unsigned long address, 
  17.347 -					unsigned long size,
  17.348 -					mmu_update_t **v)
  17.349 -{
  17.350 -	unsigned long end;
  17.351 -
  17.352 -	address &= ~PGDIR_MASK;
  17.353 -	end = address + size;
  17.354 -	if (end > PGDIR_SIZE)
  17.355 -		end = PGDIR_SIZE;
  17.356 -	if (address >= end)
  17.357 -		BUG();
  17.358 -	do {
  17.359 -		pte_t *pte = (mm == &init_mm) ? 
  17.360 -			pte_alloc_kernel(mm, pmd, address) :
  17.361 -			pte_alloc_map(mm, pmd, address);
  17.362 -		if (!pte)
  17.363 -			return -ENOMEM;
  17.364 -		direct_remap_area_pte(pte, address, end - address, v);
  17.365 -		pte_unmap(pte);
  17.366 -		address = (address + PMD_SIZE) & PMD_MASK;
  17.367 -		pmd++;
  17.368 -	} while (address && (address < end));
  17.369 -	return 0;
  17.370 -}
  17.371 - 
  17.372 -int __direct_remap_area_pages(struct mm_struct *mm,
  17.373 -			      unsigned long address, 
  17.374 -			      unsigned long size, 
  17.375 -			      mmu_update_t *v)
  17.376 -{
  17.377 -	pgd_t * dir;
  17.378 -	unsigned long end = address + size;
  17.379 -	int error;
  17.380 -
  17.381 -#if defined(__i386__)
  17.382 -	dir = pgd_offset(mm, address);
  17.383 -#elif defined (__x86_64)
  17.384 -        dir = (mm == &init_mm) ?
  17.385 -		pgd_offset_k(address):
  17.386 -		pgd_offset(mm, address);
  17.387 -#endif
  17.388 -	if (address >= end)
  17.389 -		BUG();
  17.390 -	spin_lock(&mm->page_table_lock);
  17.391 -	do {
  17.392 -		pud_t *pud;
  17.393 -		pmd_t *pmd;
  17.394 -
  17.395 -		error = -ENOMEM;
  17.396 -		pud = pud_alloc(mm, dir, address);
  17.397 -		if (!pud)
  17.398 -			break;
  17.399 -		pmd = pmd_alloc(mm, pud, address);
  17.400 -		if (!pmd)
  17.401 -			break;
  17.402 -		error = 0;
  17.403 -		direct_remap_area_pmd(mm, pmd, address, end - address, &v);
  17.404 -		address = (address + PGDIR_SIZE) & PGDIR_MASK;
  17.405 -		dir++;
  17.406 -
  17.407 -	} while (address && (address < end));
  17.408 -	spin_unlock(&mm->page_table_lock);
  17.409 -	return error;
  17.410 -}
  17.411 -
  17.412 -
  17.413 -int direct_remap_area_pages(struct mm_struct *mm,
  17.414 -			    unsigned long address, 
  17.415 -			    unsigned long machine_addr,
  17.416 -			    unsigned long size, 
  17.417 -			    pgprot_t prot,
  17.418 -			    domid_t  domid)
  17.419 -{
  17.420 -	int i;
  17.421 -	unsigned long start_address;
  17.422 -#define MAX_DIRECTMAP_MMU_QUEUE 130
  17.423 -	mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u;
  17.424 -
  17.425 -	start_address = address;
  17.426 -
  17.427 -	flush_cache_all();
  17.428 -
  17.429 -	for (i = 0; i < size; i += PAGE_SIZE) {
  17.430 -		if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
  17.431 -			/* Fill in the PTE pointers. */
  17.432 -			__direct_remap_area_pages(mm,
  17.433 -						  start_address, 
  17.434 -						  address-start_address, 
  17.435 -						  u);
  17.436 - 
  17.437 -			if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
  17.438 -				return -EFAULT;
  17.439 -			v = u;
  17.440 -			start_address = address;
  17.441 -		}
  17.442 -
  17.443 -		/*
  17.444 -		 * Fill in the machine address: PTE ptr is done later by
  17.445 -		 * __direct_remap_area_pages(). 
  17.446 -		 */
  17.447 -		v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
  17.448 -
  17.449 -		machine_addr += PAGE_SIZE;
  17.450 -		address += PAGE_SIZE; 
  17.451 -		v++;
  17.452 -	}
  17.453 -
  17.454 -	if (v != u) {
  17.455 -		/* get the ptep's filled in */
  17.456 -		__direct_remap_area_pages(mm,
  17.457 -					  start_address, 
  17.458 -					  address-start_address, 
  17.459 -					  u);
  17.460 -		if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
  17.461 -			return -EFAULT;
  17.462 -	}
  17.463 -
  17.464 -	flush_tlb_all();
  17.465 -
  17.466 -	return 0;
  17.467 -}
  17.468 -
  17.469 -EXPORT_SYMBOL(direct_remap_area_pages);
  17.470 -
  17.471 -int create_lookup_pte_addr(struct mm_struct *mm, 
  17.472 -                           unsigned long address,
  17.473 -                           unsigned long *ptep)
  17.474 -{
  17.475 -    int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data) 
  17.476 -    {
  17.477 -        unsigned long *ptep = (unsigned long *)data;
  17.478 -        if (ptep) *ptep = (pfn_to_mfn(page_to_pfn(pte_page)) << PAGE_SHIFT)
  17.479 -                       | ((unsigned long)pte & ~PAGE_MASK);
  17.480 -        return 0;
  17.481 -    }
  17.482 -
  17.483 -    return generic_page_range(mm, address, PAGE_SIZE, f, ptep);
  17.484 -}
  17.485 -
  17.486 -EXPORT_SYMBOL(create_lookup_pte_addr);
  17.487 -
  17.488 -int touch_pte_range(struct mm_struct *mm,
  17.489 -                    unsigned long address,
  17.490 -                    unsigned long size)
  17.491 -{
  17.492 -    int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data) 
  17.493 -    {
  17.494 -        return 0;
  17.495 -    }
  17.496 -
  17.497 -    return generic_page_range(mm, address, size, f, NULL);
  17.498 -}                 
  17.499 -
  17.500 -EXPORT_SYMBOL(touch_pte_range);
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Mon Aug 22 11:37:48 2005 -0700
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Tue Aug 23 12:03:21 2005 -0700
    18.3 @@ -434,20 +434,20 @@ void balloon_update_driver_allowance(lon
    18.4  	balloon_unlock(flags);
    18.5  }
    18.6  
    18.7 +static int dealloc_pte_fn(
    18.8 +	pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
    18.9 +{
   18.10 +	unsigned long mfn = pte_mfn(*pte);
   18.11 +	set_pte(pte, __pte_ma(0));
   18.12 +	phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] =
   18.13 +		INVALID_P2M_ENTRY;
   18.14 +	BUG_ON(HYPERVISOR_dom_mem_op(
   18.15 +		MEMOP_decrease_reservation, &mfn, 1, 0) != 1);
   18.16 +	return 0;
   18.17 +}
   18.18 +
   18.19  struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
   18.20  {
   18.21 -	int f(pte_t *pte, struct page *pte_page,
   18.22 -	      unsigned long addr, void *data)
   18.23 -	{
   18.24 -		unsigned long mfn = pte_mfn(*pte);
   18.25 -		set_pte(pte, __pte_ma(0));
   18.26 -		phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] =
   18.27 -			INVALID_P2M_ENTRY;
   18.28 -		BUG_ON(HYPERVISOR_dom_mem_op(
   18.29 -			MEMOP_decrease_reservation, &mfn, 1, 0) != 1);
   18.30 -		return 0;
   18.31 -        }
   18.32 -
   18.33  	unsigned long vstart, flags;
   18.34  	unsigned int  order = get_order(nr_pages * PAGE_SIZE);
   18.35  
   18.36 @@ -459,7 +459,7 @@ struct page *balloon_alloc_empty_page_ra
   18.37  
   18.38  	balloon_lock(flags);
   18.39  	BUG_ON(generic_page_range(
   18.40 -		&init_mm, vstart, PAGE_SIZE << order, f, NULL) != 0);
   18.41 +		&init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL));
   18.42  	current_pages -= 1UL << order;
   18.43  	balloon_unlock(flags);
   18.44  
    19.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Mon Aug 22 11:37:48 2005 -0700
    19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Tue Aug 23 12:03:21 2005 -0700
    19.3 @@ -11,6 +11,8 @@
    19.4   * Copyright (c) 2005, Christopher Clark
    19.5   */
    19.6  
    19.7 +#include <linux/spinlock.h>
    19.8 +#include <asm-xen/balloon.h>
    19.9  #include "common.h"
   19.10  
   19.11  /*
   19.12 @@ -63,9 +65,6 @@ typedef unsigned int PEND_RING_IDX;
   19.13  static PEND_RING_IDX pending_prod, pending_cons;
   19.14  #define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
   19.15  
   19.16 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   19.17 -static kmem_cache_t *buffer_head_cachep;
   19.18 -#else
   19.19  static request_queue_t *plugged_queue;
   19.20  static inline void flush_plugged_queue(void)
   19.21  {
   19.22 @@ -78,7 +77,6 @@ static inline void flush_plugged_queue(v
   19.23          plugged_queue = NULL;
   19.24      }
   19.25  }
   19.26 -#endif
   19.27  
   19.28  /* When using grant tables to map a frame for device access then the
   19.29   * handle returned must be used to unmap the frame. This is needed to
   19.30 @@ -182,11 +180,7 @@ static int blkio_schedule(void *arg)
   19.31      blkif_t          *blkif;
   19.32      struct list_head *ent;
   19.33  
   19.34 -    daemonize(
   19.35 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   19.36 -        "xenblkd"
   19.37 -#endif
   19.38 -        );
   19.39 +    daemonize("xenblkd");
   19.40  
   19.41      for ( ; ; )
   19.42      {
   19.43 @@ -213,11 +207,7 @@ static int blkio_schedule(void *arg)
   19.44          }
   19.45  
   19.46          /* Push the batch through to disc. */
   19.47 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   19.48 -        run_task_queue(&tq_disk);
   19.49 -#else
   19.50          flush_plugged_queue();
   19.51 -#endif
   19.52      }
   19.53  }
   19.54  
   19.55 @@ -266,13 +256,6 @@ static void __end_block_io_op(pending_re
   19.56      }
   19.57  }
   19.58  
   19.59 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   19.60 -static void end_block_io_op(struct buffer_head *bh, int uptodate)
   19.61 -{
   19.62 -    __end_block_io_op(bh->b_private, uptodate);
   19.63 -    kmem_cache_free(buffer_head_cachep, bh);
   19.64 -}
   19.65 -#else
   19.66  static int end_block_io_op(struct bio *bio, unsigned int done, int error)
   19.67  {
   19.68      if ( bio->bi_size != 0 )
   19.69 @@ -281,7 +264,6 @@ static int end_block_io_op(struct bio *b
   19.70      bio_put(bio);
   19.71      return error;
   19.72  }
   19.73 -#endif
   19.74  
   19.75  
   19.76  /******************************************************************************
   19.77 @@ -355,13 +337,9 @@ static void dispatch_rw_block_io(blkif_t
   19.78          unsigned long buf; unsigned int nsec;
   19.79      } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   19.80      unsigned int nseg;
   19.81 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   19.82 -    struct buffer_head *bh;
   19.83 -#else
   19.84      struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   19.85      int nbio = 0;
   19.86      request_queue_t *q;
   19.87 -#endif
   19.88  
   19.89      /* Check that number of segments is sane. */
   19.90      nseg = req->nr_segments;
   19.91 @@ -433,49 +411,6 @@ static void dispatch_rw_block_io(blkif_t
   19.92      pending_req->status    = BLKIF_RSP_OKAY;
   19.93      pending_req->nr_pages  = nseg;
   19.94  
   19.95 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   19.96 -
   19.97 -    atomic_set(&pending_req->pendcnt, nseg);
   19.98 -    pending_cons++;
   19.99 -    blkif_get(blkif);
  19.100 -
  19.101 -    for ( i = 0; i < nseg; i++ )
  19.102 -    {
  19.103 -        bh = kmem_cache_alloc(buffer_head_cachep, GFP_KERNEL);
  19.104 -        if ( unlikely(bh == NULL) )
  19.105 -        {
  19.106 -            __end_block_io_op(pending_req, 0);
  19.107 -            continue;
  19.108 -        }
  19.109 -
  19.110 -        memset(bh, 0, sizeof (struct buffer_head));
  19.111 -
  19.112 -        init_waitqueue_head(&bh->b_wait);
  19.113 -        bh->b_size          = seg[i].nsec << 9;
  19.114 -        bh->b_dev           = preq.dev;
  19.115 -        bh->b_rdev          = preq.dev;
  19.116 -        bh->b_rsector       = (unsigned long)preq.sector_number;
  19.117 -        bh->b_data          = (char *)MMAP_VADDR(pending_idx, i) +
  19.118 -            (seg[i].buf & ~PAGE_MASK);
  19.119 -        bh->b_page          = virt_to_page(MMAP_VADDR(pending_idx, i));
  19.120 -        bh->b_end_io        = end_block_io_op;
  19.121 -        bh->b_private       = pending_req;
  19.122 -
  19.123 -        bh->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | 
  19.124 -            (1 << BH_Req) | (1 << BH_Launder);
  19.125 -        if ( operation == WRITE )
  19.126 -            bh->b_state |= (1 << BH_JBD) | (1 << BH_Req) | (1 << BH_Uptodate);
  19.127 -
  19.128 -        atomic_set(&bh->b_count, 1);
  19.129 -
  19.130 -        /* Dispatch a single request. We'll flush it to disc later. */
  19.131 -        generic_make_request(operation, bh);
  19.132 -
  19.133 -        preq.sector_number += seg[i].nsec;
  19.134 -    }
  19.135 -
  19.136 -#else
  19.137 -
  19.138      for ( i = 0; i < nseg; i++ )
  19.139      {
  19.140          if ( ((int)preq.sector_number|(int)seg[i].nsec) &
  19.141 @@ -524,8 +459,6 @@ static void dispatch_rw_block_io(blkif_t
  19.142      for ( i = 0; i < nbio; i++ )
  19.143          submit_bio(operation, biolist[i]);
  19.144  
  19.145 -#endif
  19.146 -
  19.147      return;
  19.148  
  19.149   bad_descriptor:
  19.150 @@ -593,12 +526,6 @@ static int __init blkif_init(void)
  19.151      if ( kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
  19.152          BUG();
  19.153  
  19.154 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  19.155 -    buffer_head_cachep = kmem_cache_create(
  19.156 -        "buffer_head_cache", sizeof(struct buffer_head),
  19.157 -        0, SLAB_HWCACHE_ALIGN, NULL, NULL);
  19.158 -#endif
  19.159 -
  19.160      blkif_xenbus_init();
  19.161  
  19.162      memset( pending_grant_handles,  BLKBACK_INVALID_HANDLE, MMAP_PAGES );
    20.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Mon Aug 22 11:37:48 2005 -0700
    20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Aug 23 12:03:21 2005 -0700
    20.3 @@ -5,7 +5,6 @@
    20.4  #include <linux/config.h>
    20.5  #include <linux/version.h>
    20.6  #include <linux/module.h>
    20.7 -#include <linux/rbtree.h>
    20.8  #include <linux/interrupt.h>
    20.9  #include <linux/slab.h>
   20.10  #include <linux/blkdev.h>
   20.11 @@ -30,12 +29,13 @@
   20.12  #define DPRINTK(_f, _a...) ((void)0)
   20.13  #endif
   20.14  
   20.15 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   20.16 -typedef struct rb_root rb_root_t;
   20.17 -typedef struct rb_node rb_node_t;
   20.18 -#else
   20.19 -struct block_device;
   20.20 -#endif
   20.21 +struct vbd {
   20.22 +    blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
   20.23 +    unsigned char  readonly;    /* Non-zero -> read-only */
   20.24 +    unsigned char  type;        /* VDISK_xxx */
   20.25 +    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
   20.26 +    struct block_device *bdev;
   20.27 +}; 
   20.28  
   20.29  typedef struct blkif_st {
   20.30      /* Unique identifier for this interface. */
   20.31 @@ -48,25 +48,18 @@ typedef struct blkif_st {
   20.32      /* Comms information. */
   20.33      blkif_back_ring_t blk_ring;
   20.34      /* VBDs attached to this interface. */
   20.35 -    rb_root_t         vbd_rb;        /* Mapping from 16-bit vdevices to VBDs.*/
   20.36 -    spinlock_t        vbd_lock;      /* Protects VBD mapping. */
   20.37 +    struct vbd        vbd;
   20.38      /* Private fields. */
   20.39      enum { DISCONNECTED, CONNECTED } status;
   20.40 -    /*
   20.41 -     * DISCONNECT response is deferred until pending requests are ack'ed.
   20.42 -     * We therefore need to store the id from the original request.
   20.43 -     */
   20.44 -    u8               disconnect_rspid;
   20.45  #ifdef CONFIG_XEN_BLKDEV_TAP_BE
   20.46      /* Is this a blktap frontend */
   20.47      unsigned int     is_blktap;
   20.48  #endif
   20.49 -    struct blkif_st *hash_next;
   20.50      struct list_head blkdev_list;
   20.51      spinlock_t       blk_ring_lock;
   20.52      atomic_t         refcnt;
   20.53  
   20.54 -    struct work_struct work;
   20.55 +    struct work_struct free_work;
   20.56      u16 shmem_handle;
   20.57      unsigned long shmem_vaddr;
   20.58      grant_ref_t shmem_ref;
   20.59 @@ -77,30 +70,25 @@ void blkif_destroy(blkif_be_destroy_t *d
   20.60  void blkif_connect(blkif_be_connect_t *connect);
   20.61  int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
   20.62  void blkif_disconnect_complete(blkif_t *blkif);
   20.63 -blkif_t *blkif_find(domid_t domid);
   20.64 -void free_blkif(blkif_t *blkif);
   20.65 +blkif_t *alloc_blkif(domid_t domid);
   20.66 +void free_blkif_callback(blkif_t *blkif);
   20.67  int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
   20.68  
   20.69  #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
   20.70  #define blkif_put(_b)                             \
   20.71      do {                                          \
   20.72          if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   20.73 -            free_blkif(_b);			  \
   20.74 +            free_blkif_callback(_b);		  \
   20.75      } while (0)
   20.76  
   20.77 -struct vbd;
   20.78 -void vbd_free(blkif_t *blkif, struct vbd *vbd);
   20.79 -
   20.80 -/* Creates inactive vbd. */
   20.81 -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly);
   20.82 -int vbd_is_active(struct vbd *vbd);
   20.83 -void vbd_activate(blkif_t *blkif, struct vbd *vbd);
   20.84 +/* Create a vbd. */
   20.85 +int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice,
   20.86 +	       int readonly);
   20.87 +void vbd_free(struct vbd *vbd);
   20.88  
   20.89  unsigned long vbd_size(struct vbd *vbd);
   20.90  unsigned int vbd_info(struct vbd *vbd);
   20.91  unsigned long vbd_secsize(struct vbd *vbd);
   20.92 -void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
   20.93 -void destroy_all_vbds(blkif_t *blkif);
   20.94  
   20.95  struct phys_req {
   20.96      unsigned short       dev;
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Mon Aug 22 11:37:48 2005 -0700
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Tue Aug 23 12:03:21 2005 -0700
    21.3 @@ -9,27 +9,11 @@
    21.4  #include "common.h"
    21.5  #include <asm-xen/evtchn.h>
    21.6  
    21.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    21.8 -#define VMALLOC_VMADDR(x) ((unsigned long)(x))
    21.9 -#endif
   21.10 -
   21.11 -#define BLKIF_HASHSZ 1024
   21.12 -#define BLKIF_HASH(_d) (((int)(_d))&(BLKIF_HASHSZ-1))
   21.13 -
   21.14  static kmem_cache_t *blkif_cachep;
   21.15 -static blkif_t      *blkif_hash[BLKIF_HASHSZ];
   21.16  
   21.17 -blkif_t *blkif_find(domid_t domid)
   21.18 +blkif_t *alloc_blkif(domid_t domid)
   21.19  {
   21.20 -    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid)];
   21.21 -
   21.22 -    while (blkif) {
   21.23 -	if (blkif->domid == domid) {
   21.24 -	    blkif_get(blkif);
   21.25 -	    return blkif;
   21.26 -	}
   21.27 -        blkif = blkif->hash_next;
   21.28 -    }
   21.29 +    blkif_t *blkif;
   21.30  
   21.31      blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
   21.32      if (!blkif)
   21.33 @@ -38,12 +22,9 @@ blkif_t *blkif_find(domid_t domid)
   21.34      memset(blkif, 0, sizeof(*blkif));
   21.35      blkif->domid = domid;
   21.36      blkif->status = DISCONNECTED;
   21.37 -    spin_lock_init(&blkif->vbd_lock);
   21.38      spin_lock_init(&blkif->blk_ring_lock);
   21.39      atomic_set(&blkif->refcnt, 1);
   21.40  
   21.41 -    blkif->hash_next = blkif_hash[BLKIF_HASH(domid)];
   21.42 -    blkif_hash[BLKIF_HASH(domid)] = blkif;
   21.43      return blkif;
   21.44  }
   21.45  
   21.46 @@ -55,7 +36,7 @@ static int map_frontend_page(blkif_t *bl
   21.47      op.flags = GNTMAP_host_map;
   21.48      op.ref = shared_page;
   21.49      op.dom = blkif->domid;
   21.50 -       
   21.51 +
   21.52      BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   21.53  
   21.54      if (op.handle < 0) {
   21.55 @@ -91,7 +72,7 @@ int blkif_map(blkif_t *blkif, unsigned l
   21.56      if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   21.57  	return -ENOMEM;
   21.58  
   21.59 -    err = map_frontend_page(blkif, VMALLOC_VMADDR(vma->addr), shared_page);
   21.60 +    err = map_frontend_page(blkif, (unsigned long)vma->addr, shared_page);
   21.61      if (err) {
   21.62          vfree(vma->addr);
   21.63  	return err;
   21.64 @@ -123,10 +104,10 @@ int blkif_map(blkif_t *blkif, unsigned l
   21.65      return 0;
   21.66  }
   21.67  
   21.68 -void free_blkif(blkif_t *blkif)
   21.69 +static void free_blkif(void *arg)
   21.70  {
   21.71 -    blkif_t     **pblkif;
   21.72      evtchn_op_t op = { .cmd = EVTCHNOP_close };
   21.73 +    blkif_t *blkif = (blkif_t *)arg;
   21.74  
   21.75      op.u.close.port = blkif->evtchn;
   21.76      op.u.close.dom = DOMID_SELF;
   21.77 @@ -135,6 +116,8 @@ void free_blkif(blkif_t *blkif)
   21.78      op.u.close.dom = blkif->domid;
   21.79      HYPERVISOR_event_channel_op(&op);
   21.80  
   21.81 +    vbd_free(&blkif->vbd);
   21.82 +
   21.83      if (blkif->evtchn)
   21.84          unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
   21.85  
   21.86 @@ -143,20 +126,17 @@ void free_blkif(blkif_t *blkif)
   21.87  	vfree(blkif->blk_ring.sring);
   21.88      }
   21.89  
   21.90 -    pblkif = &blkif_hash[BLKIF_HASH(blkif->domid)];
   21.91 -    while ( *pblkif != blkif )
   21.92 -    {
   21.93 -	BUG_ON(!*pblkif);
   21.94 -        pblkif = &(*pblkif)->hash_next;
   21.95 -    }
   21.96 -    *pblkif = blkif->hash_next;
   21.97 -    destroy_all_vbds(blkif);
   21.98      kmem_cache_free(blkif_cachep, blkif);
   21.99  }
  21.100  
  21.101 +void free_blkif_callback(blkif_t *blkif)
  21.102 +{
  21.103 +    INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
  21.104 +    schedule_work(&blkif->free_work);
  21.105 +}
  21.106 +
  21.107  void __init blkif_interface_init(void)
  21.108  {
  21.109      blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
  21.110                                       0, 0, NULL, NULL);
  21.111 -    memset(blkif_hash, 0, sizeof(blkif_hash));
  21.112  }
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Mon Aug 22 11:37:48 2005 -0700
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 23 12:03:21 2005 -0700
    22.3 @@ -3,38 +3,19 @@
    22.4   * 
    22.5   * Routines for managing virtual block devices (VBDs).
    22.6   * 
    22.7 - * NOTE: vbd_lock protects updates to the rb_tree against concurrent lookups 
    22.8 - * in vbd_translate.  All other lookups are implicitly protected because the 
    22.9 - * only caller (the control message dispatch routine) serializes the calls.
   22.10 - * 
   22.11   * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
   22.12   */
   22.13  
   22.14  #include "common.h"
   22.15  #include <asm-xen/xenbus.h>
   22.16  
   22.17 -struct vbd { 
   22.18 -    blkif_vdev_t   handle;     /* what the domain refers to this vbd as */
   22.19 -    unsigned char  readonly;    /* Non-zero -> read-only */
   22.20 -    unsigned char  type;        /* VDISK_xxx */
   22.21 -    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
   22.22 -    struct block_device *bdev;
   22.23 -
   22.24 -    int active;
   22.25 -    rb_node_t      rb;          /* for linking into R-B tree lookup struct */
   22.26 -}; 
   22.27 -
   22.28 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   22.29  static inline dev_t vbd_map_devnum(blkif_pdev_t cookie)
   22.30 -{ return MKDEV(cookie>>8, cookie&0xff); }
   22.31 +{
   22.32 +    return MKDEV(BLKIF_MAJOR(cookie), BLKIF_MINOR(cookie));
   22.33 +}
   22.34  #define vbd_sz(_v)   ((_v)->bdev->bd_part ? \
   22.35      (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
   22.36  #define bdev_put(_b) blkdev_put(_b)
   22.37 -#else
   22.38 -#define vbd_sz(_v)   (blk_size[MAJOR((_v)->pdevice)][MINOR((_v)->pdevice)]*2)
   22.39 -#define bdev_put(_b) ((void)0)
   22.40 -#define bdev_hardsect_size(_b) 512
   22.41 -#endif
   22.42  
   22.43  unsigned long vbd_size(struct vbd *vbd)
   22.44  {
   22.45 @@ -51,45 +32,32 @@ unsigned long vbd_secsize(struct vbd *vb
   22.46  	return bdev_hardsect_size(vbd->bdev);
   22.47  }
   22.48  
   22.49 -int vbd_is_active(struct vbd *vbd)
   22.50 -{
   22.51 -	return vbd->active;
   22.52 -}
   22.53 -
   22.54 -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
   22.55 -		       blkif_pdev_t pdevice, int readonly)
   22.56 +int vbd_create(blkif_t *blkif, blkif_vdev_t handle,
   22.57 +	       blkif_pdev_t pdevice, int readonly)
   22.58  {
   22.59 -    struct vbd  *vbd; 
   22.60 +    struct vbd *vbd;
   22.61  
   22.62 -    if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
   22.63 -    {
   22.64 -        DPRINTK("vbd_create: out of memory\n");
   22.65 -	return ERR_PTR(-ENOMEM);
   22.66 -    }
   22.67 -
   22.68 +    vbd = &blkif->vbd;
   22.69      vbd->handle   = handle; 
   22.70      vbd->readonly = readonly;
   22.71      vbd->type     = 0;
   22.72 -    vbd->active   = 0;
   22.73  
   22.74      vbd->pdevice  = pdevice;
   22.75  
   22.76 -    /* FIXME: Who frees vbd on failure? --RR */
   22.77 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   22.78      vbd->bdev = open_by_devnum(
   22.79          vbd_map_devnum(vbd->pdevice),
   22.80          vbd->readonly ? FMODE_READ : FMODE_WRITE);
   22.81      if ( IS_ERR(vbd->bdev) )
   22.82      {
   22.83          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   22.84 -        return ERR_PTR(-ENOENT);
   22.85 +        return -ENOENT;
   22.86      }
   22.87  
   22.88      if ( (vbd->bdev->bd_disk == NULL) )
   22.89      {
   22.90          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   22.91 -        bdev_put(vbd->bdev);
   22.92 -        return ERR_PTR(-ENOENT);
   22.93 +	vbd_free(vbd);
   22.94 +        return -ENOENT;
   22.95      }
   22.96  
   22.97      if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
   22.98 @@ -97,121 +65,27 @@ struct vbd *vbd_create(blkif_t *blkif, b
   22.99      if ( vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE )
  22.100          vbd->type |= VDISK_REMOVABLE;
  22.101  
  22.102 -#else
  22.103 -    if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
  22.104 -    {
  22.105 -        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
  22.106 -        return ERR_PTR(-ENOENT);
  22.107 -    }
  22.108 -#endif
  22.109 -
  22.110      DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
  22.111              handle, blkif->domid);
  22.112 -    return vbd;
  22.113 +    return 0;
  22.114  }
  22.115  
  22.116 -void vbd_activate(blkif_t *blkif, struct vbd *vbd)
  22.117 +void vbd_free(struct vbd *vbd)
  22.118  {
  22.119 -    rb_node_t  **rb_p, *rb_parent = NULL;
  22.120 -    struct vbd *i;
  22.121 -    BUG_ON(vbd_is_active(vbd));
  22.122 -
  22.123 -    /* Find where to put it. */
  22.124 -    rb_p = &blkif->vbd_rb.rb_node;
  22.125 -    while ( *rb_p != NULL )
  22.126 -    {
  22.127 -        rb_parent = *rb_p;
  22.128 -        i = rb_entry(rb_parent, struct vbd, rb);
  22.129 -        if ( vbd->handle < i->handle )
  22.130 -        {
  22.131 -            rb_p = &rb_parent->rb_left;
  22.132 -        }
  22.133 -        else if ( vbd->handle > i->handle )
  22.134 -        {
  22.135 -            rb_p = &rb_parent->rb_right;
  22.136 -        }
  22.137 -        else
  22.138 -        {
  22.139 -	    /* We never create two of same vbd, so not possible. */
  22.140 -	    BUG();
  22.141 -        }
  22.142 -    }
  22.143 -
  22.144 -    /* Now we're active. */
  22.145 -    vbd->active = 1;
  22.146 -    blkif_get(blkif);
  22.147 -
  22.148 -    spin_lock(&blkif->vbd_lock);
  22.149 -    rb_link_node(&vbd->rb, rb_parent, rb_p);
  22.150 -    rb_insert_color(&vbd->rb, &blkif->vbd_rb);
  22.151 -    spin_unlock(&blkif->vbd_lock);
  22.152 -}
  22.153 -
  22.154 -void vbd_free(blkif_t *blkif, struct vbd *vbd)
  22.155 -{
  22.156 -    if (vbd_is_active(vbd)) {
  22.157 -	spin_lock(&blkif->vbd_lock);
  22.158 -	rb_erase(&vbd->rb, &blkif->vbd_rb);
  22.159 -	spin_unlock(&blkif->vbd_lock);
  22.160 -	blkif_put(blkif);
  22.161 -    }
  22.162 -    bdev_put(vbd->bdev);
  22.163 -    kfree(vbd);
  22.164 -}
  22.165 -
  22.166 -void destroy_all_vbds(blkif_t *blkif)
  22.167 -{
  22.168 -    struct vbd *vbd;
  22.169 -    rb_node_t  *rb;
  22.170 -
  22.171 -    spin_lock(&blkif->vbd_lock);
  22.172 -
  22.173 -    while ( (rb = blkif->vbd_rb.rb_node) != NULL )
  22.174 -    {
  22.175 -        vbd = rb_entry(rb, struct vbd, rb);
  22.176 -        rb_erase(rb, &blkif->vbd_rb);
  22.177 -        spin_unlock(&blkif->vbd_lock);
  22.178 -        bdev_put(vbd->bdev);
  22.179 -        kfree(vbd);
  22.180 -        spin_lock(&blkif->vbd_lock);
  22.181 -        blkif_put(blkif);
  22.182 -    }
  22.183 -
  22.184 -    spin_unlock(&blkif->vbd_lock);
  22.185 +    if (vbd->bdev)
  22.186 +	bdev_put(vbd->bdev);
  22.187 +    vbd->bdev = NULL;
  22.188  }
  22.189  
  22.190  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
  22.191  {
  22.192 -    struct vbd *vbd;
  22.193 -    rb_node_t  *rb;
  22.194 -    int         rc = -EACCES;
  22.195 -
  22.196 -    /* Take the vbd_lock because another thread could be updating the tree. */
  22.197 -    spin_lock(&blkif->vbd_lock);
  22.198 +    struct vbd *vbd = &blkif->vbd;
  22.199 +    int rc = -EACCES;
  22.200  
  22.201 -    rb = blkif->vbd_rb.rb_node;
  22.202 -    while ( rb != NULL )
  22.203 -    {
  22.204 -        vbd = rb_entry(rb, struct vbd, rb);
  22.205 -        if ( req->dev < vbd->handle )
  22.206 -            rb = rb->rb_left;
  22.207 -        else if ( req->dev > vbd->handle )
  22.208 -            rb = rb->rb_right;
  22.209 -        else
  22.210 -            goto found;
  22.211 -    }
  22.212 -
  22.213 -    DPRINTK("vbd_translate; domain %u attempted to access "
  22.214 -            "non-existent VBD.\n", blkif->domid);
  22.215 -    rc = -ENODEV;
  22.216 -    goto out;
  22.217 -
  22.218 - found:
  22.219 -
  22.220 -    if ( (operation == WRITE) && vbd->readonly )
  22.221 +    if ((operation == WRITE) && vbd->readonly)
  22.222          goto out;
  22.223  
  22.224 -    if ( unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)) )
  22.225 +    if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
  22.226          goto out;
  22.227  
  22.228      req->dev  = vbd->pdevice;
  22.229 @@ -219,6 +93,5 @@ int vbd_translate(struct phys_req *req, 
  22.230      rc = 0;
  22.231  
  22.232   out:
  22.233 -    spin_unlock(&blkif->vbd_lock);
  22.234      return rc;
  22.235  }
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Mon Aug 22 11:37:48 2005 -0700
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Aug 23 12:03:21 2005 -0700
    23.3 @@ -26,7 +26,6 @@ struct backend_info
    23.4  
    23.5  	/* our communications channel */
    23.6  	blkif_t *blkif;
    23.7 -	struct vbd *vbd;
    23.8  
    23.9  	long int frontend_id;
   23.10  	long int pdev;
   23.11 @@ -47,8 +46,6 @@ static int blkback_remove(struct xenbus_
   23.12  	if (be->watch.node)
   23.13  		unregister_xenbus_watch(&be->watch);
   23.14  	unregister_xenbus_watch(&be->backend_watch);
   23.15 -	if (be->vbd)
   23.16 -		vbd_free(be->blkif, be->vbd);
   23.17  	if (be->blkif)
   23.18  		blkif_put(be->blkif);
   23.19  	if (be->frontpath)
   23.20 @@ -72,7 +69,7 @@ static void frontend_changed(struct xenb
   23.21  		device_unregister(&be->dev->dev);
   23.22  		return;
   23.23  	}
   23.24 -	if (vbd_is_active(be->vbd))
   23.25 +	if (be->blkif->status == CONNECTED)
   23.26  		return;
   23.27  
   23.28  	err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
   23.29 @@ -85,9 +82,8 @@ static void frontend_changed(struct xenb
   23.30  	}
   23.31  
   23.32  	/* Domains must use same shared frame for all vbds. */
   23.33 -	if (be->blkif->status == CONNECTED &&
   23.34 -	    (evtchn != be->blkif->remote_evtchn ||
   23.35 -	     sharedmfn != be->blkif->shmem_frame)) {
   23.36 +	if (evtchn != be->blkif->remote_evtchn ||
   23.37 +	    sharedmfn != be->blkif->shmem_frame) {
   23.38  		xenbus_dev_error(be->dev, err,
   23.39  				 "Shared frame/evtchn %li/%u not same as"
   23.40  				 " old %li/%u",
   23.41 @@ -105,7 +101,7 @@ static void frontend_changed(struct xenb
   23.42  	}
   23.43  
   23.44  	err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
   23.45 -			    vbd_size(be->vbd));
   23.46 +			    vbd_size(&be->blkif->vbd));
   23.47  	if (err) {
   23.48  		xenbus_dev_error(be->dev, err, "writing %s/sectors",
   23.49  				 be->dev->nodename);
   23.50 @@ -114,34 +110,29 @@ static void frontend_changed(struct xenb
   23.51  
   23.52  	/* FIXME: use a typename instead */
   23.53  	err = xenbus_printf(be->dev->nodename, "info", "%u",
   23.54 -			    vbd_info(be->vbd));
   23.55 +			    vbd_info(&be->blkif->vbd));
   23.56  	if (err) {
   23.57  		xenbus_dev_error(be->dev, err, "writing %s/info",
   23.58  				 be->dev->nodename);
   23.59  		goto abort;
   23.60  	}
   23.61  	err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
   23.62 -			    vbd_secsize(be->vbd));
   23.63 +			    vbd_secsize(&be->blkif->vbd));
   23.64  	if (err) {
   23.65  		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
   23.66  				 be->dev->nodename);
   23.67  		goto abort;
   23.68  	}
   23.69  
   23.70 -	/* First vbd?  We need to map the shared frame, irq etc. */
   23.71 -	if (be->blkif->status != CONNECTED) {
   23.72 -		err = blkif_map(be->blkif, sharedmfn, evtchn);
   23.73 -		if (err) {
   23.74 -			xenbus_dev_error(be->dev, err,
   23.75 -					 "mapping shared-frame %lu port %u",
   23.76 -					 sharedmfn, evtchn);
   23.77 -			goto abort;
   23.78 -		}
   23.79 +	/* Map the shared frame, irq etc. */
   23.80 +	err = blkif_map(be->blkif, sharedmfn, evtchn);
   23.81 +	if (err) {
   23.82 +		xenbus_dev_error(be->dev, err,
   23.83 +				 "mapping shared-frame %lu port %u",
   23.84 +				 sharedmfn, evtchn);
   23.85 +		goto abort;
   23.86  	}
   23.87  
   23.88 -	/* We're ready, activate. */
   23.89 -	vbd_activate(be->blkif, be->vbd);
   23.90 -
   23.91  	xenbus_transaction_end(0);
   23.92  	xenbus_dev_ok(be->dev);
   23.93  
   23.94 @@ -228,20 +219,16 @@ static void backend_changed(struct xenbu
   23.95  		p = strrchr(be->frontpath, '/') + 1;
   23.96  		handle = simple_strtoul(p, NULL, 0);
   23.97  
   23.98 -		be->blkif = blkif_find(be->frontend_id);
   23.99 +		be->blkif = alloc_blkif(be->frontend_id);
  23.100  		if (IS_ERR(be->blkif)) {
  23.101  			err = PTR_ERR(be->blkif);
  23.102  			be->blkif = NULL;
  23.103  			goto device_fail;
  23.104  		}
  23.105  
  23.106 -		be->vbd = vbd_create(be->blkif, handle, be->pdev,
  23.107 -				     be->readonly);
  23.108 -		if (IS_ERR(be->vbd)) {
  23.109 -			err = PTR_ERR(be->vbd);
  23.110 -			be->vbd = NULL;
  23.111 +		err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
  23.112 +		if (err)
  23.113  			goto device_fail;
  23.114 -		}
  23.115  
  23.116  		frontend_changed(&be->watch, be->frontpath);
  23.117  	}
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Mon Aug 22 11:37:48 2005 -0700
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Aug 23 12:03:21 2005 -0700
    24.3 @@ -63,25 +63,16 @@ typedef unsigned char byte; /* from linu
    24.4  /* Control whether runtime update of vbds is enabled. */
    24.5  #define ENABLE_VBD_UPDATE 1
    24.6  
    24.7 -#define BLKIF_STATE_CLOSED       0
    24.8 -#define BLKIF_STATE_DISCONNECTED 1
    24.9 -#define BLKIF_STATE_CONNECTED    2
   24.10 +#define BLKIF_STATE_DISCONNECTED 0
   24.11 +#define BLKIF_STATE_CONNECTED    1
   24.12  
   24.13 -static unsigned int blkif_state = BLKIF_STATE_CLOSED;
   24.14 -static unsigned int blkif_evtchn = 0;
   24.15 -static unsigned int blkif_vbds = 0;
   24.16 -static unsigned int blkif_vbds_connected = 0;
   24.17 -
   24.18 -static blkif_front_ring_t blk_ring;
   24.19 +static unsigned int blkif_state = BLKIF_STATE_DISCONNECTED;
   24.20  
   24.21  #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   24.22  
   24.23 -static domid_t rdomid = 0;
   24.24 -static grant_ref_t gref_head, gref_terminal;
   24.25  #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
   24.26      (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
   24.27  #define GRANTREF_INVALID (1<<15)
   24.28 -static int shmem_ref;
   24.29  
   24.30  static struct blk_shadow {
   24.31      blkif_request_t req;
   24.32 @@ -92,7 +83,7 @@ unsigned long blk_shadow_free;
   24.33  
   24.34  static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */
   24.35  
   24.36 -static void kick_pending_request_queues(void);
   24.37 +static void kick_pending_request_queues(struct blkfront_info *info);
   24.38  
   24.39  static int __init xlblk_init(void);
   24.40  
   24.41 @@ -119,7 +110,7 @@ static inline void ADD_ID_TO_FREELIST(un
   24.42  
   24.43  /* Kernel-specific definitions used in the common code */
   24.44  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   24.45 -#define DISABLE_SCATTERGATHER() 
   24.46 +#define DISABLE_SCATTERGATHER()
   24.47  #else
   24.48  static int sg_operation = -1;
   24.49  #define DISABLE_SCATTERGATHER() (sg_operation = -1)
   24.50 @@ -138,11 +129,11 @@ static inline void unpickle_request(blki
   24.51  }
   24.52  
   24.53  
   24.54 -static inline void flush_requests(void)
   24.55 +static inline void flush_requests(struct blkfront_info *info)
   24.56  {
   24.57      DISABLE_SCATTERGATHER();
   24.58 -    RING_PUSH_REQUESTS(&blk_ring);
   24.59 -    notify_via_evtchn(blkif_evtchn);
   24.60 +    RING_PUSH_REQUESTS(&info->ring);
   24.61 +    notify_via_evtchn(info->evtchn);
   24.62  }
   24.63  
   24.64  
   24.65 @@ -152,30 +143,39 @@ static inline void flush_requests(void)
   24.66  
   24.67  module_init(xlblk_init);
   24.68  
   24.69 -static struct xlbd_disk_info *head_waiting = NULL;
   24.70 -static void kick_pending_request_queues(void)
   24.71 +static void kick_pending_request_queues(struct blkfront_info *info)
   24.72  {
   24.73 -    struct xlbd_disk_info *di;
   24.74 -    while ( ((di = head_waiting) != NULL) && !RING_FULL(&blk_ring) )
   24.75 -    {
   24.76 -        head_waiting = di->next_waiting;
   24.77 -        di->next_waiting = NULL;
   24.78 -        /* Re-enable calldowns. */
   24.79 -        blk_start_queue(di->rq);
   24.80 -        /* Kick things off immediately. */
   24.81 -        do_blkif_request(di->rq);
   24.82 -    }
   24.83 +	if (!RING_FULL(&info->ring)) {
   24.84 +		/* Re-enable calldowns. */
   24.85 +		blk_start_queue(info->rq);
   24.86 +		/* Kick things off immediately. */
   24.87 +		do_blkif_request(info->rq);
   24.88 +	}
   24.89 +}
   24.90 +
   24.91 +static void blkif_restart_queue(void *arg)
   24.92 +{
   24.93 +	struct blkfront_info *info = (struct blkfront_info *)arg;
   24.94 +	spin_lock_irq(&blkif_io_lock);
   24.95 +	kick_pending_request_queues(info);
   24.96 +	spin_unlock_irq(&blkif_io_lock);
   24.97 +}
   24.98 +
   24.99 +static void blkif_restart_queue_callback(void *arg)
  24.100 +{
  24.101 +	struct blkfront_info *info = (struct blkfront_info *)arg;
  24.102 +	schedule_work(&info->work);
  24.103  }
  24.104  
  24.105  int blkif_open(struct inode *inode, struct file *filep)
  24.106  {
  24.107 -    struct gendisk *gd = inode->i_bdev->bd_disk;
  24.108 -    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
  24.109 +	// struct gendisk *gd = inode->i_bdev->bd_disk;
  24.110 +	// struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
  24.111  
  24.112 -    /* Update of usage count is protected by per-device semaphore. */
  24.113 -    di->mi->usage++;
  24.114 -    
  24.115 -    return 0;
  24.116 +	/* Update of usage count is protected by per-device semaphore. */
  24.117 +	// di->mi->usage++;
  24.118 +
  24.119 +	return 0;
  24.120  }
  24.121  
  24.122  
  24.123 @@ -192,8 +192,8 @@ int blkif_ioctl(struct inode *inode, str
  24.124      int i;
  24.125  
  24.126      DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
  24.127 -                  command, (long)argument, inode->i_rdev); 
  24.128 -  
  24.129 +                  command, (long)argument, inode->i_rdev);
  24.130 +
  24.131      switch ( command )
  24.132      {
  24.133      case HDIO_GETGEO:
  24.134 @@ -219,7 +219,7 @@ int blkif_ioctl(struct inode *inode, str
  24.135  /*
  24.136   * blkif_queue_request
  24.137   *
  24.138 - * request block io 
  24.139 + * request block io
  24.140   * 
  24.141   * id: for guest use only.
  24.142   * operation: BLKIF_OP_{READ,WRITE,PROBE}
  24.143 @@ -228,7 +228,7 @@ int blkif_ioctl(struct inode *inode, str
  24.144   */
  24.145  static int blkif_queue_request(struct request *req)
  24.146  {
  24.147 -    struct xlbd_disk_info *di = req->rq_disk->private_data;
  24.148 +    struct blkfront_info *info = req->rq_disk->private_data;
  24.149      unsigned long buffer_ma;
  24.150      blkif_request_t *ring_req;
  24.151      struct bio *bio;
  24.152 @@ -237,20 +237,28 @@ static int blkif_queue_request(struct re
  24.153      unsigned long id;
  24.154      unsigned int fsect, lsect;
  24.155      int ref;
  24.156 +    grant_ref_t gref_head;
  24.157  
  24.158 -    if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
  24.159 +    if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
  24.160          return 1;
  24.161  
  24.162 +    if (gnttab_alloc_grant_references(BLKIF_MAX_SEGMENTS_PER_REQUEST,
  24.163 +				      &gref_head) < 0) {
  24.164 +	    gnttab_request_free_callback(&info->callback,
  24.165 +					 blkif_restart_queue_callback, info,
  24.166 +					 BLKIF_MAX_SEGMENTS_PER_REQUEST);
  24.167 +	    return 1;
  24.168 +    }
  24.169 +
  24.170      /* Fill out a communications ring structure. */
  24.171 -    ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
  24.172 +    ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
  24.173      id = GET_ID_FROM_FREELIST();
  24.174      blk_shadow[id].request = (unsigned long)req;
  24.175  
  24.176      ring_req->id = id;
  24.177 -    ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
  24.178 -        BLKIF_OP_READ;
  24.179 +    ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ;
  24.180      ring_req->sector_number = (blkif_sector_t)req->sector;
  24.181 -    ring_req->handle = di->handle;
  24.182 +    ring_req->handle = info->handle;
  24.183  
  24.184      ring_req->nr_segments = 0;
  24.185      rq_for_each_bio(bio, req)
  24.186 @@ -263,56 +271,61 @@ static int blkif_queue_request(struct re
  24.187              fsect = bvec->bv_offset >> 9;
  24.188              lsect = fsect + (bvec->bv_len >> 9) - 1;
  24.189              /* install a grant reference. */
  24.190 -            ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
  24.191 +            ref = gnttab_claim_grant_reference(&gref_head);
  24.192              ASSERT( ref != -ENOSPC );
  24.193  
  24.194              gnttab_grant_foreign_access_ref(
  24.195                          ref,
  24.196 -                        rdomid,
  24.197 +                        info->backend_id,
  24.198                          buffer_ma >> PAGE_SHIFT,
  24.199                          rq_data_dir(req) );
  24.200  
  24.201              blk_shadow[id].frame[ring_req->nr_segments] =
  24.202                  buffer_ma >> PAGE_SHIFT;
  24.203  
  24.204 -            ring_req->frame_and_sects[ring_req->nr_segments++] =
  24.205 +            ring_req->frame_and_sects[ring_req->nr_segments] =
  24.206                  blkif_fas_from_gref(ref, fsect, lsect);
  24.207 +
  24.208 +	    ring_req->nr_segments++;
  24.209          }
  24.210      }
  24.211  
  24.212 -    blk_ring.req_prod_pvt++;
  24.213 -    
  24.214 +    info->ring.req_prod_pvt++;
  24.215 +
  24.216      /* Keep a private copy so we can reissue requests when recovering. */
  24.217      pickle_request(&blk_shadow[id], ring_req);
  24.218  
  24.219 +    gnttab_free_grant_references(gref_head);
  24.220 +
  24.221      return 0;
  24.222  }
  24.223  
  24.224 -
  24.225  /*
  24.226   * do_blkif_request
  24.227   *  read a block; request is in a request queue
  24.228   */
  24.229  void do_blkif_request(request_queue_t *rq)
  24.230  {
  24.231 -    struct xlbd_disk_info *di;
  24.232 +    struct blkfront_info *info = NULL;
  24.233      struct request *req;
  24.234      int queued;
  24.235  
  24.236 -    DPRINTK("Entered do_blkif_request\n"); 
  24.237 +    DPRINTK("Entered do_blkif_request\n");
  24.238  
  24.239      queued = 0;
  24.240  
  24.241      while ( (req = elv_next_request(rq)) != NULL )
  24.242      {
  24.243 +	info = req->rq_disk->private_data;
  24.244 +
  24.245          if ( !blk_fs_request(req) )
  24.246          {
  24.247              end_request(req, 0);
  24.248              continue;
  24.249          }
  24.250  
  24.251 -        if ( RING_FULL(&blk_ring) )
  24.252 -            goto wait;
  24.253 +	if (RING_FULL(&info->ring))
  24.254 +		goto wait;
  24.255  
  24.256          DPRINTK("do_blk_req %p: cmd %p, sec %lx, (%u/%li) buffer:%p [%s]\n",
  24.257                  req, req->cmd, req->sector, req->current_nr_sectors,
  24.258 @@ -320,25 +333,19 @@ void do_blkif_request(request_queue_t *r
  24.259                  rq_data_dir(req) ? "write" : "read");
  24.260  
  24.261          blkdev_dequeue_request(req);
  24.262 -        if ( blkif_queue_request(req) )
  24.263 -        {
  24.264 +        if (blkif_queue_request(req)) {
  24.265 +		blk_requeue_request(rq, req);
  24.266          wait:
  24.267 -            di = req->rq_disk->private_data;
  24.268 -            if ( di->next_waiting == NULL )
  24.269 -            {
  24.270 -                di->next_waiting = head_waiting;
  24.271 -                head_waiting = di;
  24.272 -                /* Avoid pointless unplugs. */
  24.273 -                blk_stop_queue(rq);
  24.274 -            }
  24.275 -            break;
  24.276 +		/* Avoid pointless unplugs. */
  24.277 +		blk_stop_queue(rq);
  24.278 +		break;
  24.279          }
  24.280  
  24.281          queued++;
  24.282      }
  24.283  
  24.284      if ( queued != 0 )
  24.285 -        flush_requests();
  24.286 +        flush_requests(info);
  24.287  }
  24.288  
  24.289  
  24.290 @@ -347,25 +354,24 @@ static irqreturn_t blkif_int(int irq, vo
  24.291      struct request *req;
  24.292      blkif_response_t *bret;
  24.293      RING_IDX i, rp;
  24.294 -    unsigned long flags; 
  24.295 -    
  24.296 -    spin_lock_irqsave(&blkif_io_lock, flags);     
  24.297 +    unsigned long flags;
  24.298 +    struct blkfront_info *info = (struct blkfront_info *)dev_id;
  24.299  
  24.300 -    if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) || 
  24.301 -         unlikely(recovery) )
  24.302 -    {
  24.303 +    spin_lock_irqsave(&blkif_io_lock, flags);
  24.304 +
  24.305 +    if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
  24.306          spin_unlock_irqrestore(&blkif_io_lock, flags);
  24.307          return IRQ_HANDLED;
  24.308      }
  24.309 -    
  24.310 -    rp = blk_ring.sring->rsp_prod;
  24.311 +
  24.312 +    rp = info->ring.sring->rsp_prod;
  24.313      rmb(); /* Ensure we see queued responses up to 'rp'. */
  24.314  
  24.315 -    for ( i = blk_ring.rsp_cons; i != rp; i++ )
  24.316 +    for ( i = info->ring.rsp_cons; i != rp; i++ )
  24.317      {
  24.318          unsigned long id;
  24.319  
  24.320 -        bret = RING_GET_RESPONSE(&blk_ring, i);
  24.321 +        bret = RING_GET_RESPONSE(&info->ring, i);
  24.322          id   = bret->id;
  24.323          req  = (struct request *)blk_shadow[id].request;
  24.324  
  24.325 @@ -382,7 +388,7 @@ static irqreturn_t blkif_int(int irq, vo
  24.326                          bret->status);
  24.327  
  24.328              if ( unlikely(end_that_request_first
  24.329 -                          (req, 
  24.330 +                          (req,
  24.331                             (bret->status == BLKIF_RSP_OKAY),
  24.332                             req->hard_nr_sectors)) )
  24.333                  BUG();
  24.334 @@ -394,9 +400,9 @@ static irqreturn_t blkif_int(int irq, vo
  24.335          }
  24.336      }
  24.337  
  24.338 -    blk_ring.rsp_cons = i;
  24.339 +    info->ring.rsp_cons = i;
  24.340  
  24.341 -    kick_pending_request_queues();
  24.342 +    kick_pending_request_queues(info);
  24.343  
  24.344      spin_unlock_irqrestore(&blkif_io_lock, flags);
  24.345  
  24.346 @@ -425,31 +431,31 @@ static int nr_pending;
  24.347  static void kick_pending_request_queues(void)
  24.348  {
  24.349      /* We kick pending request queues if the ring is reasonably empty. */
  24.350 -    if ( (nr_pending != 0) && 
  24.351 -         (RING_PENDING_REQUESTS(&blk_ring) < (BLK_RING_SIZE >> 1)) )
  24.352 +    if ( (nr_pending != 0) &&
  24.353 +         (RING_PENDING_REQUESTS(&info->ring) < (BLK_RING_SIZE >> 1)) )
  24.354      {
  24.355          /* Attempt to drain the queue, but bail if the ring becomes full. */
  24.356 -        while ( (nr_pending != 0) && !RING_FULL(&blk_ring) )
  24.357 +        while ( (nr_pending != 0) && !RING_FULL(&info->ring) )
  24.358              do_blkif_request(pending_queues[--nr_pending]);
  24.359      }
  24.360  }
  24.361  
  24.362  int blkif_open(struct inode *inode, struct file *filep)
  24.363  {
  24.364 -    short xldev = inode->i_rdev; 
  24.365 +    short xldev = inode->i_rdev;
  24.366      struct gendisk *gd = get_gendisk(xldev);
  24.367      xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
  24.368 -    short minor = MINOR(xldev); 
  24.369 +    short minor = MINOR(xldev);
  24.370  
  24.371      if ( gd->part[minor].nr_sects == 0 )
  24.372 -    { 
  24.373 +    {
  24.374          /*
  24.375           * Device either doesn't exist, or has zero capacity; we use a few
  24.376           * cheesy heuristics to return the relevant error code
  24.377           */
  24.378          if ( (gd->sizes[minor >> gd->minor_shift] != 0) ||
  24.379               ((minor & (gd->max_p - 1)) != 0) )
  24.380 -        { 
  24.381 +        {
  24.382              /*
  24.383               * We have a real device, but no such partition, or we just have a
  24.384               * partition number so guess this is the problem.
  24.385 @@ -458,16 +464,16 @@ int blkif_open(struct inode *inode, stru
  24.386          }
  24.387          else if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE )
  24.388          {
  24.389 -            /* This is a removable device => assume that media is missing. */ 
  24.390 +            /* This is a removable device => assume that media is missing. */
  24.391              return -ENOMEDIUM; /* media not present (this is a guess) */
  24.392 -        } 
  24.393 +        }
  24.394          else
  24.395 -        { 
  24.396 +        {
  24.397              /* Just go for the general 'no such device' error. */
  24.398              return -ENODEV;    /* no such device */
  24.399          }
  24.400      }
  24.401 -    
  24.402 +
  24.403      /* Update of usage count is protected by per-device semaphore. */
  24.404      disk->usage++;
  24.405  
  24.406 @@ -496,24 +502,24 @@ int blkif_ioctl(struct inode *inode, str
  24.407  {
  24.408      kdev_t dev = inode->i_rdev;
  24.409      struct hd_geometry *geo = (struct hd_geometry *)argument;
  24.410 -    struct gendisk *gd;     
  24.411 -    struct hd_struct *part; 
  24.412 +    struct gendisk *gd;
  24.413 +    struct hd_struct *part;
  24.414      int i;
  24.415      unsigned short cylinders;
  24.416      byte heads, sectors;
  24.417  
  24.418      /* NB. No need to check permissions. That is done for us. */
  24.419 -    
  24.420 +
  24.421      DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
  24.422 -                  command, (long) argument, dev); 
  24.423 -  
  24.424 +                  command, (long) argument, dev);
  24.425 +
  24.426      gd = get_gendisk(dev);
  24.427 -    part = &gd->part[MINOR(dev)]; 
  24.428 +    part = &gd->part[MINOR(dev)];
  24.429  
  24.430      switch ( command )
  24.431      {
  24.432      case BLKGETSIZE:
  24.433 -        DPRINTK_IOCTL("   BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects); 
  24.434 +        DPRINTK_IOCTL("   BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
  24.435          return put_user(part->nr_sects, (unsigned long *) argument);
  24.436  
  24.437      case BLKGETSIZE64:
  24.438 @@ -526,7 +532,7 @@ int blkif_ioctl(struct inode *inode, str
  24.439          return blkif_revalidate(dev);
  24.440  
  24.441      case BLKSSZGET:
  24.442 -        return hardsect_size[MAJOR(dev)][MINOR(dev)]; 
  24.443 +        return hardsect_size[MAJOR(dev)][MINOR(dev)];
  24.444  
  24.445      case BLKBSZGET:                                        /* get block size */
  24.446          DPRINTK_IOCTL("   BLKBSZGET: %x\n", BLKBSZGET);
  24.447 @@ -552,7 +558,7 @@ int blkif_ioctl(struct inode *inode, str
  24.448             values consistent with the size of the device */
  24.449  
  24.450          heads = 0xff;
  24.451 -        sectors = 0x3f; 
  24.452 +        sectors = 0x3f;
  24.453          cylinders = part->nr_sects / (heads * sectors);
  24.454  
  24.455          if (put_user(0x00,  (unsigned long *) &geo->start)) return -EFAULT;
  24.456 @@ -562,7 +568,7 @@ int blkif_ioctl(struct inode *inode, str
  24.457  
  24.458          return 0;
  24.459  
  24.460 -    case HDIO_GETGEO_BIG: 
  24.461 +    case HDIO_GETGEO_BIG:
  24.462          DPRINTK_IOCTL("   HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
  24.463          if (!argument) return -EINVAL;
  24.464  
  24.465 @@ -570,7 +576,7 @@ int blkif_ioctl(struct inode *inode, str
  24.466             values consistent with the size of the device */
  24.467  
  24.468          heads = 0xff;
  24.469 -        sectors = 0x3f; 
  24.470 +        sectors = 0x3f;
  24.471          cylinders = part->nr_sects / (heads * sectors);
  24.472  
  24.473          if (put_user(0x00,  (unsigned long *) &geo->start))  return -EFAULT;
  24.474 @@ -594,7 +600,7 @@ int blkif_ioctl(struct inode *inode, str
  24.475          WPRINTK("ioctl %08x not supported by XL blkif\n", command);
  24.476          return -ENOSYS;
  24.477      }
  24.478 -    
  24.479 +
  24.480      return 0;
  24.481  }
  24.482  
  24.483 @@ -614,7 +620,7 @@ int blkif_revalidate(kdev_t dev)
  24.484      xl_disk_t *disk;
  24.485      unsigned long capacity;
  24.486      int i, rc = 0;
  24.487 -    
  24.488 +
  24.489      if ( (bd = bdget(dev)) == NULL )
  24.490          return -EINVAL;
  24.491  
  24.492 @@ -662,7 +668,7 @@ int blkif_revalidate(kdev_t dev)
  24.493  /*
  24.494   * blkif_queue_request
  24.495   *
  24.496 - * request block io 
  24.497 + * request block io
  24.498   * 
  24.499   * id: for guest use only.
  24.500   * operation: BLKIF_OP_{READ,WRITE,PROBE}
  24.501 @@ -696,7 +702,7 @@ static int blkif_queue_request(unsigned 
  24.502  
  24.503      buffer_ma &= PAGE_MASK;
  24.504  
  24.505 -    if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
  24.506 +    if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
  24.507          return 1;
  24.508  
  24.509      switch ( operation )
  24.510 @@ -704,7 +710,7 @@ static int blkif_queue_request(unsigned 
  24.511  
  24.512      case BLKIF_OP_READ:
  24.513      case BLKIF_OP_WRITE:
  24.514 -        gd = get_gendisk(device); 
  24.515 +        gd = get_gendisk(device);
  24.516  
  24.517          /*
  24.518           * Update the sector_number we'll pass down as appropriate; note that
  24.519 @@ -714,10 +720,10 @@ static int blkif_queue_request(unsigned 
  24.520          sector_number += gd->part[MINOR(device)].start_sect;
  24.521  
  24.522          /*
  24.523 -         * If this unit doesn't consist of virtual partitions then we clear 
  24.524 +         * If this unit doesn't consist of virtual partitions then we clear
  24.525           * the partn bits from the device number.
  24.526           */
  24.527 -        if ( !(gd->flags[MINOR(device)>>gd->minor_shift] & 
  24.528 +        if ( !(gd->flags[MINOR(device)>>gd->minor_shift] &
  24.529                 GENHD_FL_VIRT_PARTNS) )
  24.530              device &= ~(gd->max_p - 1);
  24.531  
  24.532 @@ -725,20 +731,20 @@ static int blkif_queue_request(unsigned 
  24.533               (sg_dev == device) &&
  24.534               (sg_next_sect == sector_number) )
  24.535          {
  24.536 -            req = RING_GET_REQUEST(&blk_ring, 
  24.537 -                                   blk_ring.req_prod_pvt - 1);
  24.538 +            req = RING_GET_REQUEST(&info->ring,
  24.539 +                                   info->ring.req_prod_pvt - 1);
  24.540              bh = (struct buffer_head *)id;
  24.541 -     
  24.542 +
  24.543              bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request;
  24.544              blk_shadow[req->id].request = (unsigned long)id;
  24.545  
  24.546              /* install a grant reference. */
  24.547 -            ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
  24.548 +            ref = gnttab_claim_grant_reference(&gref_head);
  24.549              ASSERT( ref != -ENOSPC );
  24.550  
  24.551              gnttab_grant_foreign_access_ref(
  24.552                          ref,
  24.553 -                        rdomid,
  24.554 +                        info->backend_id,
  24.555                          buffer_ma >> PAGE_SHIFT,
  24.556                          ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
  24.557  
  24.558 @@ -757,7 +763,7 @@ static int blkif_queue_request(unsigned 
  24.559  
  24.560              return 0;
  24.561          }
  24.562 -        else if ( RING_FULL(&blk_ring) )
  24.563 +        else if ( RING_FULL(&info->ring) )
  24.564          {
  24.565              return 1;
  24.566          }
  24.567 @@ -774,7 +780,7 @@ static int blkif_queue_request(unsigned 
  24.568      }
  24.569  
  24.570      /* Fill out a communications ring structure. */
  24.571 -    req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
  24.572 +    req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
  24.573  
  24.574      xid = GET_ID_FROM_FREELIST();
  24.575      blk_shadow[xid].request = (unsigned long)id;
  24.576 @@ -782,15 +788,15 @@ static int blkif_queue_request(unsigned 
  24.577      req->id            = xid;
  24.578      req->operation     = operation;
  24.579      req->sector_number = (blkif_sector_t)sector_number;
  24.580 -    req->handle        = handle; 
  24.581 +    req->handle        = handle;
  24.582      req->nr_segments   = 1;
  24.583      /* install a grant reference. */
  24.584 -    ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
  24.585 +    ref = gnttab_claim_grant_reference(&gref_head);
  24.586      ASSERT( ref != -ENOSPC );
  24.587  
  24.588      gnttab_grant_foreign_access_ref(
  24.589                  ref,
  24.590 -                rdomid,
  24.591 +                info->backend_id,
  24.592                  buffer_ma >> PAGE_SHIFT,
  24.593                  ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
  24.594  
  24.595 @@ -798,11 +804,11 @@ static int blkif_queue_request(unsigned 
  24.596  
  24.597      req->frame_and_sects[0] = blkif_fas_from_gref(ref, fsect, lsect);
  24.598  
  24.599 -    /* Keep a private copy so we can reissue requests when recovering. */    
  24.600 +    /* Keep a private copy so we can reissue requests when recovering. */
  24.601      pickle_request(&blk_shadow[xid], req);
  24.602  
  24.603 -    blk_ring.req_prod_pvt++;
  24.604 -    
  24.605 +    info->ring.req_prod_pvt++;
  24.606 +
  24.607      return 0;
  24.608  }
  24.609  
  24.610 @@ -817,13 +823,13 @@ void do_blkif_request(request_queue_t *r
  24.611      struct buffer_head *bh, *next_bh;
  24.612      int rw, nsect, full, queued = 0;
  24.613  
  24.614 -    DPRINTK("Entered do_blkif_request\n"); 
  24.615 +    DPRINTK("Entered do_blkif_request\n");
  24.616  
  24.617      while ( !rq->plugged && !list_empty(&rq->queue_head))
  24.618      {
  24.619 -        if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL ) 
  24.620 +        if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL )
  24.621              goto out;
  24.622 -  
  24.623 +
  24.624          DPRINTK("do_blkif_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n",
  24.625                  req, req->cmd, req->sector,
  24.626                  req->current_nr_sectors, req->nr_sectors, req->bh);
  24.627 @@ -844,16 +850,16 @@ void do_blkif_request(request_queue_t *r
  24.628  
  24.629              full = blkif_queue_request(
  24.630                  (unsigned long)bh,
  24.631 -                (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE, 
  24.632 +                (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE,
  24.633                  bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev);
  24.634  
  24.635              if ( full )
  24.636 -            { 
  24.637 +            {
  24.638                  bh->b_reqnext = next_bh;
  24.639                  pending_queues[nr_pending++] = rq;
  24.640                  if ( unlikely(nr_pending >= MAX_PENDING) )
  24.641                      BUG();
  24.642 -                goto out; 
  24.643 +                goto out;
  24.644              }
  24.645  
  24.646              queued++;
  24.647 @@ -861,7 +867,7 @@ void do_blkif_request(request_queue_t *r
  24.648              /* Dequeue the buffer head from the request. */
  24.649              nsect = bh->b_size >> 9;
  24.650              bh = req->bh = next_bh;
  24.651 -            
  24.652 +
  24.653              if ( bh != NULL )
  24.654              {
  24.655                  /* There's another buffer head to do. Update the request. */
  24.656 @@ -891,27 +897,27 @@ void do_blkif_request(request_queue_t *r
  24.657  
  24.658  static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
  24.659  {
  24.660 -    RING_IDX i, rp; 
  24.661 -    unsigned long flags; 
  24.662 +    RING_IDX i, rp;
  24.663 +    unsigned long flags;
  24.664      struct buffer_head *bh, *next_bh;
  24.665 -    
  24.666 -    spin_lock_irqsave(&io_request_lock, flags);     
  24.667  
  24.668 -    if ( unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery) )
  24.669 +    spin_lock_irqsave(&io_request_lock, flags);
  24.670 +
  24.671 +    if ( unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery) )
  24.672      {
  24.673          spin_unlock_irqrestore(&io_request_lock, flags);
  24.674          return;
  24.675      }
  24.676  
  24.677 -    rp = blk_ring.sring->rsp_prod;
  24.678 +    rp = info->ring.sring->rsp_prod;
  24.679      rmb(); /* Ensure we see queued responses up to 'rp'. */
  24.680  
  24.681 -    for ( i = blk_ring.rsp_cons; i != rp; i++ )
  24.682 +    for ( i = info->ring.rsp_cons; i != rp; i++ )
  24.683      {
  24.684          unsigned long id;
  24.685          blkif_response_t *bret;
  24.686 -        
  24.687 -        bret = RING_GET_RESPONSE(&blk_ring, i);
  24.688 +
  24.689 +        bret = RING_GET_RESPONSE(&info->ring, i);
  24.690          id = bret->id;
  24.691          bh = (struct buffer_head *)blk_shadow[id].request;
  24.692  
  24.693 @@ -943,8 +949,8 @@ static void blkif_int(int irq, void *dev
  24.694          }
  24.695  
  24.696      }
  24.697 -    blk_ring.rsp_cons = i;
  24.698 -    
  24.699 +    info->ring.rsp_cons = i;
  24.700 +
  24.701      kick_pending_request_queues();
  24.702  
  24.703      spin_unlock_irqrestore(&io_request_lock, flags);
  24.704 @@ -954,24 +960,24 @@ static void blkif_int(int irq, void *dev
  24.705  
  24.706  /*****************************  COMMON CODE  *******************************/
  24.707  
  24.708 -static void blkif_free(void)
  24.709 +static void blkif_free(struct blkfront_info *info)
  24.710  {
  24.711      /* Prevent new requests being issued until we fix things up. */
  24.712      spin_lock_irq(&blkif_io_lock);
  24.713 -    blkif_state = BLKIF_STATE_DISCONNECTED;
  24.714 +    info->connected = BLKIF_STATE_DISCONNECTED;
  24.715      spin_unlock_irq(&blkif_io_lock);
  24.716  
  24.717      /* Free resources associated with old device channel. */
  24.718 -    if ( blk_ring.sring != NULL )
  24.719 +    if ( info->ring.sring != NULL )
  24.720      {
  24.721 -        free_page((unsigned long)blk_ring.sring);
  24.722 -        blk_ring.sring = NULL;
  24.723 +        free_page((unsigned long)info->ring.sring);
  24.724 +        info->ring.sring = NULL;
  24.725      }
  24.726 -    unbind_evtchn_from_irqhandler(blkif_evtchn, NULL);
  24.727 -    blkif_evtchn = 0;
  24.728 +    unbind_evtchn_from_irqhandler(info->evtchn, NULL);
  24.729 +    info->evtchn = 0;
  24.730  }
  24.731  
  24.732 -static void blkif_recover(void)
  24.733 +static void blkif_recover(struct blkfront_info *info)
  24.734  {
  24.735      int i;
  24.736      blkif_request_t *req;
  24.737 @@ -987,7 +993,7 @@ static void blkif_recover(void)
  24.738      memset(&blk_shadow, 0, sizeof(blk_shadow));
  24.739      for ( i = 0; i < BLK_RING_SIZE; i++ )
  24.740          blk_shadow[i].req.id = i+1;
  24.741 -    blk_shadow_free = blk_ring.req_prod_pvt;
  24.742 +    blk_shadow_free = info->ring.req_prod_pvt;
  24.743      blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  24.744  
  24.745      /* Stage 3: Find pending requests and requeue them. */
  24.746 @@ -999,7 +1005,7 @@ static void blkif_recover(void)
  24.747  
  24.748          /* Grab a request slot and unpickle shadow state into it. */
  24.749          req = RING_GET_REQUEST(
  24.750 -            &blk_ring, blk_ring.req_prod_pvt);
  24.751 +            &info->ring, info->ring.req_prod_pvt);
  24.752          unpickle_request(req, &copy[i]);
  24.753  
  24.754          /* We get a new request id, and must reset the shadow state. */
  24.755 @@ -1012,7 +1018,7 @@ static void blkif_recover(void)
  24.756              if ( req->frame_and_sects[j] & GRANTREF_INVALID )
  24.757                  gnttab_grant_foreign_access_ref(
  24.758                      blkif_gref_from_fas(req->frame_and_sects[j]),
  24.759 -                    rdomid,
  24.760 +                    info->backend_id,
  24.761                      blk_shadow[req->id].frame[j],
  24.762                      rq_data_dir((struct request *)
  24.763                                  blk_shadow[req->id].request));
  24.764 @@ -1020,32 +1026,31 @@ static void blkif_recover(void)
  24.765          }
  24.766          blk_shadow[req->id].req = *req;
  24.767  
  24.768 -        blk_ring.req_prod_pvt++;
  24.769 +        info->ring.req_prod_pvt++;
  24.770      }
  24.771  
  24.772      kfree(copy);
  24.773  
  24.774      recovery = 0;
  24.775  
  24.776 -    /* blk_ring->req_prod will be set when we flush_requests().*/
  24.777 +    /* info->ring->req_prod will be set when we flush_requests().*/
  24.778      wmb();
  24.779  
  24.780      /* Kicks things back into life. */
  24.781 -    flush_requests();
  24.782 +    flush_requests(info);
  24.783  
  24.784      /* Now safe to left other people use the interface. */
  24.785 -    blkif_state = BLKIF_STATE_CONNECTED;
  24.786 +    info->connected = BLKIF_STATE_CONNECTED;
  24.787  }
  24.788  
  24.789 -static void blkif_connect(u16 evtchn, domid_t domid)
  24.790 +static void blkif_connect(struct blkfront_info *info, u16 evtchn)
  24.791  {
  24.792      int err = 0;
  24.793  
  24.794 -    blkif_evtchn = evtchn;
  24.795 -    rdomid       = domid;
  24.796 +    info->evtchn = evtchn;
  24.797  
  24.798      err = bind_evtchn_to_irqhandler(
  24.799 -        blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
  24.800 +        info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
  24.801      if ( err != 0 )
  24.802      {
  24.803          WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  24.804 @@ -1059,17 +1064,6 @@ static struct xenbus_device_id blkfront_
  24.805  	{ "" }
  24.806  };
  24.807  
  24.808 -struct blkfront_info
  24.809 -{
  24.810 -	/* We watch the backend */
  24.811 -	struct xenbus_watch watch;
  24.812 -	int vdevice;
  24.813 -	u16 handle;
  24.814 -	int connected;
  24.815 -	struct xenbus_device *dev;
  24.816 -	char *backend;
  24.817 -};
  24.818 -
  24.819  static void watch_for_status(struct xenbus_watch *watch, const char *node)
  24.820  {
  24.821  	struct blkfront_info *info;
  24.822 @@ -1081,35 +1075,33 @@ static void watch_for_status(struct xenb
  24.823  	node += strlen(watch->node);
  24.824  
  24.825  	/* FIXME: clean up when error on the other end. */
  24.826 -	if (info->connected)
  24.827 +	if (info->connected == BLKIF_STATE_CONNECTED)
  24.828  		return;
  24.829  
  24.830 -	err = xenbus_gather(watch->node, 
  24.831 +	err = xenbus_gather(watch->node,
  24.832  			    "sectors", "%lu", &sectors,
  24.833  			    "info", "%u", &binfo,
  24.834  			    "sector-size", "%lu", &sector_size,
  24.835  			    NULL);
  24.836  	if (err) {
  24.837 -		xenbus_dev_error(info->dev, err, "reading backend fields");
  24.838 +		xenbus_dev_error(info->xbdev, err, "reading backend fields");
  24.839  		return;
  24.840  	}
  24.841  
  24.842 -	xlvbd_add(sectors, info->vdevice, info->handle, binfo, sector_size);
  24.843 -	info->connected = 1;
  24.844 +	xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
  24.845 +	info->connected = BLKIF_STATE_CONNECTED;
  24.846  
  24.847 -	/* First to connect?  blkif is now connected. */
  24.848 -	if (blkif_vbds_connected++ == 0)
  24.849 -		blkif_state = BLKIF_STATE_CONNECTED;
  24.850 +	blkif_state = BLKIF_STATE_CONNECTED;
  24.851  
  24.852 -	xenbus_dev_ok(info->dev);
  24.853 +	xenbus_dev_ok(info->xbdev);
  24.854  
  24.855  	/* Kick pending requests. */
  24.856  	spin_lock_irq(&blkif_io_lock);
  24.857 -	kick_pending_request_queues();
  24.858 +	kick_pending_request_queues(info);
  24.859  	spin_unlock_irq(&blkif_io_lock);
  24.860  }
  24.861  
  24.862 -static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id)
  24.863 +static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
  24.864  {
  24.865  	blkif_sring_t *sring;
  24.866  	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
  24.867 @@ -1121,25 +1113,28 @@ static int setup_blkring(struct xenbus_d
  24.868  		return -ENOMEM;
  24.869  	}
  24.870  	SHARED_RING_INIT(sring);
  24.871 -	FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
  24.872 +	FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
  24.873  
  24.874 -	shmem_ref = gnttab_claim_grant_reference(&gref_head,
  24.875 -						 gref_terminal);
  24.876 -	ASSERT(shmem_ref != -ENOSPC);
  24.877 -	gnttab_grant_foreign_access_ref(shmem_ref,
  24.878 -					backend_id,
  24.879 -					virt_to_mfn(blk_ring.sring),
  24.880 -					0);
  24.881 +	err = gnttab_grant_foreign_access(info->backend_id,
  24.882 +					  virt_to_mfn(info->ring.sring), 0);
  24.883 +	if (err == -ENOSPC) {
  24.884 +		free_page((unsigned long)info->ring.sring);
  24.885 +		info->ring.sring = 0;
  24.886 +		xenbus_dev_error(dev, err, "granting access to ring page");
  24.887 +		return err;
  24.888 +	}
  24.889 +	info->grant_id = err;
  24.890  
  24.891 -	op.u.alloc_unbound.dom = backend_id;
  24.892 +	op.u.alloc_unbound.dom = info->backend_id;
  24.893  	err = HYPERVISOR_event_channel_op(&op);
  24.894  	if (err) {
  24.895 -		free_page((unsigned long)blk_ring.sring);
  24.896 -		blk_ring.sring = 0;
  24.897 +		gnttab_end_foreign_access(info->grant_id, 0);
  24.898 +		free_page((unsigned long)info->ring.sring);
  24.899 +		info->ring.sring = 0;
  24.900  		xenbus_dev_error(dev, err, "allocating event channel");
  24.901  		return err;
  24.902  	}
  24.903 -	blkif_connect(op.u.alloc_unbound.port, backend_id);
  24.904 +	blkif_connect(info, op.u.alloc_unbound.port);
  24.905  	return 0;
  24.906  }
  24.907  
  24.908 @@ -1149,11 +1144,11 @@ static int talk_to_backend(struct xenbus
  24.909  {
  24.910  	char *backend;
  24.911  	const char *message;
  24.912 -	int err, backend_id;
  24.913 +	int err;
  24.914  
  24.915  	backend = NULL;
  24.916  	err = xenbus_gather(dev->nodename,
  24.917 -			    "backend-id", "%i", &backend_id,
  24.918 +			    "backend-id", "%i", &info->backend_id,
  24.919  			    "backend", NULL, &backend,
  24.920  			    NULL);
  24.921  	if (XENBUS_EXIST_ERR(err))
  24.922 @@ -1168,12 +1163,10 @@ static int talk_to_backend(struct xenbus
  24.923  		goto out;
  24.924  	}
  24.925  
  24.926 -	/* First device?  We create shared ring, alloc event channel. */
  24.927 -	if (blkif_vbds == 0) {
  24.928 -		err = setup_blkring(dev, backend_id);
  24.929 -		if (err)
  24.930 -			goto out;
  24.931 -	}
  24.932 +	/* Create shared ring, alloc event channel. */
  24.933 +	err = setup_blkring(dev, info);
  24.934 +	if (err)
  24.935 +		goto out;
  24.936  
  24.937  	err = xenbus_transaction_start(dev->nodename);
  24.938  	if (err) {
  24.939 @@ -1181,13 +1174,13 @@ static int talk_to_backend(struct xenbus
  24.940  		goto destroy_blkring;
  24.941  	}
  24.942  
  24.943 -	err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref);
  24.944 +	err = xenbus_printf(dev->nodename, "grant-id","%u", info->grant_id);
  24.945  	if (err) {
  24.946  		message = "writing grant-id";
  24.947  		goto abort_transaction;
  24.948  	}
  24.949  	err = xenbus_printf(dev->nodename,
  24.950 -			    "event-channel", "%u", blkif_evtchn);
  24.951 +			    "event-channel", "%u", info->evtchn);
  24.952  	if (err) {
  24.953  		message = "writing event-channel";
  24.954  		goto abort_transaction;
  24.955 @@ -1220,8 +1213,7 @@ static int talk_to_backend(struct xenbus
  24.956  	/* Have to do this *outside* transaction.  */
  24.957  	xenbus_dev_error(dev, err, "%s", message);
  24.958   destroy_blkring:
  24.959 -	if (blkif_vbds == 0)
  24.960 -		blkif_free();
  24.961 +	blkif_free(info);
  24.962  	goto out;
  24.963  }
  24.964  
  24.965 @@ -1250,9 +1242,11 @@ static int blkfront_probe(struct xenbus_
  24.966  		xenbus_dev_error(dev, err, "allocating info structure");
  24.967  		return err;
  24.968  	}
  24.969 -	info->dev = dev;
  24.970 +	info->xbdev = dev;
  24.971  	info->vdevice = vdevice;
  24.972 -	info->connected = 0;
  24.973 +	info->connected = BLKIF_STATE_DISCONNECTED;
  24.974 +	info->mi = NULL;
  24.975 +	INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
  24.976  
  24.977  	/* Front end dir is a number, which is used as the id. */
  24.978  	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
  24.979 @@ -1266,7 +1260,6 @@ static int blkfront_probe(struct xenbus_
  24.980  
  24.981  	/* Call once in case entries already there. */
  24.982  	watch_for_status(&info->watch, info->watch.node);
  24.983 -	blkif_vbds++;
  24.984  	return 0;
  24.985  }
  24.986  
  24.987 @@ -1277,16 +1270,14 @@ static int blkfront_remove(struct xenbus
  24.988  	if (info->backend)
  24.989  		unregister_xenbus_watch(&info->watch);
  24.990  
  24.991 -	if (info->connected) {
  24.992 -		xlvbd_del(info->handle);
  24.993 -		blkif_vbds_connected--;
  24.994 -	}
  24.995 +	if (info->mi)
  24.996 +		xlvbd_del(info);
  24.997 +
  24.998 +	blkif_free(info);
  24.999 +
 24.1000  	kfree(info->backend);
 24.1001  	kfree(info);
 24.1002  
 24.1003 -	if (--blkif_vbds == 0)
 24.1004 -		blkif_free();
 24.1005 -
 24.1006  	return 0;
 24.1007  }
 24.1008  
 24.1009 @@ -1298,10 +1289,8 @@ static int blkfront_suspend(struct xenbu
 24.1010  	kfree(info->backend);
 24.1011  	info->backend = NULL;
 24.1012  
 24.1013 -	if (--blkif_vbds == 0) {
 24.1014 -		recovery = 1;
 24.1015 -		blkif_free();
 24.1016 -	}
 24.1017 +	recovery = 1;
 24.1018 +	blkif_free(info);
 24.1019  
 24.1020  	return 0;
 24.1021  }
 24.1022 @@ -1314,8 +1303,7 @@ static int blkfront_resume(struct xenbus
 24.1023  	/* FIXME: Check geometry hasn't changed here... */
 24.1024  	err = talk_to_backend(dev, info);
 24.1025  	if (!err) {
 24.1026 -		if (blkif_vbds++ == 0)
 24.1027 -			blkif_recover();
 24.1028 +		blkif_recover(info);
 24.1029  	}
 24.1030  	return err;
 24.1031  }
 24.1032 @@ -1363,11 +1351,6 @@ static int __init xlblk_init(void)
 24.1033  {
 24.1034      int i;
 24.1035  
 24.1036 -    /* A grant for every ring slot, plus one for the ring itself. */
 24.1037 -    if (gnttab_alloc_grant_references(MAXIMUM_OUTSTANDING_BLOCK_REQS + 1,
 24.1038 -				      &gref_head, &gref_terminal) < 0)
 24.1039 -        return 1;
 24.1040 -
 24.1041      if ( (xen_start_info.flags & SIF_INITDOMAIN) ||
 24.1042           (xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
 24.1043          return 0;
 24.1044 @@ -1391,6 +1374,6 @@ static void blkif_completion(struct blk_
 24.1045  {
 24.1046      int i;
 24.1047      for ( i = 0; i < s->req.nr_segments; i++ )
 24.1048 -        gnttab_release_grant_reference(
 24.1049 -            &gref_head, blkif_gref_from_fas(s->req.frame_and_sects[i]));
 24.1050 +        gnttab_free_grant_reference(
 24.1051 +		blkif_gref_from_fas(s->req.frame_and_sects[i]));
 24.1052  }
    25.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Mon Aug 22 11:37:48 2005 -0700
    25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Tue Aug 23 12:03:21 2005 -0700
    25.3 @@ -46,6 +46,7 @@
    25.4  #include <linux/major.h>
    25.5  #include <linux/devfs_fs_kernel.h>
    25.6  #include <asm-xen/hypervisor.h>
    25.7 +#include <asm-xen/xenbus.h>
    25.8  #include <asm-xen/xen-public/xen.h>
    25.9  #include <asm-xen/xen-public/io/blkif.h>
   25.10  #include <asm-xen/xen-public/io/ring.h>
   25.11 @@ -79,11 +80,20 @@
   25.12  #define DPRINTK_IOCTL(_f, _a...) ((void)0)
   25.13  #endif
   25.14  
   25.15 -struct xlbd_type_info {
   25.16 -    int partn_shift;
   25.17 -    int disks_per_major;
   25.18 -    char *devname;
   25.19 -    char *diskname;
   25.20 +struct xlbd_type_info
   25.21 +{
   25.22 +	int partn_shift;
   25.23 +	int disks_per_major;
   25.24 +	char *devname;
   25.25 +	char *diskname;
   25.26 +};
   25.27 +
   25.28 +struct xlbd_major_info
   25.29 +{
   25.30 +	int major;
   25.31 +	int index;
   25.32 +	int usage;
   25.33 +	struct xlbd_type_info *type;
   25.34  };
   25.35  
   25.36  /*
   25.37 @@ -91,27 +101,28 @@ struct xlbd_type_info {
   25.38   * hang in private_data off the gendisk structure. We may end up
   25.39   * putting all kinds of interesting stuff here :-)
   25.40   */
   25.41 -struct xlbd_major_info {
   25.42 -    int major;
   25.43 -    int index;
   25.44 -    int usage;
   25.45 -    struct xlbd_type_info *type;
   25.46 +struct blkfront_info
   25.47 +{
   25.48 +	struct xenbus_device *xbdev;
   25.49 +	/* We watch the backend */
   25.50 +	struct xenbus_watch watch;
   25.51 +	dev_t dev;
   25.52 +	int vdevice;
   25.53 +	blkif_vdev_t handle;
   25.54 +	int connected;
   25.55 +	char *backend;
   25.56 +	int backend_id;
   25.57 +	int grant_id;
   25.58 +	blkif_front_ring_t ring;
   25.59 +	unsigned int evtchn;
   25.60 +	struct xlbd_major_info *mi;
   25.61 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   25.62 +	request_queue_t *rq;
   25.63 +#endif
   25.64 +	struct work_struct work;
   25.65 +	struct gnttab_free_callback callback;
   25.66  };
   25.67  
   25.68 -struct xlbd_disk_info {
   25.69 -    int xd_device;
   25.70 -    blkif_vdev_t handle;
   25.71 -    struct xlbd_major_info *mi;
   25.72 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   25.73 -    struct xlbd_disk_info  *next_waiting;
   25.74 -    request_queue_t        *rq;
   25.75 -#endif
   25.76 -};
   25.77 -
   25.78 -typedef struct xen_block {
   25.79 -    int usage;
   25.80 -} xen_block_t;
   25.81 -
   25.82  extern spinlock_t blkif_io_lock;
   25.83  
   25.84  extern int blkif_open(struct inode *inode, struct file *filep);
   25.85 @@ -123,7 +134,7 @@ extern int blkif_revalidate(dev_t dev);
   25.86  extern void do_blkif_request (request_queue_t *rq); 
   25.87  
   25.88  /* Virtual block-device subsystem. */
   25.89 -int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
   25.90 -	      u16 info, u16 sector_size);
   25.91 -void xlvbd_del(blkif_vdev_t handle);
   25.92 +int xlvbd_add(blkif_sector_t capacity, int device,
   25.93 +	      u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
   25.94 +void xlvbd_del(struct blkfront_info *info);
   25.95  #endif /* __XEN_DRIVERS_BLOCK_H__ */
    26.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Mon Aug 22 11:37:48 2005 -0700
    26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Tue Aug 23 12:03:21 2005 -0700
    26.3 @@ -43,325 +43,269 @@
    26.4  #define NUM_SCSI_MAJORS 9
    26.5  #define NUM_VBD_MAJORS 1
    26.6  
    26.7 -struct lvdisk
    26.8 -{
    26.9 -    blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
   26.10 -    blkif_vdev_t   handle;   /*  8: Device number (opaque 16 bit value). */
   26.11 -    u16            info;
   26.12 -    dev_t          dev;
   26.13 -    struct list_head list;
   26.14 -};
   26.15 -
   26.16  static struct xlbd_type_info xlbd_ide_type = {
   26.17 -    .partn_shift = 6,
   26.18 -    .disks_per_major = 2,
   26.19 -    .devname = "ide",
   26.20 -    .diskname = "hd",
   26.21 +	.partn_shift = 6,
   26.22 +	.disks_per_major = 2,
   26.23 +	.devname = "ide",
   26.24 +	.diskname = "hd",
   26.25  };
   26.26  
   26.27  static struct xlbd_type_info xlbd_scsi_type = {
   26.28 -    .partn_shift = 4,
   26.29 -    .disks_per_major = 16,
   26.30 -    .devname = "sd",
   26.31 -    .diskname = "sd",
   26.32 +	.partn_shift = 4,
   26.33 +	.disks_per_major = 16,
   26.34 +	.devname = "sd",
   26.35 +	.diskname = "sd",
   26.36  };
   26.37  
   26.38  static struct xlbd_type_info xlbd_vbd_type = {
   26.39 -    .partn_shift = 4,
   26.40 -    .disks_per_major = 16,
   26.41 -    .devname = "xvd",
   26.42 -    .diskname = "xvd",
   26.43 +	.partn_shift = 4,
   26.44 +	.disks_per_major = 16,
   26.45 +	.devname = "xvd",
   26.46 +	.diskname = "xvd",
   26.47  };
   26.48  
   26.49  static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
   26.50 -                                         NUM_VBD_MAJORS];
   26.51 +					  NUM_VBD_MAJORS];
   26.52  
   26.53 -#define XLBD_MAJOR_IDE_START    0
   26.54 -#define XLBD_MAJOR_SCSI_START   (NUM_IDE_MAJORS)
   26.55 -#define XLBD_MAJOR_VBD_START    (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
   26.56 +#define XLBD_MAJOR_IDE_START	0
   26.57 +#define XLBD_MAJOR_SCSI_START	(NUM_IDE_MAJORS)
   26.58 +#define XLBD_MAJOR_VBD_START	(NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
   26.59  
   26.60 -#define XLBD_MAJOR_IDE_RANGE    XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
   26.61 -#define XLBD_MAJOR_SCSI_RANGE   XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
   26.62 -#define XLBD_MAJOR_VBD_RANGE    XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
   26.63 +#define XLBD_MAJOR_IDE_RANGE	XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
   26.64 +#define XLBD_MAJOR_SCSI_RANGE	XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
   26.65 +#define XLBD_MAJOR_VBD_RANGE	XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
   26.66  
   26.67  /* Information about our VBDs. */
   26.68  #define MAX_VBDS 64
   26.69  static LIST_HEAD(vbds_list);
   26.70  
   26.71 -#define MAJOR_XEN(dev) ((dev)>>8)
   26.72 -#define MINOR_XEN(dev) ((dev) & 0xff)
   26.73 -
   26.74 -static struct block_device_operations xlvbd_block_fops = 
   26.75 +static struct block_device_operations xlvbd_block_fops =
   26.76  {
   26.77 -    .owner  = THIS_MODULE,
   26.78 -    .open  = blkif_open,
   26.79 -    .release = blkif_release,
   26.80 -    .ioctl  = blkif_ioctl,
   26.81 +	.owner = THIS_MODULE,
   26.82 +	.open = blkif_open,
   26.83 +	.release = blkif_release,
   26.84 +	.ioctl  = blkif_ioctl,
   26.85  };
   26.86  
   26.87  spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
   26.88  
   26.89 -static struct lvdisk *xlvbd_device_alloc(void)
   26.90 -{
   26.91 -    struct lvdisk *disk;
   26.92 -
   26.93 -    disk = kmalloc(sizeof(*disk), GFP_KERNEL);
   26.94 -    if (disk != NULL) {
   26.95 -        memset(disk, 0, sizeof(*disk));
   26.96 -        INIT_LIST_HEAD(&disk->list);
   26.97 -    }
   26.98 -    return disk;
   26.99 -}
  26.100 -
  26.101 -static void xlvbd_device_free(struct lvdisk *disk)
  26.102 -{
  26.103 -    list_del(&disk->list);
  26.104 -    kfree(disk);
  26.105 -}
  26.106 -
  26.107 -static struct xlbd_major_info *xlbd_alloc_major_info(
  26.108 -    int major, int minor, int index)
  26.109 +static struct xlbd_major_info *
  26.110 +xlbd_alloc_major_info(int major, int minor, int index)
  26.111  {
  26.112 -    struct xlbd_major_info *ptr;
  26.113 -
  26.114 -    ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
  26.115 -    if (ptr == NULL)
  26.116 -        return NULL;
  26.117 -
  26.118 -    memset(ptr, 0, sizeof(struct xlbd_major_info));
  26.119 -
  26.120 -    ptr->major = major;
  26.121 -
  26.122 -    switch (index) {
  26.123 -    case XLBD_MAJOR_IDE_RANGE:
  26.124 -        ptr->type = &xlbd_ide_type;
  26.125 -        ptr->index = index - XLBD_MAJOR_IDE_START;
  26.126 -        break;
  26.127 -    case XLBD_MAJOR_SCSI_RANGE:
  26.128 -        ptr->type = &xlbd_scsi_type;
  26.129 -        ptr->index = index - XLBD_MAJOR_SCSI_START;
  26.130 -        break;
  26.131 -    case XLBD_MAJOR_VBD_RANGE:
  26.132 -        ptr->type = &xlbd_vbd_type;
  26.133 -        ptr->index = index - XLBD_MAJOR_VBD_START;
  26.134 -        break;
  26.135 -    }
  26.136 -    
  26.137 -    printk("Registering block device major %i\n", ptr->major);
  26.138 -    if (register_blkdev(ptr->major, ptr->type->devname)) {
  26.139 -        WPRINTK("can't get major %d with name %s\n",
  26.140 -                ptr->major, ptr->type->devname);
  26.141 -        kfree(ptr);
  26.142 -        return NULL;
  26.143 -    }
  26.144 +	struct xlbd_major_info *ptr;
  26.145  
  26.146 -    devfs_mk_dir(ptr->type->devname);
  26.147 -    major_info[index] = ptr;
  26.148 -    return ptr;
  26.149 -}
  26.150 -
  26.151 -static struct xlbd_major_info *xlbd_get_major_info(int device)
  26.152 -{
  26.153 -    int major, minor, index;
  26.154 -
  26.155 -    major = MAJOR_XEN(device);
  26.156 -    minor = MINOR_XEN(device);
  26.157 -
  26.158 -    switch (major) {
  26.159 -    case IDE0_MAJOR: index = 0; break;
  26.160 -    case IDE1_MAJOR: index = 1; break;
  26.161 -    case IDE2_MAJOR: index = 2; break;
  26.162 -    case IDE3_MAJOR: index = 3; break;
  26.163 -    case IDE4_MAJOR: index = 4; break;
  26.164 -    case IDE5_MAJOR: index = 5; break;
  26.165 -    case IDE6_MAJOR: index = 6; break;
  26.166 -    case IDE7_MAJOR: index = 7; break;
  26.167 -    case IDE8_MAJOR: index = 8; break;
  26.168 -    case IDE9_MAJOR: index = 9; break;
  26.169 -    case SCSI_DISK0_MAJOR: index = 10; break;
  26.170 -    case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
  26.171 -        index = 11 + major - SCSI_DISK1_MAJOR;
  26.172 -        break;
  26.173 -    case SCSI_CDROM_MAJOR: index = 18; break;
  26.174 -    default: index = 19; break;
  26.175 -    }
  26.176 +	ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
  26.177 +	if (ptr == NULL)
  26.178 +		return NULL;
  26.179  
  26.180 -    return ((major_info[index] != NULL) ? major_info[index] :
  26.181 -            xlbd_alloc_major_info(major, minor, index));
  26.182 -}
  26.183 -
  26.184 -static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
  26.185 -{
  26.186 -    request_queue_t *rq;
  26.187 -
  26.188 -    rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
  26.189 -    if (rq == NULL)
  26.190 -        return -1;
  26.191 -
  26.192 -    elevator_init(rq, "noop");
  26.193 +	memset(ptr, 0, sizeof(struct xlbd_major_info));
  26.194  
  26.195 -    /* Hard sector size and max sectors impersonate the equiv. hardware. */
  26.196 -    blk_queue_hardsect_size(rq, sector_size);
  26.197 -    blk_queue_max_sectors(rq, 512);
  26.198 -
  26.199 -    /* Each segment in a request is up to an aligned page in size. */
  26.200 -    blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
  26.201 -    blk_queue_max_segment_size(rq, PAGE_SIZE);
  26.202 +	ptr->major = major;
  26.203  
  26.204 -    /* Ensure a merged request will fit in a single I/O ring slot. */
  26.205 -    blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
  26.206 -    blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
  26.207 +	switch (index) {
  26.208 +	case XLBD_MAJOR_IDE_RANGE:
  26.209 +		ptr->type = &xlbd_ide_type;
  26.210 +		ptr->index = index - XLBD_MAJOR_IDE_START;
  26.211 +		break;
  26.212 +	case XLBD_MAJOR_SCSI_RANGE:
  26.213 +		ptr->type = &xlbd_scsi_type;
  26.214 +		ptr->index = index - XLBD_MAJOR_SCSI_START;
  26.215 +		break;
  26.216 +	case XLBD_MAJOR_VBD_RANGE:
  26.217 +		ptr->type = &xlbd_vbd_type;
  26.218 +		ptr->index = index - XLBD_MAJOR_VBD_START;
  26.219 +		break;
  26.220 +	}
  26.221  
  26.222 -    /* Make sure buffer addresses are sector-aligned. */
  26.223 -    blk_queue_dma_alignment(rq, 511);
  26.224 +	printk("Registering block device major %i\n", ptr->major);
  26.225 +	if (register_blkdev(ptr->major, ptr->type->devname)) {
  26.226 +		WPRINTK("can't get major %d with name %s\n",
  26.227 +			ptr->major, ptr->type->devname);
  26.228 +		kfree(ptr);
  26.229 +		return NULL;
  26.230 +	}
  26.231  
  26.232 -    gd->queue = rq;
  26.233 -
  26.234 -    return 0;
  26.235 +	devfs_mk_dir(ptr->type->devname);
  26.236 +	major_info[index] = ptr;
  26.237 +	return ptr;
  26.238  }
  26.239  
  26.240 -static struct gendisk *xlvbd_alloc_gendisk(
  26.241 -    struct xlbd_major_info *mi, int minor, blkif_sector_t capacity,
  26.242 -    int device, blkif_vdev_t handle, u16 info, u16 sector_size)
  26.243 +static struct xlbd_major_info *
  26.244 +xlbd_get_major_info(int vdevice)
  26.245  {
  26.246 -    struct gendisk *gd;
  26.247 -    struct xlbd_disk_info *di;
  26.248 -    int nr_minors = 1;
  26.249 -
  26.250 -    di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
  26.251 -    if (di == NULL)
  26.252 -        return NULL;
  26.253 -    memset(di, 0, sizeof(*di));
  26.254 -    di->mi = mi;
  26.255 -    di->xd_device = device;
  26.256 -    di->handle = handle;
  26.257 -
  26.258 -    if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
  26.259 -        nr_minors = 1 << mi->type->partn_shift;
  26.260 -
  26.261 -    gd = alloc_disk(nr_minors);
  26.262 -    if (gd == NULL)
  26.263 -        goto out;
  26.264 +	struct xlbd_major_info *mi;
  26.265 +	int major, minor, index;
  26.266  
  26.267 -    if (nr_minors > 1)
  26.268 -        sprintf(gd->disk_name, "%s%c", mi->type->diskname,
  26.269 -                'a' + mi->index * mi->type->disks_per_major +
  26.270 -                    (minor >> mi->type->partn_shift));
  26.271 -    else
  26.272 -        sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
  26.273 -                'a' + mi->index * mi->type->disks_per_major +
  26.274 -                (minor >> mi->type->partn_shift),
  26.275 -                minor & ((1 << mi->type->partn_shift) - 1));
  26.276 -
  26.277 -    gd->major = mi->major;
  26.278 -    gd->first_minor = minor;
  26.279 -    gd->fops = &xlvbd_block_fops;
  26.280 -    gd->private_data = di;
  26.281 -    set_capacity(gd, capacity);
  26.282 +	major = BLKIF_MAJOR(vdevice);
  26.283 +	minor = BLKIF_MINOR(vdevice);
  26.284  
  26.285 -    if (xlvbd_init_blk_queue(gd, sector_size)) {
  26.286 -        del_gendisk(gd);
  26.287 -        goto out;
  26.288 -    }
  26.289 -
  26.290 -    di->rq = gd->queue;
  26.291 -
  26.292 -    if (info & VDISK_READONLY)
  26.293 -        set_disk_ro(gd, 1);
  26.294 +	switch (major) {
  26.295 +	case IDE0_MAJOR: index = 0; break;
  26.296 +	case IDE1_MAJOR: index = 1; break;
  26.297 +	case IDE2_MAJOR: index = 2; break;
  26.298 +	case IDE3_MAJOR: index = 3; break;
  26.299 +	case IDE4_MAJOR: index = 4; break;
  26.300 +	case IDE5_MAJOR: index = 5; break;
  26.301 +	case IDE6_MAJOR: index = 6; break;
  26.302 +	case IDE7_MAJOR: index = 7; break;
  26.303 +	case IDE8_MAJOR: index = 8; break;
  26.304 +	case IDE9_MAJOR: index = 9; break;
  26.305 +	case SCSI_DISK0_MAJOR: index = 10; break;
  26.306 +	case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
  26.307 +		index = 11 + major - SCSI_DISK1_MAJOR;
  26.308 +		break;
  26.309 +	case SCSI_CDROM_MAJOR: index = 18; break;
  26.310 +	default: index = 19; break;
  26.311 +	}
  26.312  
  26.313 -    if (info & VDISK_REMOVABLE)
  26.314 -        gd->flags |= GENHD_FL_REMOVABLE;
  26.315 -
  26.316 -    if (info & VDISK_CDROM)
  26.317 -        gd->flags |= GENHD_FL_CD;
  26.318 -
  26.319 -    add_disk(gd);
  26.320 -
  26.321 -    return gd;
  26.322 -
  26.323 -out:
  26.324 -    kfree(di);
  26.325 -    return NULL;
  26.326 +	mi = ((major_info[index] != NULL) ? major_info[index] :
  26.327 +	      xlbd_alloc_major_info(major, minor, index));
  26.328 +	mi->usage++;
  26.329 +	return mi;
  26.330  }
  26.331  
  26.332 -int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
  26.333 -	      u16 info, u16 sector_size)
  26.334 +static void
  26.335 +xlbd_put_major_info(struct xlbd_major_info *mi)
  26.336  {
  26.337 -    struct lvdisk *new;
  26.338 -    struct block_device *bd;
  26.339 -    struct gendisk *gd;
  26.340 -    struct xlbd_major_info *mi;
  26.341 -
  26.342 -    mi = xlbd_get_major_info(device);
  26.343 -    if (mi == NULL)
  26.344 -        return -EPERM;
  26.345 -
  26.346 -    new = xlvbd_device_alloc();
  26.347 -    if (new == NULL)
  26.348 -        return -ENOMEM;
  26.349 -    new->capacity = capacity;
  26.350 -    new->info = info;
  26.351 -    new->handle = handle;
  26.352 -    new->dev = MKDEV(MAJOR_XEN(device), MINOR_XEN(device));
  26.353 -
  26.354 -    bd = bdget(new->dev);
  26.355 -    if (bd == NULL)
  26.356 -        goto out;
  26.357 -    
  26.358 -    gd = xlvbd_alloc_gendisk(mi, MINOR_XEN(device), capacity, device, handle,
  26.359 -			     info, sector_size);
  26.360 -    if (gd == NULL)
  26.361 -        goto out_bd;
  26.362 -
  26.363 -    list_add(&new->list, &vbds_list);
  26.364 -out_bd:
  26.365 -    bdput(bd);
  26.366 -out:
  26.367 -    return 0;
  26.368 +	mi->usage--;
  26.369 +	/* XXX: release major if 0 */
  26.370  }
  26.371  
  26.372 -static int xlvbd_device_del(struct lvdisk *disk)
  26.373 +static int
  26.374 +xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
  26.375  {
  26.376 -    struct block_device *bd;
  26.377 -    struct gendisk *gd;
  26.378 -    struct xlbd_disk_info *di;
  26.379 -    int ret = 0, unused;
  26.380 -    request_queue_t *rq;
  26.381 -
  26.382 -    bd = bdget(disk->dev);
  26.383 -    if (bd == NULL)
  26.384 -        return -1;
  26.385 -
  26.386 -    gd = get_gendisk(disk->dev, &unused);
  26.387 -    di = gd->private_data;
  26.388 +	request_queue_t *rq;
  26.389  
  26.390 -#if 0 /* This is wrong: hda and hdb share same major, for example. */
  26.391 -    if (di->mi->usage != 0) {
  26.392 -        WPRINTK("disk removal failed: used [dev=%x]\n", disk->dev);
  26.393 -        ret = -1;
  26.394 -        goto out;
  26.395 -    }
  26.396 -#endif
  26.397 +	rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
  26.398 +	if (rq == NULL)
  26.399 +		return -1;
  26.400  
  26.401 -    rq = gd->queue;
  26.402 -    del_gendisk(gd);
  26.403 -    put_disk(gd);
  26.404 -    blk_cleanup_queue(rq);
  26.405 +	elevator_init(rq, "noop");
  26.406  
  26.407 -    xlvbd_device_free(disk);
  26.408 -    bdput(bd);
  26.409 -    return ret;
  26.410 +	/* Hard sector size and max sectors impersonate the equiv. hardware. */
  26.411 +	blk_queue_hardsect_size(rq, sector_size);
  26.412 +	blk_queue_max_sectors(rq, 512);
  26.413 +
  26.414 +	/* Each segment in a request is up to an aligned page in size. */
  26.415 +	blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
  26.416 +	blk_queue_max_segment_size(rq, PAGE_SIZE);
  26.417 +
  26.418 +	/* Ensure a merged request will fit in a single I/O ring slot. */
  26.419 +	blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
  26.420 +	blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
  26.421 +
  26.422 +	/* Make sure buffer addresses are sector-aligned. */
  26.423 +	blk_queue_dma_alignment(rq, 511);
  26.424 +
  26.425 +	gd->queue = rq;
  26.426 +
  26.427 +	return 0;
  26.428  }
  26.429  
  26.430 -void xlvbd_del(blkif_vdev_t handle)
  26.431 +static int
  26.432 +xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
  26.433 +		    u16 vdisk_info, u16 sector_size,
  26.434 +		    struct blkfront_info *info)
  26.435  {
  26.436 -	struct lvdisk *i;
  26.437 +	struct gendisk *gd;
  26.438 +	struct xlbd_major_info *mi;
  26.439 +	int nr_minors = 1;
  26.440 +	int err = -ENODEV;
  26.441  
  26.442 -	list_for_each_entry(i, &vbds_list, list) {
  26.443 -		if (i->handle == handle) {
  26.444 -			xlvbd_device_del(i);
  26.445 -			return;
  26.446 -		}
  26.447 +	mi = xlbd_get_major_info(vdevice);
  26.448 +	if (mi == NULL)
  26.449 +		goto out;
  26.450 +	info->mi = mi;
  26.451 +
  26.452 +	if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
  26.453 +		nr_minors = 1 << mi->type->partn_shift;
  26.454 +
  26.455 +	gd = alloc_disk(nr_minors);
  26.456 +	if (gd == NULL)
  26.457 +		goto out;
  26.458 +
  26.459 +	if (nr_minors > 1)
  26.460 +		sprintf(gd->disk_name, "%s%c", mi->type->diskname,
  26.461 +			'a' + mi->index * mi->type->disks_per_major +
  26.462 +			(minor >> mi->type->partn_shift));
  26.463 +	else
  26.464 +		sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
  26.465 +			'a' + mi->index * mi->type->disks_per_major +
  26.466 +			(minor >> mi->type->partn_shift),
  26.467 +			minor & ((1 << mi->type->partn_shift) - 1));
  26.468 +
  26.469 +	gd->major = mi->major;
  26.470 +	gd->first_minor = minor;
  26.471 +	gd->fops = &xlvbd_block_fops;
  26.472 +	gd->private_data = info;
  26.473 +	set_capacity(gd, capacity);
  26.474 +
  26.475 +	if (xlvbd_init_blk_queue(gd, sector_size)) {
  26.476 +		del_gendisk(gd);
  26.477 +		goto out;
  26.478  	}
  26.479 -	BUG();
  26.480 +
  26.481 +	info->rq = gd->queue;
  26.482 +
  26.483 +	if (vdisk_info & VDISK_READONLY)
  26.484 +		set_disk_ro(gd, 1);
  26.485 +
  26.486 +	if (vdisk_info & VDISK_REMOVABLE)
  26.487 +		gd->flags |= GENHD_FL_REMOVABLE;
  26.488 +
  26.489 +	if (vdisk_info & VDISK_CDROM)
  26.490 +		gd->flags |= GENHD_FL_CD;
  26.491 +
  26.492 +	add_disk(gd);
  26.493 +
  26.494 +	return 0;
  26.495 +
  26.496 + out:
  26.497 +	if (mi)
  26.498 +		xlbd_put_major_info(mi);
  26.499 +	return err;
  26.500  }
  26.501 +
  26.502 +int
  26.503 +xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info,
  26.504 +	  u16 sector_size, struct blkfront_info *info)
  26.505 +{
  26.506 +	struct block_device *bd;
  26.507 +	int err = 0;
  26.508 +
  26.509 +	info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
  26.510 +
  26.511 +	bd = bdget(info->dev);
  26.512 +	if (bd == NULL)
  26.513 +		return -ENODEV;
  26.514 +
  26.515 +	err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity, vdevice,
  26.516 +				  vdisk_info, sector_size, info);
  26.517 +
  26.518 +	bdput(bd);
  26.519 +	return err;
  26.520 +}
  26.521 +
  26.522 +void
  26.523 +xlvbd_del(struct blkfront_info *info)
  26.524 +{
  26.525 +	struct block_device *bd;
  26.526 +	struct gendisk *gd;
  26.527 +	int unused;
  26.528 +	request_queue_t *rq;
  26.529 +
  26.530 +	bd = bdget(info->dev);
  26.531 +	if (bd == NULL)
  26.532 +		return;
  26.533 +
  26.534 +	gd = get_gendisk(info->dev, &unused);
  26.535 +	rq = gd->queue;
  26.536 +
  26.537 +	del_gendisk(gd);
  26.538 +	put_disk(gd);
  26.539 +	xlbd_put_major_info(info->mi);
  26.540 +	info->mi = NULL;
  26.541 +	blk_cleanup_queue(rq);
  26.542 +
  26.543 +	bdput(bd);
  26.544 +}
    27.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Mon Aug 22 11:37:48 2005 -0700
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Aug 23 12:03:21 2005 -0700
    27.3 @@ -102,12 +102,12 @@ dump_packet(int tag, void *addr, u32 ap)
    27.4  #endif
    27.5  
    27.6  #ifdef CONFIG_XEN_NETDEV_GRANT_TX
    27.7 -static grant_ref_t gref_tx_head, gref_tx_terminal;
    27.8 +static grant_ref_t gref_tx_head;
    27.9  static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
   27.10  #endif
   27.11  
   27.12  #ifdef CONFIG_XEN_NETDEV_GRANT_RX
   27.13 -static grant_ref_t gref_rx_head, gref_rx_terminal;
   27.14 +static grant_ref_t gref_rx_head;
   27.15  static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
   27.16  #endif
   27.17  
   27.18 @@ -441,8 +441,8 @@ static void network_alloc_rx_buffers(str
   27.19          
   27.20          np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
   27.21  #ifdef CONFIG_XEN_NETDEV_GRANT_RX
   27.22 -        if (unlikely((ref = gnttab_claim_grant_reference(&gref_rx_head, 
   27.23 -                                                gref_rx_terminal)) < 0)) {
   27.24 +	ref = gnttab_claim_grant_reference(&gref_rx_head);
   27.25 +        if (unlikely(ref < 0)) {
   27.26              printk(KERN_ALERT "#### netfront can't claim rx reference\n");
   27.27              BUG();
   27.28          }
   27.29 @@ -537,8 +537,8 @@ static int network_start_xmit(struct sk_
   27.30  
   27.31      tx->id   = id;
   27.32  #ifdef CONFIG_XEN_NETDEV_GRANT_TX
   27.33 -    if (unlikely((ref = gnttab_claim_grant_reference(&gref_tx_head, 
   27.34 -                                                     gref_tx_terminal)) < 0)) {
   27.35 +    ref = gnttab_claim_grant_reference(&gref_tx_head);
   27.36 +    if (unlikely(ref < 0)) {
   27.37          printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
   27.38          BUG();
   27.39      }
   27.40 @@ -929,8 +929,7 @@ static void send_interface_connect(struc
   27.41      msg->handle = np->handle;
   27.42      msg->tx_shmem_frame = virt_to_mfn(np->tx);
   27.43  #ifdef CONFIG_XEN_NETDEV_GRANT_TX
   27.44 -    msg->tx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_tx_head, 
   27.45 -                                                            gref_tx_terminal);
   27.46 +    msg->tx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_tx_head);
   27.47      if(msg->tx_shmem_ref < 0) { 
   27.48          printk(KERN_ALERT "#### netfront can't claim tx_shmem reference\n");
   27.49          BUG();
   27.50 @@ -941,8 +940,7 @@ static void send_interface_connect(struc
   27.51  
   27.52      msg->rx_shmem_frame = virt_to_mfn(np->rx);
   27.53  #ifdef CONFIG_XEN_NETDEV_GRANT_RX
   27.54 -    msg->rx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_rx_head, 
   27.55 -                                                            gref_rx_terminal);
   27.56 +    msg->rx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_rx_head);
   27.57      if(msg->rx_shmem_ref < 0) {
   27.58          printk(KERN_ALERT "#### netfront can't claim rx_shmem reference\n");
   27.59          BUG();
   27.60 @@ -1420,7 +1418,7 @@ static int __init netif_init(void)
   27.61  #ifdef CONFIG_XEN_NETDEV_GRANT_TX
   27.62      /* A grant for every ring slot, plus one for the ring itself */
   27.63      if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE + 1,
   27.64 -                                      &gref_tx_head, &gref_tx_terminal) < 0) {
   27.65 +                                      &gref_tx_head) < 0) {
   27.66          printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
   27.67          return 1;
   27.68      }
   27.69 @@ -1429,7 +1427,7 @@ static int __init netif_init(void)
   27.70  #ifdef CONFIG_XEN_NETDEV_GRANT_RX
   27.71      /* A grant for every ring slot, plus one for the ring itself */
   27.72      if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE + 1,
   27.73 -                                      &gref_rx_head, &gref_rx_terminal) < 0) {
   27.74 +                                      &gref_rx_head) < 0) {
   27.75          printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
   27.76          return 1;
   27.77      }
   27.78 @@ -1457,10 +1455,10 @@ static int __init netif_init(void)
   27.79  static void netif_exit(void)
   27.80  {
   27.81  #ifdef CONFIG_XEN_NETDEV_GRANT_TX
   27.82 -    gnttab_free_grant_references(NETIF_TX_RING_SIZE + 1, gref_tx_head);
   27.83 +    gnttab_free_grant_references(gref_tx_head);
   27.84  #endif
   27.85  #ifdef CONFIG_XEN_NETDEV_GRANT_RX
   27.86 -    gnttab_free_grant_references(NETIF_RX_RING_SIZE + 1, gref_rx_head);
   27.87 +    gnttab_free_grant_references(gref_rx_head);
   27.88  #endif
   27.89  }
   27.90  
    28.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Aug 22 11:37:48 2005 -0700
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Tue Aug 23 12:03:21 2005 -0700
    28.3 @@ -167,7 +167,7 @@ static int privcmd_ioctl(struct inode *i
    28.4              if (ret)
    28.5                  goto batch_err;
    28.6  
    28.7 -            u.val = (mfn << PAGE_SHIFT) | pgprot_val(vma->vm_page_prot);
    28.8 +            u.val = pte_val_ma(pfn_pte_ma(mfn, vma->vm_page_prot));
    28.9              u.ptr = ptep;
   28.10  
   28.11              if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0) )
    29.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Mon Aug 22 11:37:48 2005 -0700
    29.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Tue Aug 23 12:03:21 2005 -0700
    29.3 @@ -60,9 +60,13 @@
    29.4  #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
    29.5  
    29.6  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
    29.7 +#define INVALID_P2M_ENTRY	(~0U)
    29.8 +#define FOREIGN_FRAME(m)	((m) | 0x80000000U)
    29.9  extern unsigned int *phys_to_machine_mapping;
   29.10 -#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
   29.11 -#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
   29.12 +#define pfn_to_mfn(pfn)	\
   29.13 +((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
   29.14 +#define mfn_to_pfn(mfn)	\
   29.15 +((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
   29.16  
   29.17  /* Definitions for machine and pseudophysical addresses. */
   29.18  #ifdef CONFIG_X86_PAE
    30.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Mon Aug 22 11:37:48 2005 -0700
    30.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Tue Aug 23 12:03:21 2005 -0700
    30.3 @@ -63,17 +63,15 @@ inline static void set_pte_at_sync(struc
    30.4   * 
    30.5   * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
    30.6   *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
    30.7 - *      require. In all the cases we care about, the high bit gets shifted out
    30.8 - *      (e.g., phys_to_machine()) so behaviour there is correct.
    30.9 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   30.10 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   30.11   */
   30.12 -#define INVALID_P2M_ENTRY (~0U)
   30.13 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
   30.14  #define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
   30.15  #define pte_pfn(_pte)							\
   30.16  ({									\
   30.17  	unsigned long mfn = pte_mfn(_pte);				\
   30.18  	unsigned long pfn = mfn_to_pfn(mfn);				\
   30.19 -	if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))		\
   30.20 +	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
   30.21  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
   30.22  	pfn;								\
   30.23  })
    31.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Mon Aug 22 11:37:48 2005 -0700
    31.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h	Tue Aug 23 12:03:21 2005 -0700
    31.3 @@ -150,15 +150,13 @@ static inline int pte_none(pte_t pte)
    31.4  	return !pte.pte_low && !pte.pte_high;
    31.5  }
    31.6  
    31.7 -#define INVALID_P2M_ENTRY (~0U)
    31.8 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
    31.9  #define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
   31.10  		        (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
   31.11  #define pte_pfn(_pte)                                                  \
   31.12  ({                                                                     \
   31.13         unsigned long mfn = pte_mfn(_pte);                              \
   31.14         unsigned long pfn = mfn_to_pfn(mfn);                            \
   31.15 -       if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))             \
   31.16 +       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
   31.17                 pfn = max_mapnr; /* special: force !pfn_valid() */      \
   31.18         pfn;                                                            \
   31.19  })
    32.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Mon Aug 22 11:37:48 2005 -0700
    32.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Tue Aug 23 12:03:21 2005 -0700
    32.3 @@ -62,9 +62,13 @@ void copy_page(void *, void *);
    32.4  #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
    32.5  
    32.6  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
    32.7 +#define INVALID_P2M_ENTRY	(~0U)
    32.8 +#define FOREIGN_FRAME(m)	((m) | 0x80000000U)
    32.9  extern u32 *phys_to_machine_mapping;
   32.10 -#define pfn_to_mfn(_pfn) ((unsigned long) phys_to_machine_mapping[(unsigned int)(_pfn)])
   32.11 -#define mfn_to_pfn(_mfn) ((unsigned long) machine_to_phys_mapping[(unsigned int)(_mfn)])
   32.12 +#define pfn_to_mfn(pfn)	\
   32.13 +((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
   32.14 +#define mfn_to_pfn(mfn)	\
   32.15 +((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
   32.16  
   32.17  /* Definitions for machine and pseudophysical addresses. */
   32.18  typedef unsigned long paddr_t;
    33.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Mon Aug 22 11:37:48 2005 -0700
    33.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Tue Aug 23 12:03:21 2005 -0700
    33.3 @@ -300,17 +300,15 @@ inline static void set_pte_at(struct mm_
    33.4   * 
    33.5   * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
    33.6   *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
    33.7 - *      require. In all the cases we care about, the high bit gets shifted out
    33.8 - *      (e.g., phys_to_machine()) so behaviour there is correct.
    33.9 + *      require. In all the cases we care about, the FOREIGN_FRAME bit is
   33.10 + *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
   33.11   */
   33.12 -#define INVALID_P2M_ENTRY (~0U)
   33.13 -#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
   33.14  #define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
   33.15  #define pte_pfn(_pte)							\
   33.16  ({									\
   33.17  	unsigned long mfn = pte_mfn(_pte);                              \
   33.18  	unsigned pfn = mfn_to_pfn(mfn);                                 \
   33.19 -	if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn))		\
   33.20 +	if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
   33.21  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
   33.22  	pfn;								\
   33.23  })
    34.1 --- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h	Mon Aug 22 11:37:48 2005 -0700
    34.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h	Tue Aug 23 12:03:21 2005 -0700
    34.3 @@ -19,54 +19,46 @@
    34.4  
    34.5  /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
    34.6  #define NR_GRANT_FRAMES 4
    34.7 -#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    34.8 -
    34.9 -int
   34.10 -gnttab_grant_foreign_access(
   34.11 -    domid_t domid, unsigned long frame, int readonly);
   34.12 -
   34.13 -void
   34.14 -gnttab_end_foreign_access(
   34.15 -    grant_ref_t ref, int readonly);
   34.16  
   34.17 -int
   34.18 -gnttab_grant_foreign_transfer(
   34.19 -    domid_t domid, unsigned long pfn);
   34.20 +struct gnttab_free_callback {
   34.21 +    struct gnttab_free_callback *next;
   34.22 +    void (*fn)(void *);
   34.23 +    void *arg;
   34.24 +    u16 count;
   34.25 +};
   34.26  
   34.27 -unsigned long
   34.28 -gnttab_end_foreign_transfer(
   34.29 -    grant_ref_t ref);
   34.30 +int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
   34.31 +				int readonly);
   34.32  
   34.33 -int
   34.34 -gnttab_query_foreign_access( 
   34.35 -    grant_ref_t ref );
   34.36 +void gnttab_end_foreign_access(grant_ref_t ref, int readonly);
   34.37 +
   34.38 +int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
   34.39 +
   34.40 +unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
   34.41 +
   34.42 +int gnttab_query_foreign_access(grant_ref_t ref);
   34.43  
   34.44  /*
   34.45   * operations on reserved batches of grant references
   34.46   */
   34.47 -int
   34.48 -gnttab_alloc_grant_references(
   34.49 -    u16 count, grant_ref_t *pprivate_head, grant_ref_t *private_terminal );
   34.50 -
   34.51 -void
   34.52 -gnttab_free_grant_references(
   34.53 -    u16 count, grant_ref_t private_head );
   34.54 -
   34.55 -int
   34.56 -gnttab_claim_grant_reference( grant_ref_t *pprivate_head, grant_ref_t terminal
   34.57 -);
   34.58 +int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head);
   34.59  
   34.60 -void
   34.61 -gnttab_release_grant_reference(
   34.62 -    grant_ref_t *private_head, grant_ref_t release );
   34.63 +void gnttab_free_grant_reference(grant_ref_t ref);
   34.64  
   34.65 -void
   34.66 -gnttab_grant_foreign_access_ref(
   34.67 -    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);
   34.68 +void gnttab_free_grant_references(grant_ref_t head);
   34.69  
   34.70 -void
   34.71 -gnttab_grant_foreign_transfer_ref(
   34.72 -    grant_ref_t, domid_t domid, unsigned long pfn);
   34.73 +int gnttab_claim_grant_reference(grant_ref_t *pprivate_head);
   34.74  
   34.75 +void gnttab_release_grant_reference(grant_ref_t *private_head,
   34.76 +				    grant_ref_t release);
   34.77 +
   34.78 +void gnttab_request_free_callback(struct gnttab_free_callback *callback,
   34.79 +				  void (*fn)(void *), void *arg, u16 count);
   34.80 +
   34.81 +void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
   34.82 +				     unsigned long frame, int readonly);
   34.83 +
   34.84 +void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
   34.85 +				       unsigned long pfn);
   34.86  
   34.87  #endif /* __ASM_GNTTAB_H__ */
    35.1 --- a/tools/Makefile	Mon Aug 22 11:37:48 2005 -0700
    35.2 +++ b/tools/Makefile	Tue Aug 23 12:03:21 2005 -0700
    35.3 @@ -14,6 +14,7 @@ SUBDIRS += xcutils
    35.4  SUBDIRS += firmware
    35.5  SUBDIRS += security
    35.6  SUBDIRS += console
    35.7 +SUBDIRS += xenstat
    35.8  
    35.9  .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
   35.10  
    36.1 --- a/tools/Rules.mk	Mon Aug 22 11:37:48 2005 -0700
    36.2 +++ b/tools/Rules.mk	Tue Aug 23 12:03:21 2005 -0700
    36.3 @@ -6,6 +6,7 @@ XEN_XC             = $(XEN_ROOT)/tools/p
    36.4  XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
    36.5  XEN_XCS            = $(XEN_ROOT)/tools/xcs
    36.6  XEN_XENSTORE       = $(XEN_ROOT)/tools/xenstore
    36.7 +XEN_LIBXENSTAT     = $(XEN_ROOT)/tools/xenstat/libxenstat/src
    36.8  
    36.9  ifeq ($(XEN_TARGET_ARCH),x86_32)
   36.10  CFLAGS  += -m32 -march=i686
    37.1 --- a/tools/python/xen/xm/main.py	Mon Aug 22 11:37:48 2005 -0700
    37.2 +++ b/tools/python/xen/xm/main.py	Tue Aug 23 12:03:21 2005 -0700
    37.3 @@ -49,6 +49,7 @@ xm common subcommands:
    37.4      restore <File>          create a domain from a saved state file
    37.5      save <DomId> <File>     save domain state (and config) to file
    37.6      shutdown <DomId>        shutdown a domain
    37.7 +    top                     monitor system and domains in real-time
    37.8      unpause <DomId>         unpause a paused domain
    37.9  
   37.10  For a complete list of subcommands run 'xm help --long'
   37.11 @@ -87,6 +88,7 @@ xm full list of subcommands:
   37.12      dmesg   [--clear]         read or clear Xen's message buffer
   37.13      info                      get information about the xen host
   37.14      log                       print the xend log
   37.15 +    top                       monitor system and domains in real-time
   37.16  
   37.17    Scheduler Commands:
   37.18      bvt <options>             set BVT scheduler parameters
   37.19 @@ -457,6 +459,9 @@ def xm_console(args):
   37.20      os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
   37.21      console = sxp.child(info, "console")
   37.22  
   37.23 +def xm_top(args):
   37.24 +    os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop'])
   37.25 +
   37.26  def xm_dmesg(args):
   37.27      
   37.28      gopts = Opts(use="""[-c|--clear]
   37.29 @@ -545,6 +550,8 @@ def xm_block_destroy(args):
   37.30  commands = {
   37.31      # console commands
   37.32      "console": xm_console,
   37.33 +    # xenstat commands
   37.34 +    "top": xm_top,
   37.35      # domain commands
   37.36      "domid": xm_domid,
   37.37      "domname": xm_domname,
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/xenstat/Makefile	Tue Aug 23 12:03:21 2005 -0700
    38.3 @@ -0,0 +1,13 @@
    38.4 +XEN_ROOT = ../..
    38.5 +include $(XEN_ROOT)/tools/Rules.mk
    38.6 +
    38.7 +SUBDIRS :=
    38.8 +SUBDIRS += libxenstat
    38.9 +SUBDIRS += xentop
   38.10 +
   38.11 +.PHONY: all install clean
   38.12 +
   38.13 +all install clean:
   38.14 +	@set -e; for subdir in $(SUBDIRS); do \
   38.15 +		$(MAKE) -C $$subdir $@; \
   38.16 +	done
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/tools/xenstat/libxenstat/COPYING	Tue Aug 23 12:03:21 2005 -0700
    39.3 @@ -0,0 +1,510 @@
    39.4 +
    39.5 +                  GNU LESSER GENERAL PUBLIC LICENSE
    39.6 +                       Version 2.1, February 1999
    39.7 +
    39.8 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    39.9 +	51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   39.10 + Everyone is permitted to copy and distribute verbatim copies
   39.11 + of this license document, but changing it is not allowed.
   39.12 +
   39.13 +[This is the first released version of the Lesser GPL.  It also counts
   39.14 + as the successor of the GNU Library Public License, version 2, hence
   39.15 + the version number 2.1.]
   39.16 +
   39.17 +                            Preamble
   39.18 +
   39.19 +  The licenses for most software are designed to take away your
   39.20 +freedom to share and change it.  By contrast, the GNU General Public
   39.21 +Licenses are intended to guarantee your freedom to share and change
   39.22 +free software--to make sure the software is free for all its users.
   39.23 +
   39.24 +  This license, the Lesser General Public License, applies to some
   39.25 +specially designated software packages--typically libraries--of the
   39.26 +Free Software Foundation and other authors who decide to use it.  You
   39.27 +can use it too, but we suggest you first think carefully about whether
   39.28 +this license or the ordinary General Public License is the better
   39.29 +strategy to use in any particular case, based on the explanations
   39.30 +below.
   39.31 +
   39.32 +  When we speak of free software, we are referring to freedom of use,
   39.33 +not price.  Our General Public Licenses are designed to make sure that
   39.34 +you have the freedom to distribute copies of free software (and charge
   39.35 +for this service if you wish); that you receive source code or can get
   39.36 +it if you want it; that you can change the software and use pieces of
   39.37 +it in new free programs; and that you are informed that you can do
   39.38 +these things.
   39.39 +
   39.40 +  To protect your rights, we need to make restrictions that forbid
   39.41 +distributors to deny you these rights or to ask you to surrender these
   39.42 +rights.  These restrictions translate to certain responsibilities for
   39.43 +you if you distribute copies of the library or if you modify it.
   39.44 +
   39.45 +  For example, if you distribute copies of the library, whether gratis
   39.46 +or for a fee, you must give the recipients all the rights that we gave
   39.47 +you.  You must make sure that they, too, receive or can get the source
   39.48 +code.  If you link other code with the library, you must provide
   39.49 +complete object files to the recipients, so that they can relink them
   39.50 +with the library after making changes to the library and recompiling
   39.51 +it.  And you must show them these terms so they know their rights.
   39.52 +
   39.53 +  We protect your rights with a two-step method: (1) we copyright the
   39.54 +library, and (2) we offer you this license, which gives you legal
   39.55 +permission to copy, distribute and/or modify the library.
   39.56 +
   39.57 +  To protect each distributor, we want to make it very clear that
   39.58 +there is no warranty for the free library.  Also, if the library is
   39.59 +modified by someone else and passed on, the recipients should know
   39.60 +that what they have is not the original version, so that the original
   39.61 +author's reputation will not be affected by problems that might be
   39.62 +introduced by others.
   39.63 +
   39.64 +  Finally, software patents pose a constant threat to the existence of
   39.65 +any free program.  We wish to make sure that a company cannot
   39.66 +effectively restrict the users of a free program by obtaining a
   39.67 +restrictive license from a patent holder.  Therefore, we insist that
   39.68 +any patent license obtained for a version of the library must be
   39.69 +consistent with the full freedom of use specified in this license.
   39.70 +
   39.71 +  Most GNU software, including some libraries, is covered by the
   39.72 +ordinary GNU General Public License.  This license, the GNU Lesser
   39.73 +General Public License, applies to certain designated libraries, and
   39.74 +is quite different from the ordinary General Public License.  We use
   39.75 +this license for certain libraries in order to permit linking those
   39.76 +libraries into non-free programs.
   39.77 +
   39.78 +  When a program is linked with a library, whether statically or using
   39.79 +a shared library, the combination of the two is legally speaking a
   39.80 +combined work, a derivative of the original library.  The ordinary
   39.81 +General Public License therefore permits such linking only if the
   39.82 +entire combination fits its criteria of freedom.  The Lesser General
   39.83 +Public License permits more lax criteria for linking other code with
   39.84 +the library.
   39.85 +
   39.86 +  We call this license the "Lesser" General Public License because it
   39.87 +does Less to protect the user's freedom than the ordinary General
   39.88 +Public License.  It also provides other free software developers Less
   39.89 +of an advantage over competing non-free programs.  These disadvantages
   39.90 +are the reason we use the ordinary General Public License for many
   39.91 +libraries.  However, the Lesser license provides advantages in certain
   39.92 +special circumstances.
   39.93 +
   39.94 +  For example, on rare occasions, there may be a special need to
   39.95 +encourage the widest possible use of a certain library, so that it
   39.96 +becomes a de-facto standard.  To achieve this, non-free programs must
   39.97 +be allowed to use the library.  A more frequent case is that a free
   39.98 +library does the same job as widely used non-free libraries.  In this
   39.99 +case, there is little to gain by limiting the free library to free
  39.100 +software only, so we use the Lesser General Public License.
  39.101 +
  39.102 +  In other cases, permission to use a particular library in non-free
  39.103 +programs enables a greater number of people to use a large body of
  39.104 +free software.  For example, permission to use the GNU C Library in
  39.105 +non-free programs enables many more people to use the whole GNU
  39.106 +operating system, as well as its variant, the GNU/Linux operating
  39.107 +system.
  39.108 +
  39.109 +  Although the Lesser General Public License is Less protective of the
  39.110 +users' freedom, it does ensure that the user of a program that is
  39.111 +linked with the Library has the freedom and the wherewithal to run
  39.112 +that program using a modified version of the Library.
  39.113 +
  39.114 +  The precise terms and conditions for copying, distribution and
  39.115 +modification follow.  Pay close attention to the difference between a
  39.116 +"work based on the library" and a "work that uses the library".  The
  39.117 +former contains code derived from the library, whereas the latter must
  39.118 +be combined with the library in order to run.
  39.119 +
  39.120 +                  GNU LESSER GENERAL PUBLIC LICENSE
  39.121 +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  39.122 +
  39.123 +  0. This License Agreement applies to any software library or other
  39.124 +program which contains a notice placed by the copyright holder or
  39.125 +other authorized party saying it may be distributed under the terms of
  39.126 +this Lesser General Public License (also called "this License").
  39.127 +Each licensee is addressed as "you".
  39.128 +
  39.129 +  A "library" means a collection of software functions and/or data
  39.130 +prepared so as to be conveniently linked with application programs
  39.131 +(which use some of those functions and data) to form executables.
  39.132 +
  39.133 +  The "Library", below, refers to any such software library or work
  39.134 +which has been distributed under these terms.  A "work based on the
  39.135 +Library" means either the Library or any derivative work under
  39.136 +copyright law: that is to say, a work containing the Library or a
  39.137 +portion of it, either verbatim or with modifications and/or translated
  39.138 +straightforwardly into another language.  (Hereinafter, translation is
  39.139 +included without limitation in the term "modification".)
  39.140 +
  39.141 +  "Source code" for a work means the preferred form of the work for
  39.142 +making modifications to it.  For a library, complete source code means
  39.143 +all the source code for all modules it contains, plus any associated
  39.144 +interface definition files, plus the scripts used to control
  39.145 +compilation and installation of the library.
  39.146 +
  39.147 +  Activities other than copying, distribution and modification are not
  39.148 +covered by this License; they are outside its scope.  The act of
  39.149 +running a program using the Library is not restricted, and output from
  39.150 +such a program is covered only if its contents constitute a work based
  39.151 +on the Library (independent of the use of the Library in a tool for
  39.152 +writing it).  Whether that is true depends on what the Library does
  39.153 +and what the program that uses the Library does.
  39.154 +
  39.155 +  1. You may copy and distribute verbatim copies of the Library's
  39.156 +complete source code as you receive it, in any medium, provided that
  39.157 +you conspicuously and appropriately publish on each copy an
  39.158 +appropriate copyright notice and disclaimer of warranty; keep intact
  39.159 +all the notices that refer to this License and to the absence of any
  39.160 +warranty; and distribute a copy of this License along with the
  39.161 +Library.
  39.162 +
  39.163 +  You may charge a fee for the physical act of transferring a copy,
  39.164 +and you may at your option offer warranty protection in exchange for a
  39.165 +fee.
  39.166 +
  39.167 +  2. You may modify your copy or copies of the Library or any portion
  39.168 +of it, thus forming a work based on the Library, and copy and
  39.169 +distribute such modifications or work under the terms of Section 1
  39.170 +above, provided that you also meet all of these conditions:
  39.171 +
  39.172 +    a) The modified work must itself be a software library.
  39.173 +
  39.174 +    b) You must cause the files modified to carry prominent notices
  39.175 +    stating that you changed the files and the date of any change.
  39.176 +
  39.177 +    c) You must cause the whole of the work to be licensed at no
  39.178 +    charge to all third parties under the terms of this License.
  39.179 +
  39.180 +    d) If a facility in the modified Library refers to a function or a
  39.181 +    table of data to be supplied by an application program that uses
  39.182 +    the facility, other than as an argument passed when the facility
  39.183 +    is invoked, then you must make a good faith effort to ensure that,
  39.184 +    in the event an application does not supply such function or
  39.185 +    table, the facility still operates, and performs whatever part of
  39.186 +    its purpose remains meaningful.
  39.187 +
  39.188 +    (For example, a function in a library to compute square roots has
  39.189 +    a purpose that is entirely well-defined independent of the
  39.190 +    application.  Therefore, Subsection 2d requires that any
  39.191 +    application-supplied function or table used by this function must
  39.192 +    be optional: if the application does not supply it, the square
  39.193 +    root function must still compute square roots.)
  39.194 +
  39.195 +These requirements apply to the modified work as a whole.  If
  39.196 +identifiable sections of that work are not derived from the Library,
  39.197 +and can be reasonably considered independent and separate works in
  39.198 +themselves, then this License, and its terms, do not apply to those
  39.199 +sections when you distribute them as separate works.  But when you
  39.200 +distribute the same sections as part of a whole which is a work based
  39.201 +on the Library, the distribution of the whole must be on the terms of
  39.202 +this License, whose permissions for other licensees extend to the
  39.203 +entire whole, and thus to each and every part regardless of who wrote
  39.204 +it.
  39.205 +
  39.206 +Thus, it is not the intent of this section to claim rights or contest
  39.207 +your rights to work written entirely by you; rather, the intent is to
  39.208 +exercise the right to control the distribution of derivative or
  39.209 +collective works based on the Library.
  39.210 +
  39.211 +In addition, mere aggregation of another work not based on the Library
  39.212 +with the Library (or with a work based on the Library) on a volume of
  39.213 +a storage or distribution medium does not bring the other work under
  39.214 +the scope of this License.
  39.215 +
  39.216 +  3. You may opt to apply the terms of the ordinary GNU General Public
  39.217 +License instead of this License to a given copy of the Library.  To do
  39.218 +this, you must alter all the notices that refer to this License, so
  39.219 +that they refer to the ordinary GNU General Public License, version 2,
  39.220 +instead of to this License.  (If a newer version than version 2 of the
  39.221 +ordinary GNU General Public License has appeared, then you can specify
  39.222 +that version instead if you wish.)  Do not make any other change in
  39.223 +these notices.
  39.224 +
  39.225 +  Once this change is made in a given copy, it is irreversible for
  39.226 +that copy, so the ordinary GNU General Public License applies to all
  39.227 +subsequent copies and derivative works made from that copy.
  39.228 +
  39.229 +  This option is useful when you wish to copy part of the code of
  39.230 +the Library into a program that is not a library.
  39.231 +
  39.232 +  4. You may copy and distribute the Library (or a portion or
  39.233 +derivative of it, under Section 2) in object code or executable form
  39.234 +under the terms of Sections 1 and 2 above provided that you accompany
  39.235 +it with the complete corresponding machine-readable source code, which
  39.236 +must be distributed under the terms of Sections 1 and 2 above on a
  39.237 +medium customarily used for software interchange.
  39.238 +
  39.239 +  If distribution of object code is made by offering access to copy
  39.240 +from a designated place, then offering equivalent access to copy the
  39.241 +source code from the same place satisfies the requirement to
  39.242 +distribute the source code, even though third parties are not
  39.243 +compelled to copy the source along with the object code.
  39.244 +
  39.245 +  5. A program that contains no derivative of any portion of the
  39.246 +Library, but is designed to work with the Library by being compiled or
  39.247 +linked with it, is called a "work that uses the Library".  Such a
  39.248 +work, in isolation, is not a derivative work of the Library, and
  39.249 +therefore falls outside the scope of this License.
  39.250 +
  39.251 +  However, linking a "work that uses the Library" with the Library
  39.252 +creates an executable that is a derivative of the Library (because it
  39.253 +contains portions of the Library), rather than a "work that uses the
  39.254 +library".  The executable is therefore covered by this License.
  39.255 +Section 6 states terms for distribution of such executables.
  39.256 +
  39.257 +  When a "work that uses the Library" uses material from a header file
  39.258 +that is part of the Library, the object code for the work may be a
  39.259 +derivative work of the Library even though the source code is not.
  39.260 +Whether this is true is especially significant if the work can be
  39.261 +linked without the Library, or if the work is itself a library.  The
  39.262 +threshold for this to be true is not precisely defined by law.
  39.263 +
  39.264 +  If such an object file uses only numerical parameters, data
  39.265 +structure layouts and accessors, and small macros and small inline
  39.266 +functions (ten lines or less in length), then the use of the object
  39.267 +file is unrestricted, regardless of whether it is legally a derivative
  39.268 +work.  (Executables containing this object code plus portions of the
  39.269 +Library will still fall under Section 6.)
  39.270 +
  39.271 +  Otherwise, if the work is a derivative of the Library, you may
  39.272 +distribute the object code for the work under the terms of Section 6.
  39.273 +Any executables containing that work also fall under Section 6,
  39.274 +whether or not they are linked directly with the Library itself.
  39.275 +
  39.276 +  6. As an exception to the Sections above, you may also combine or
  39.277 +link a "work that uses the Library" with the Library to produce a
  39.278 +work containing portions of the Library, and distribute that work
  39.279 +under terms of your choice, provided that the terms permit
  39.280 +modification of the work for the customer's own use and reverse
  39.281 +engineering for debugging such modifications.
  39.282 +
  39.283 +  You must give prominent notice with each copy of the work that the
  39.284 +Library is used in it and that the Library and its use are covered by
  39.285 +this License.  You must supply a copy of this License.  If the work
  39.286 +during execution displays copyright notices, you must include the
  39.287 +copyright notice for the Library among them, as well as a reference
  39.288 +directing the user to the copy of this License.  Also, you must do one
  39.289 +of these things:
  39.290 +
  39.291 +    a) Accompany the work with the complete corresponding
  39.292 +    machine-readable source code for the Library including whatever
  39.293 +    changes were used in the work (which must be distributed under
  39.294 +    Sections 1 and 2 above); and, if the work is an executable linked
  39.295 +    with the Library, with the complete machine-readable "work that
  39.296 +    uses the Library", as object code and/or source code, so that the
  39.297 +    user can modify the Library and then relink to produce a modified
  39.298 +    executable containing the modified Library.  (It is understood
  39.299 +    that the user who changes the contents of definitions files in the
  39.300 +    Library will not necessarily be able to recompile the application
  39.301 +    to use the modified definitions.)
  39.302 +
  39.303 +    b) Use a suitable shared library mechanism for linking with the
  39.304 +    Library.  A suitable mechanism is one that (1) uses at run time a
  39.305 +    copy of the library already present on the user's computer system,
  39.306 +    rather than copying library functions into the executable, and (2)
  39.307 +    will operate properly with a modified version of the library, if
  39.308 +    the user installs one, as long as the modified version is
  39.309 +    interface-compatible with the version that the work was made with.
  39.310 +
  39.311 +    c) Accompany the work with a written offer, valid for at least
  39.312 +    three years, to give the same user the materials specified in
  39.313 +    Subsection 6a, above, for a charge no more than the cost of
  39.314 +    performing this distribution.
  39.315 +
  39.316 +    d) If distribution of the work is made by offering access to copy
  39.317 +    from a designated place, offer equivalent access to copy the above
  39.318 +    specified materials from the same place.
  39.319 +
  39.320 +    e) Verify that the user has already received a copy of these
  39.321 +    materials or that you have already sent this user a copy.
  39.322 +
  39.323 +  For an executable, the required form of the "work that uses the
  39.324 +Library" must include any data and utility programs needed for
  39.325 +reproducing the executable from it.  However, as a special exception,
  39.326 +the materials to be distributed need not include anything that is
  39.327 +normally distributed (in either source or binary form) with the major
  39.328 +components (compiler, kernel, and so on) of the operating system on
  39.329 +which the executable runs, unless that component itself accompanies
  39.330 +the executable.
  39.331 +
  39.332 +  It may happen that this requirement contradicts the license
  39.333 +restrictions of other proprietary libraries that do not normally
  39.334 +accompany the operating system.  Such a contradiction means you cannot
  39.335 +use both them and the Library together in an executable that you
  39.336 +distribute.
  39.337 +
  39.338 +  7. You may place library facilities that are a work based on the
  39.339 +Library side-by-side in a single library together with other library
  39.340 +facilities not covered by this License, and distribute such a combined
  39.341 +library, provided that the separate distribution of the work based on
  39.342 +the Library and of the other library facilities is otherwise
  39.343 +permitted, and provided that you do these two things:
  39.344 +
  39.345 +    a) Accompany the combined library with a copy of the same work
  39.346 +    based on the Library, uncombined with any other library
  39.347 +    facilities.  This must be distributed under the terms of the
  39.348 +    Sections above.
  39.349 +
  39.350 +    b) Give prominent notice with the combined library of the fact
  39.351 +    that part of it is a work based on the Library, and explaining
  39.352 +    where to find the accompanying uncombined form of the same work.
  39.353 +
  39.354 +  8. You may not copy, modify, sublicense, link with, or distribute
  39.355 +the Library except as expressly provided under this License.  Any
  39.356 +attempt otherwise to copy, modify, sublicense, link with, or
  39.357 +distribute the Library is void, and will automatically terminate your
  39.358 +rights under this License.  However, parties who have received copies,
  39.359 +or rights, from you under this License will not have their licenses
  39.360 +terminated so long as such parties remain in full compliance.
  39.361 +
  39.362 +  9. You are not required to accept this License, since you have not
  39.363 +signed it.  However, nothing else grants you permission to modify or
  39.364 +distribute the Library or its derivative works.  These actions are
  39.365 +prohibited by law if you do not accept this License.  Therefore, by
  39.366 +modifying or distributing the Library (or any work based on the
  39.367 +Library), you indicate your acceptance of this License to do so, and
  39.368 +all its terms and conditions for copying, distributing or modifying
  39.369 +the Library or works based on it.
  39.370 +
  39.371 +  10. Each time you redistribute the Library (or any work based on the
  39.372 +Library), the recipient automatically receives a license from the
  39.373 +original licensor to copy, distribute, link with or modify the Library
  39.374 +subject to these terms and conditions.  You may not impose any further
  39.375 +restrictions on the recipients' exercise of the rights granted herein.
  39.376 +You are not responsible for enforcing compliance by third parties with
  39.377 +this License.
  39.378 +
  39.379 +  11. If, as a consequence of a court judgment or allegation of patent
  39.380 +infringement or for any other reason (not limited to patent issues),
  39.381 +conditions are imposed on you (whether by court order, agreement or
  39.382 +otherwise) that contradict the conditions of this License, they do not
  39.383 +excuse you from the conditions of this License.  If you cannot
  39.384 +distribute so as to satisfy simultaneously your obligations under this
  39.385 +License and any other pertinent obligations, then as a consequence you
  39.386 +may not distribute the Library at all.  For example, if a patent
  39.387 +license would not permit royalty-free redistribution of the Library by
  39.388 +all those who receive copies directly or indirectly through you, then
  39.389 +the only way you could satisfy both it and this License would be to
  39.390 +refrain entirely from distribution of the Library.
  39.391 +
  39.392 +If any portion of this section is held invalid or unenforceable under
  39.393 +any particular circumstance, the balance of the section is intended to
  39.394 +apply, and the section as a whole is intended to apply in other
  39.395 +circumstances.
  39.396 +
  39.397 +It is not the purpose of this section to induce you to infringe any
  39.398 +patents or other property right claims or to contest validity of any
  39.399 +such claims; this section has the sole purpose of protecting the
  39.400 +integrity of the free software distribution system which is
  39.401 +implemented by public license practices.  Many people have made
  39.402 +generous contributions to the wide range of software distributed
  39.403 +through that system in reliance on consistent application of that
  39.404 +system; it is up to the author/donor to decide if he or she is willing
  39.405 +to distribute software through any other system and a licensee cannot
  39.406 +impose that choice.
  39.407 +
  39.408 +This section is intended to make thoroughly clear what is believed to
  39.409 +be a consequence of the rest of this License.
  39.410 +
  39.411 +  12. If the distribution and/or use of the Library is restricted in
  39.412 +certain countries either by patents or by copyrighted interfaces, the
  39.413 +original copyright holder who places the Library under this License
  39.414 +may add an explicit geographical distribution limitation excluding those
  39.415 +countries, so that distribution is permitted only in or among
  39.416 +countries not thus excluded.  In such case, this License incorporates
  39.417 +the limitation as if written in the body of this License.
  39.418 +
  39.419 +  13. The Free Software Foundation may publish revised and/or new
  39.420 +versions of the Lesser General Public License from time to time.
  39.421 +Such new versions will be similar in spirit to the present version,
  39.422 +but may differ in detail to address new problems or concerns.
  39.423 +
  39.424 +Each version is given a distinguishing version number.  If the Library
  39.425 +specifies a version number of this License which applies to it and
  39.426 +"any later version", you have the option of following the terms and
  39.427 +conditions either of that version or of any later version published by
  39.428 +the Free Software Foundation.  If the Library does not specify a
  39.429 +license version number, you may choose any version ever published by
  39.430 +the Free Software Foundation.
  39.431 +
  39.432 +  14. If you wish to incorporate parts of the Library into other free
  39.433 +programs whose distribution conditions are incompatible with these,
  39.434 +write to the author to ask for permission.  For software which is
  39.435 +copyrighted by the Free Software Foundation, write to the Free
  39.436 +Software Foundation; we sometimes make exceptions for this.  Our
  39.437 +decision will be guided by the two goals of preserving the free status
  39.438 +of all derivatives of our free software and of promoting the sharing
  39.439 +and reuse of software generally.
  39.440 +
  39.441 +                            NO WARRANTY
  39.442 +
  39.443 +  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
  39.444 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
  39.445 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
  39.446 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
  39.447 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
  39.448 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39.449 +PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
  39.450 +LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
  39.451 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  39.452 +
  39.453 +  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
  39.454 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
  39.455 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
  39.456 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
  39.457 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
  39.458 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
  39.459 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
  39.460 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
  39.461 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  39.462 +DAMAGES.
  39.463 +
  39.464 +                     END OF TERMS AND CONDITIONS
  39.465 +
  39.466 +           How to Apply These Terms to Your New Libraries
  39.467 +
  39.468 +  If you develop a new library, and you want it to be of the greatest
  39.469 +possible use to the public, we recommend making it free software that
  39.470 +everyone can redistribute and change.  You can do so by permitting
  39.471 +redistribution under these terms (or, alternatively, under the terms
  39.472 +of the ordinary General Public License).
  39.473 +
  39.474 +  To apply these terms, attach the following notices to the library.
  39.475 +It is safest to attach them to the start of each source file to most
  39.476 +effectively convey the exclusion of warranty; and each file should
  39.477 +have at least the "copyright" line and a pointer to where the full
  39.478 +notice is found.
  39.479 +
  39.480 +
  39.481 +    <one line to give the library's name and a brief idea of what it does.>
  39.482 +    Copyright (C) <year>  <name of author>
  39.483 +
  39.484 +    This library is free software; you can redistribute it and/or
  39.485 +    modify it under the terms of the GNU Lesser General Public
  39.486 +    License as published by the Free Software Foundation; either
  39.487 +    version 2.1 of the License, or (at your option) any later version.
  39.488 +
  39.489 +    This library is distributed in the hope that it will be useful,
  39.490 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
  39.491 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  39.492 +    Lesser General Public License for more details.
  39.493 +
  39.494 +    You should have received a copy of the GNU Lesser General Public
  39.495 +    License along with this library; if not, write to the Free Software
  39.496 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  39.497 +
  39.498 +Also add information on how to contact you by electronic and paper mail.
  39.499 +
  39.500 +You should also get your employer (if you work as a programmer) or
  39.501 +your school, if any, to sign a "copyright disclaimer" for the library,
  39.502 +if necessary.  Here is a sample; alter the names:
  39.503 +
  39.504 +  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  39.505 +  library `Frob' (a library for tweaking knobs) written by James
  39.506 +  Random Hacker.
  39.507 +
  39.508 +  <signature of Ty Coon>, 1 April 1990
  39.509 +  Ty Coon, President of Vice
  39.510 +
  39.511 +That's all there is to it!
  39.512 +
  39.513 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/xenstat/libxenstat/Makefile	Tue Aug 23 12:03:21 2005 -0700
    40.3 @@ -0,0 +1,142 @@
    40.4 +# libxenstat: statistics-collection library for Xen
    40.5 +# Copyright (C) International Business Machines Corp., 2005
    40.6 +# Author: Josh Triplett <josht@us.ibm.com>
    40.7 +# 
    40.8 +# This library is free software; you can redistribute it and/or
    40.9 +# modify it under the terms of the GNU Lesser General Public
   40.10 +# License as published by the Free Software Foundation; either
   40.11 +# version 2.1 of the License, or (at your option) any later version.
   40.12 +# 
   40.13 +# This library is distributed in the hope that it will be useful,
   40.14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   40.16 +# Lesser General Public License for more details.
   40.17 +
   40.18 +XEN_ROOT=../../..
   40.19 +include $(XEN_ROOT)/tools/Rules.mk
   40.20 +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
   40.21 +
   40.22 +INSTALL         = install
   40.23 +INSTALL_PROG    = $(INSTALL) -m0755 -D
   40.24 +INSTALL_DATA    = $(INSTALL) -m0644 -D
   40.25 +
   40.26 +prefix=/usr
   40.27 +includedir=$(prefix)/include
   40.28 +libdir=$(prefix)/lib
   40.29 +
   40.30 +LDCONFIG=ldconfig
   40.31 +MAKE_LINK=ln -sf
   40.32 +
   40.33 +MAJOR=0
   40.34 +MINOR=0
   40.35 +
   40.36 +LIB=src/libxenstat.a
   40.37 +SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
   40.38 +SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
   40.39 +OBJECTS=src/xenstat.o src/xen-interface.o
   40.40 +SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR)
   40.41 +
   40.42 +WARN_FLAGS=-Wall -Werror
   40.43 +
   40.44 +CFLAGS+=-Isrc
   40.45 +CFLAGS+=-I$(XEN_ROOT)/xen/include/public
   40.46 +CFLAGS+=-I$(LINUX_ROOT)/include/asm-xen/linux-public/
   40.47 +LDFLAGS+=-Lsrc
   40.48 +
   40.49 +all: $(LIB)
   40.50 +
   40.51 +$(LIB): $(OBJECTS)
   40.52 +	$(AR) rc $@ $^
   40.53 +	$(RANLIB) $@
   40.54 +
   40.55 +$(SHLIB): $(OBJECTS)
   40.56 +	$(CC) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS)
   40.57 +
   40.58 +src/xenstat.o: src/xenstat.c src/xenstat.h src/xen-interface.h
   40.59 +	$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
   40.60 +
   40.61 +src/xen-interface.o: src/xen-interface.c src/xen-interface.h
   40.62 +	$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
   40.63 +
   40.64 +src/libxenstat.so.$(MAJOR): $(LIB)
   40.65 +	$(MAKE_LINK) $(<F) $@
   40.66 +
   40.67 +src/libxenstat.so: src/libxenstat.so.$(MAJOR)
   40.68 +	$(MAKE_LINK) $(<F) $@
   40.69 +
   40.70 +install: all
   40.71 +#install: all
   40.72 +#	$(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h
   40.73 +#	$(INSTALL_PROG) $(LIB) $(DESTDIR)$(libdir)/libxenstat.a
   40.74 +#	$(INSTALL_PROG) $(SHLIB) \
   40.75 +#	                $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR)
   40.76 +#	$(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \
   40.77 +#	             $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR)
   40.78 +#	$(MAKE_LINK) libxenstat.so.$(MAJOR) \
   40.79 +#	             $(DESTDIR)$(libdir)/libxenstat.so
   40.80 +#	-$(LDCONFIG)
   40.81 +
   40.82 +PYLIB=bindings/swig/python/_xenstat.so
   40.83 +PYMOD=bindings/swig/python/xenstat.py
   40.84 +PYSRC=bindings/swig/python/_xenstat.c
   40.85 +PERLLIB=bindings/swig/perl/xenstat.so
   40.86 +PERLMOD=bindings/swig/perl/xenstat.pm
   40.87 +PERLSRC=bindings/swig/perl/xenstat.c
   40.88 +BINDINGS=$(PYLIB) $(PYMOD) $(PERLLIB) $(PERLMOD)
   40.89 +BINDINGSRC=$(PYSRC) $(PERLSRC)
   40.90 +
   40.91 +# The all-bindings target builds all the language bindings
   40.92 +all-bindings: perl-bindings python-bindings
   40.93 +
   40.94 +# The install-bindings target installs all the language bindings
   40.95 +install-bindings: install-perl-bindings install-python-bindings
   40.96 +
   40.97 +$(BINDINGS): $(SHLIB) $(SHLIB_LINKS) src/xenstat.h
   40.98 +
   40.99 +SWIG_FLAGS=-module xenstat -Isrc
  40.100 +
  40.101 +# Python bindings
  40.102 +PYTHON_VERSION=2.3
  40.103 +PYTHON_FLAGS=-I/usr/include/python$(PYTHON_VERSION) -lpython$(PYTHON_VERSION)
  40.104 +$(PYSRC) $(PYMOD): bindings/swig/xenstat.i
  40.105 +	swig -python $(SWIG_FLAGS) -outdir $(@D) -o $(PYSRC) $<
  40.106 +
  40.107 +$(PYLIB): $(PYSRC)
  40.108 +	$(CC) $(CFLAGS) $(LDFLAGS) $(PYTHON_FLAGS) -shared -lxenstat -o $@ $<
  40.109 +
  40.110 +python-bindings: $(PYLIB) $(PYMOD)
  40.111 +
  40.112 +pythonlibdir=$(prefix)/lib/python$(PYTHON_VERSION)/site-packages
  40.113 +install-python-bindings: $(PYLIB) $(PYMOD)
  40.114 +	$(INSTALL_PROG) $(PYLIB) $(DESTDIR)$(pythonlibdir)/_xenstat.so
  40.115 +	$(INSTALL_PROG) $(PYMOD) $(DESTDIR)$(pythonlibdir)/xenstat.py
  40.116 +
  40.117 +ifeq ($(XENSTAT_PYTHON_BINDINGS),y)
  40.118 +all: python-bindings
  40.119 +install: install-python-bindings
  40.120 +endif
  40.121 +
  40.122 +# Perl bindings
  40.123 +PERL_FLAGS=`perl -MConfig -e 'print "$$Config{ccflags} -I$$Config{archlib}/CORE";'`
  40.124 +$(PERLSRC) $(PERLMOD): bindings/swig/xenstat.i
  40.125 +	swig -perl $(SWIG_FLAGS) -outdir $(@D) -o $(PERLSRC) $<
  40.126 +
  40.127 +$(PERLLIB): $(PERLSRC)
  40.128 +	$(CC) $(CFLAGS) $(LDFLAGS) $(PERL_FLAGS) -shared -lxenstat -o $@ $<
  40.129 +
  40.130 +perl-bindings: $(PERLLIB) $(PERLMOD)
  40.131 +
  40.132 +perllibdir=$(prefix)/lib/perl5
  40.133 +perlmoddir=$(prefix)/share/perl5
  40.134 +install-perl-bindings: $(PERLLIB) $(PERLMOD)
  40.135 +	$(INSTALL_PROG) $(PERLLIB) $(DESTDIR)$(perllibdir)/xenstat.so
  40.136 +	$(INSTALL_PROG) $(PERLMOD) $(DESTDIR)$(perlmoddir)/xenstat.pm
  40.137 +
  40.138 +ifeq ($(XENSTAT_PERL_BINDINGS),y)
  40.139 +all: perl-bindings
  40.140 +install: install-perl-bindings
  40.141 +endif
  40.142 +
  40.143 +clean:
  40.144 +	rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS) \
  40.145 +	      $(BINDINGS) $(BINDINGSRC)
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tools/xenstat/libxenstat/bindings/swig/perl/.empty	Tue Aug 23 12:03:21 2005 -0700
    41.3 @@ -0,0 +1,1 @@
    41.4 +This directory is empty; this file is included to prevent version control systems from removing the directory.
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/tools/xenstat/libxenstat/bindings/swig/python/.empty	Tue Aug 23 12:03:21 2005 -0700
    42.3 @@ -0,0 +1,1 @@
    42.4 +This directory is empty; this file is included to prevent version control systems from removing the directory.
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/xenstat/libxenstat/bindings/swig/xenstat.i	Tue Aug 23 12:03:21 2005 -0700
    43.3 @@ -0,0 +1,8 @@
    43.4 +%module xenstat_swig
    43.5 +%{
    43.6 +/* Includes the header in the wrapper code */
    43.7 +#include "xenstat.h"
    43.8 +%}
    43.9 +
   43.10 +/* Parse the header file to generate wrappers */
   43.11 +%include "xenstat.h"
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tools/xenstat/libxenstat/src/xen-interface.c	Tue Aug 23 12:03:21 2005 -0700
    44.3 @@ -0,0 +1,204 @@
    44.4 +/* xen-interface.c
    44.5 + *
    44.6 + * Copyright (C) International Business Machines Corp., 2005
    44.7 + * Authors: Josh Triplett <josht@us.ibm.com>
    44.8 + *          Judy Fischbach <jfisch@us.ibm.com>
    44.9 + *
   44.10 + * This library is free software; you can redistribute it and/or
   44.11 + * modify it under the terms of the GNU Lesser General Public
   44.12 + * License as published by the Free Software Foundation; either
   44.13 + * version 2.1 of the License, or (at your option) any later version.
   44.14 + *
   44.15 + * This library is distributed in the hope that it will be useful,
   44.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
   44.18 + * Lesser General Public License for more details.
   44.19 + */
   44.20 +
   44.21 +#include "xen-interface.h"
   44.22 +#include <fcntl.h>
   44.23 +#include <sys/ioctl.h>
   44.24 +#include <sys/mman.h>
   44.25 +#include <stdio.h>
   44.26 +#include <stdlib.h>
   44.27 +#include <string.h>
   44.28 +#include <unistd.h>
   44.29 +#include "version.h"
   44.30 +#include "privcmd.h"
   44.31 +#include "xen.h"
   44.32 +
   44.33 +struct xi_handle {
   44.34 +	int fd;
   44.35 +};
   44.36 +
   44.37 +/* Initialize for xen-interface.  Returns a handle to be used with subsequent
   44.38 + * calls to the xen-interface functions or NULL if an error occurs. */
   44.39 +xi_handle *xi_init()
   44.40 +{
   44.41 +	xi_handle *handle;
   44.42 +
   44.43 +	handle = (xi_handle *)calloc(1, sizeof(xi_handle));
   44.44 +	if (handle == NULL)
   44.45 +		return NULL;
   44.46 +
   44.47 +	handle->fd = open("/proc/xen/privcmd", O_RDWR);
   44.48 +	if (handle->fd < 0) {
   44.49 +		perror("Couldn't open /proc/xen/privcmd");
   44.50 +		free(handle);
   44.51 +		return NULL;
   44.52 +	}
   44.53 +
   44.54 +	return handle;
   44.55 +}
   44.56 +
   44.57 +/* Release the handle to libxc, free resources, etc. */
   44.58 +void xi_uninit(xi_handle *handle)
   44.59 +{
   44.60 +	close (handle->fd);
   44.61 +	free (handle);
   44.62 +}
   44.63 +
   44.64 +/* Make simple xen version hypervisor calls */
   44.65 +static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
   44.66 +{
   44.67 +	privcmd_hypercall_t privcmd;
   44.68 +	multicall_entry_t multicall[2];
   44.69 +	int ret = 0;
   44.70 +
   44.71 +	/* set up for doing hypercall */
   44.72 +	privcmd.op = __HYPERVISOR_multicall; 
   44.73 +	privcmd.arg[0] = (unsigned long)multicall;
   44.74 +	privcmd.arg[1] = 2;
   44.75 +
   44.76 +	/* first one to get xen version number */
   44.77 +	multicall[0].op = __HYPERVISOR_xen_version;
   44.78 +	multicall[0].args[0] = (unsigned long)XENVER_version;
   44.79 +
   44.80 +	/* second to get xen version flag */
   44.81 +	multicall[1].op = __HYPERVISOR_xen_version; 
   44.82 +	multicall[1].args[0] = (unsigned long)XENVER_extraversion;
   44.83 +	multicall[1].args[1] = (unsigned long)ver;
   44.84 +
   44.85 +	if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
   44.86 +		perror("Failed to mlock privcmd structure");
   44.87 +		return -1;
   44.88 +	}
   44.89 +
   44.90 +	if (mlock( multicall, sizeof(multicall_entry_t)) < 0) {
   44.91 +		perror("Failed to mlock multicall_entry structure");
   44.92 +		munlock( &multicall, sizeof(multicall_entry_t));
   44.93 +		return -1;
   44.94 +	}
   44.95 +
   44.96 +	if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
   44.97 +		perror("Hypercall failed");
   44.98 +		ret = -1;
   44.99 +	}
  44.100 +
  44.101 +	*vnum = multicall[0].result;
  44.102 +
  44.103 +	munlock( &privcmd, sizeof(privcmd_hypercall_t));
  44.104 +	munlock( &multicall, sizeof(multicall_entry_t));
  44.105 +
  44.106 +	return ret;
  44.107 +}
  44.108 +
  44.109 +/* Make Xen Dom0 op hypervisor call */
  44.110 +static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op, int dom_opcode)
  44.111 +{
  44.112 +	privcmd_hypercall_t privcmd;
  44.113 +	int ret = 0;
  44.114 +
  44.115 +	/* set up for doing hypercall */
  44.116 +	privcmd.op = __HYPERVISOR_dom0_op;
  44.117 +	privcmd.arg[0] = (unsigned long)dom_op;
  44.118 +	dom_op->cmd = dom_opcode;
  44.119 +	dom_op->interface_version = DOM0_INTERFACE_VERSION;
  44.120 +
  44.121 +	if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
  44.122 +		perror("Failed to mlock privcmd structure");
  44.123 +		return -1;
  44.124 +	}
  44.125 +
  44.126 +	if (mlock( dom_op, sizeof(dom0_op_t)) < 0) {
  44.127 +		perror("Failed to mlock dom0_op structure");
  44.128 +		munlock( &privcmd, sizeof(privcmd_hypercall_t));
  44.129 +		return -1;
  44.130 +	}
  44.131 +
  44.132 +	if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
  44.133 +		perror("Hypercall failed");
  44.134 +		ret = -1;
  44.135 +	}
  44.136 +
  44.137 +	munlock( &privcmd, sizeof(privcmd_hypercall_t));
  44.138 +	munlock( dom_op, sizeof(dom0_op_t));
  44.139 +
  44.140 +	return ret;
  44.141 +}
  44.142 +
  44.143 +/* Obtain domain data from dom0 */
  44.144 +int xi_get_physinfo(xi_handle *handle, dom0_physinfo_t *physinfo)
  44.145 +{
  44.146 +	dom0_op_t op;
  44.147 +
  44.148 +	if (xi_make_dom0_op(handle, &op, DOM0_PHYSINFO) < 0) {
  44.149 +		perror("DOM0_PHYSINFO Hypercall failed");
  44.150 +		return -1;
  44.151 +	}
  44.152 +
  44.153 +	*physinfo = op.u.physinfo;
  44.154 +	return 0;
  44.155 +}
  44.156 +
  44.157 +/* Obtain domain data from dom0 */
  44.158 +int xi_get_domaininfolist(xi_handle *handle, dom0_getdomaininfo_t *info,
  44.159 +                          unsigned int first_domain, unsigned int max_domains)
  44.160 +{
  44.161 +	dom0_op_t op;
  44.162 +	op.u.getdomaininfolist.first_domain = first_domain;
  44.163 +	op.u.getdomaininfolist.max_domains = max_domains;
  44.164 +	op.u.getdomaininfolist.buffer = info;
  44.165 +
  44.166 +	if (mlock( info, max_domains * sizeof(dom0_getdomaininfo_t)) < 0) {
  44.167 +		perror("Failed to mlock domaininfo array");
  44.168 +		return -1;
  44.169 +	}
  44.170 +
  44.171 +	if (xi_make_dom0_op(handle, &op, DOM0_GETDOMAININFOLIST) < 0) {
  44.172 +		perror("DOM0_GETDOMAININFOLIST Hypercall failed");
  44.173 +		return -1;
  44.174 +	}
  44.175 +
  44.176 +	return op.u.getdomaininfolist.num_domains;
  44.177 +}
  44.178 +
  44.179 +/* Returns cpu usage data from dom0 */
  44.180 +long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain,
  44.181 +                            unsigned int vcpu)
  44.182 +{
  44.183 +	dom0_op_t op;
  44.184 +	op.u.getvcpucontext.domain = domain;
  44.185 +	op.u.getvcpucontext.vcpu = vcpu;
  44.186 +	op.u.getvcpucontext.ctxt = NULL;
  44.187 +
  44.188 +	if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUCONTEXT) < 0) {
  44.189 +		perror("DOM0_GETVCPUCONTEXT Hypercall failed");
  44.190 +		return -1;
  44.191 +	}
  44.192 +
  44.193 +	return op.u.getvcpucontext.cpu_time;
  44.194 +}
  44.195 +
  44.196 +/* gets xen version information from hypervisor */
  44.197 +int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver) 
  44.198 +{
  44.199 +
  44.200 +        /* gets the XENVER_version and XENVER_extraversion */
  44.201 +	if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {; 
  44.202 +		perror("XEN VERSION Hypercall failed");
  44.203 +		return -1;
  44.204 +	}
  44.205 +
  44.206 +	return 0;
  44.207 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/tools/xenstat/libxenstat/src/xen-interface.h	Tue Aug 23 12:03:21 2005 -0700
    45.3 @@ -0,0 +1,53 @@
    45.4 +/* xen-interface.h
    45.5 + *
    45.6 + * Copyright (C) International Business Machines Corp., 2005
    45.7 + * Authors: Josh Triplett <josht@us.ibm.com>
    45.8 + *          Judy Fischbach <jfisch@us.ibm.com>
    45.9 + *
   45.10 + * This library is free software; you can redistribute it and/or
   45.11 + * modify it under the terms of the GNU Lesser General Public
   45.12 + * License as published by the Free Software Foundation; either
   45.13 + * version 2.1 of the License, or (at your option) any later version.
   45.14 + *
   45.15 + * This library is distributed in the hope that it will be useful,
   45.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   45.18 + * Lesser General Public License for more details.
   45.19 + */
   45.20 +
   45.21 +#include <stdint.h>
   45.22 +
   45.23 +typedef int8_t   s8;
   45.24 +typedef int16_t  s16;
   45.25 +typedef int32_t  s32;
   45.26 +typedef int64_t  s64;
   45.27 +typedef uint8_t  u8;
   45.28 +typedef uint16_t u16;
   45.29 +typedef uint32_t u32;
   45.30 +typedef uint64_t u64;
   45.31 +
   45.32 +#include "dom0_ops.h"
   45.33 +#include "version.h"
   45.34 +
   45.35 +/* Opaque handles */
   45.36 +typedef struct xi_handle xi_handle;
   45.37 +
   45.38 +/* Initialize for xen-interface.  Returns a handle to be used with subsequent
   45.39 + * calls to the xen-interface functions or NULL if an error occurs. */
   45.40 +xi_handle *xi_init();
   45.41 +
   45.42 +/* Release the handle to libxc, free resources, etc. */
   45.43 +void xi_uninit(xi_handle *handle);
   45.44 +
   45.45 +/* Obtain xen version information from hypervisor */
   45.46 +int xi_get_xen_version(xi_handle *, long *vnum, xen_extraversion_t *ver);
   45.47 +
   45.48 +/* Obtain physinfo data from dom0 */
   45.49 +int xi_get_physinfo(xi_handle *, dom0_physinfo_t *);
   45.50 +
   45.51 +/* Obtain domain data from dom0 */
   45.52 +int xi_get_domaininfolist(xi_handle *, dom0_getdomaininfo_t *, unsigned int,
   45.53 +                          unsigned int);
   45.54 +
   45.55 +/* Returns cpu usage data from dom0 */
   45.56 +long long xi_get_vcpu_usage(xi_handle *, unsigned int, unsigned int);
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Tue Aug 23 12:03:21 2005 -0700
    46.3 @@ -0,0 +1,640 @@
    46.4 +/* libxenstat: statistics-collection library for Xen
    46.5 + * Copyright (C) International Business Machines Corp., 2005
    46.6 + * Authors: Josh Triplett <josht@us.ibm.com>
    46.7 + *          Judy Fischbach <jfisch@us.ibm.com>
    46.8 + *          David Hendricks <dhendrix@us.ibm.com>
    46.9 + *
   46.10 + * This library is free software; you can redistribute it and/or
   46.11 + * modify it under the terms of the GNU Lesser General Public
   46.12 + * License as published by the Free Software Foundation; either
   46.13 + * version 2.1 of the License, or (at your option) any later version.
   46.14 + *
   46.15 + * This library is distributed in the hope that it will be useful,
   46.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   46.18 + * Lesser General Public License for more details.
   46.19 + */
   46.20 +
   46.21 +#include <limits.h>
   46.22 +#include <stdlib.h>
   46.23 +#include <stdio.h>
   46.24 +#include <string.h>
   46.25 +#include <unistd.h>
   46.26 +#include <xen-interface.h>
   46.27 +#include "xenstat.h"
   46.28 +#include "version.h"
   46.29 +
   46.30 +/*
   46.31 + * Types
   46.32 + */
   46.33 +struct xenstat_handle {
   46.34 +	xi_handle *xihandle;
   46.35 +	int page_size;
   46.36 +	FILE *procnetdev;
   46.37 +};
   46.38 +
   46.39 +#define SHORT_ASC_LEN 5 		/* length of 65535 */
   46.40 +#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
   46.41 +
   46.42 +struct xenstat_node {
   46.43 +	unsigned int flags;
   46.44 +	unsigned long long cpu_hz;
   46.45 +	unsigned int num_cpus;
   46.46 +	unsigned long long tot_mem;
   46.47 +	unsigned long long free_mem;
   46.48 +	unsigned int num_domains;
   46.49 +	char xen_version[VERSION_SIZE]; /* xen version running on this node */
   46.50 +	xenstat_domain *domains;	/* Array of length num_domains */
   46.51 +};
   46.52 +
   46.53 +struct xenstat_domain {
   46.54 +	unsigned int id;
   46.55 +	unsigned int state;
   46.56 +	unsigned long long cpu_ns;
   46.57 +	unsigned int num_vcpus;
   46.58 +	xenstat_vcpu *vcpus;		/* Array of length num_vcpus */
   46.59 +	unsigned long long cur_mem;	/* Current memory reservation */
   46.60 +	unsigned long long max_mem;	/* Total memory allowed */
   46.61 +	unsigned int ssid;
   46.62 +	unsigned int num_networks;
   46.63 +	xenstat_network *networks;	/* Array of length num_networks */
   46.64 +};
   46.65 +
   46.66 +struct xenstat_vcpu {
   46.67 +	unsigned long long ns;
   46.68 +};
   46.69 +
   46.70 +struct xenstat_network {
   46.71 +	unsigned int id;
   46.72 +	/* Received */
   46.73 +	unsigned long long rbytes;
   46.74 +	unsigned long long rpackets;
   46.75 +	unsigned long long rerrs;
   46.76 +	unsigned long long rdrop;
   46.77 +	/* Transmitted */
   46.78 +	unsigned long long tbytes;
   46.79 +	unsigned long long tpackets;
   46.80 +	unsigned long long terrs;
   46.81 +	unsigned long long tdrop;
   46.82 +};
   46.83 +
   46.84 +/*
   46.85 + * Data-collection types
   46.86 + */
   46.87 +/* Called to collect the information for the node and all the domains on
   46.88 + * it. When called, the domain information has already been collected. */
   46.89 +typedef int (*xenstat_collect_func)(xenstat_handle * handle,
   46.90 +				    xenstat_node * node);
   46.91 +/* Called to free the information collected by the collect function.  The free
   46.92 + * function will only be called on a xenstat_node if that node includes
   46.93 + * information collected by the corresponding collector. */
   46.94 +typedef void (*xenstat_free_func)(xenstat_node * node);
   46.95 +/* Called to free any information stored in the handle.  Note the lack of a
   46.96 + * matching init function; the collect functions should initialize on first
   46.97 + * use.  Also, the uninit function must handle the case that the collector has
   46.98 + * never been initialized. */
   46.99 +typedef void (*xenstat_uninit_func)(xenstat_handle * handle);
  46.100 +typedef struct xenstat_collector {
  46.101 +	unsigned int flag;
  46.102 +	xenstat_collect_func collect;
  46.103 +	xenstat_free_func free;
  46.104 +	xenstat_uninit_func uninit;
  46.105 +} xenstat_collector;
  46.106 +
  46.107 +static int  xenstat_collect_vcpus(xenstat_handle * handle,
  46.108 +				  xenstat_node * node);
  46.109 +static int  xenstat_collect_networks(xenstat_handle * handle,
  46.110 +				    xenstat_node * node);
  46.111 +static void xenstat_free_vcpus(xenstat_node * node);
  46.112 +static void xenstat_free_networks(xenstat_node * node);
  46.113 +static void xenstat_uninit_vcpus(xenstat_handle * handle);
  46.114 +static void xenstat_uninit_networks(xenstat_handle * handle);
  46.115 +
  46.116 +static xenstat_collector collectors[] = {
  46.117 +	{ XENSTAT_VCPU, xenstat_collect_vcpus,
  46.118 +	  xenstat_free_vcpus, xenstat_uninit_vcpus },
  46.119 +	{ XENSTAT_NETWORK, xenstat_collect_networks,
  46.120 +	  xenstat_free_networks, xenstat_uninit_networks }
  46.121 +};
  46.122 +
  46.123 +#define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
  46.124 +
  46.125 +/*
  46.126 + * libxenstat API
  46.127 + */
  46.128 +xenstat_handle *xenstat_init()
  46.129 +{
  46.130 +	xenstat_handle *handle;
  46.131 +
  46.132 +	handle = (xenstat_handle *) calloc(1, sizeof(xenstat_handle));
  46.133 +	if (handle == NULL)
  46.134 +		return NULL;
  46.135 +
  46.136 +#if defined(PAGESIZE)
  46.137 +	handle->page_size = PAGESIZE;
  46.138 +#elif defined(PAGE_SIZE)
  46.139 +	handle->page_size = PAGE_SIZE;
  46.140 +#else
  46.141 +	handle->page_size = sysconf(_SC_PAGE_SIZE);
  46.142 +	if (handle->page_size < 0) {
  46.143 +		perror("Failed to retrieve page size.");
  46.144 +		free(handle);
  46.145 +		return NULL;
  46.146 +	}
  46.147 +#endif
  46.148 +
  46.149 +	handle->xihandle = xi_init();
  46.150 +	if (handle->xihandle == NULL) {
  46.151 +		perror("xi_init");
  46.152 +		free(handle);
  46.153 +		return NULL;
  46.154 +	}
  46.155 +
  46.156 +	return handle;
  46.157 +}
  46.158 +
  46.159 +void xenstat_uninit(xenstat_handle * handle)
  46.160 +{
  46.161 +	unsigned int i;
  46.162 +	if (handle) {
  46.163 +		for (i = 0; i < NUM_COLLECTORS; i++)
  46.164 +			collectors[i].uninit(handle);
  46.165 +		xi_uninit(handle->xihandle);
  46.166 +		free(handle);
  46.167 +	}
  46.168 +}
  46.169 +
  46.170 +xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags)
  46.171 +{
  46.172 +#define DOMAIN_CHUNK_SIZE 256
  46.173 +	xenstat_node *node;
  46.174 +	dom0_physinfo_t physinfo;
  46.175 +	xen_extraversion_t version;
  46.176 +	long vnum = 0; 
  46.177 +	dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE];
  46.178 +	unsigned int num_domains, new_domains;
  46.179 +	unsigned int i;
  46.180 +
  46.181 +	/* Create the node */
  46.182 +	node = (xenstat_node *) calloc(1, sizeof(xenstat_node));
  46.183 +	if (node == NULL)
  46.184 +		return NULL;
  46.185 +
  46.186 +	/* Get information about the physical system */
  46.187 +	if (xi_get_physinfo(handle->xihandle, &physinfo) < 0) {
  46.188 +		free(node);
  46.189 +		return NULL;
  46.190 +	}
  46.191 +
  46.192 +	/* Get the xen version number and xen version tag */
  46.193 +	if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) {
  46.194 +		free(node); 
  46.195 +		return NULL;
  46.196 +	} 
  46.197 +	snprintf(node->xen_version, VERSION_SIZE,
  46.198 +		"%ld.%ld%s\n", ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, (char *)version); 
  46.199 +
  46.200 +	node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL;
  46.201 +	node->num_cpus =
  46.202 +	    (physinfo.threads_per_core * physinfo.cores_per_socket *
  46.203 +	     physinfo.sockets_per_node * physinfo.nr_nodes);
  46.204 +	node->tot_mem = ((unsigned long long)physinfo.total_pages)
  46.205 +	    * handle->page_size;
  46.206 +	node->free_mem = ((unsigned long long)physinfo.free_pages)
  46.207 +	    * handle->page_size;
  46.208 +
  46.209 +	/* malloc(0) is not portable, so allocate a single domain.  This will
  46.210 +	 * be resized below. */
  46.211 +	node->domains = malloc(sizeof(xenstat_domain));
  46.212 +	if (node->domains == NULL) {
  46.213 +		free(node);
  46.214 +		return NULL;
  46.215 +	}
  46.216 +
  46.217 +	num_domains = 0;
  46.218 +	do {
  46.219 +		xenstat_domain *domain;
  46.220 +
  46.221 +		new_domains = xi_get_domaininfolist(handle->xihandle,
  46.222 +		                                    domaininfo, num_domains,
  46.223 +		                                    DOMAIN_CHUNK_SIZE);
  46.224 +
  46.225 +		node->domains = realloc(node->domains,
  46.226 +					(num_domains + new_domains)
  46.227 +					* sizeof(xenstat_domain));
  46.228 +		if (node->domains == NULL) {
  46.229 +			free(node);
  46.230 +			return NULL;
  46.231 +		}
  46.232 +
  46.233 +		domain = node->domains + num_domains;
  46.234 +
  46.235 +		for (i = 0; i < new_domains; i++) {
  46.236 +			/* Fill in domain using domaininfo[i] */
  46.237 +			domain->id = domaininfo[i].domain;
  46.238 +			domain->state = domaininfo[i].flags;
  46.239 +			domain->cpu_ns = domaininfo[i].cpu_time;
  46.240 +			domain->num_vcpus = domaininfo[i].n_vcpu;
  46.241 +			domain->vcpus = NULL;
  46.242 +			domain->cur_mem =
  46.243 +			    ((unsigned long long)domaininfo[i].tot_pages)
  46.244 +			    * handle->page_size;
  46.245 +			domain->max_mem =
  46.246 +			    domaininfo[i].max_pages == UINT_MAX
  46.247 +			    ? (unsigned long long)-1
  46.248 +			    : (unsigned long long)(domaininfo[i].max_pages
  46.249 +						   * handle->page_size);
  46.250 +			domain->ssid = domaininfo[i].ssidref;
  46.251 +			domain->num_networks = 0;
  46.252 +			domain->networks = NULL;
  46.253 +
  46.254 +			domain++;
  46.255 +		}
  46.256 +		num_domains += new_domains;
  46.257 +	} while (new_domains == DOMAIN_CHUNK_SIZE);
  46.258 +	node->num_domains = num_domains;
  46.259 +
  46.260 +	/* Run all the extra data collectors requested */
  46.261 +	node->flags = 0;
  46.262 +	for (i = 0; i < NUM_COLLECTORS; i++) {
  46.263 +		if ((flags & collectors[i].flag) == collectors[i].flag) {
  46.264 +			node->flags |= collectors[i].flag;
  46.265 +			if(collectors[i].collect(handle, node) == 0) {
  46.266 +				xenstat_free_node(node);
  46.267 +				return NULL;
  46.268 +			}
  46.269 +		}
  46.270 +	}
  46.271 +
  46.272 +	return node;
  46.273 +}
  46.274 +
  46.275 +void xenstat_free_node(xenstat_node * node)
  46.276 +{
  46.277 +	int i;
  46.278 +
  46.279 +	if (node) {
  46.280 +		if (node->domains) {
  46.281 +			for (i = 0; i < NUM_COLLECTORS; i++)
  46.282 +				if((node->flags & collectors[i].flag)
  46.283 +				   == collectors[i].flag)
  46.284 +					collectors[i].free(node);
  46.285 +			free(node->domains);
  46.286 +		}
  46.287 +		free(node);
  46.288 +	}
  46.289 +}
  46.290 +
  46.291 +xenstat_domain *xenstat_node_domain(xenstat_node * node, unsigned int domid)
  46.292 +{
  46.293 +	unsigned int i;
  46.294 +
  46.295 +	/* FIXME: binary search */
  46.296 +	/* Find the appropriate domain entry in the node struct. */
  46.297 +	for (i = 0; i < node->num_domains; i++) {
  46.298 +		if (node->domains[i].id == domid)
  46.299 +			return &(node->domains[i]);
  46.300 +	}
  46.301 +	return NULL;
  46.302 +}
  46.303 +
  46.304 +xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node,
  46.305 +					     unsigned int index)
  46.306 +{
  46.307 +	if (0 <= index && index < node->num_domains)
  46.308 +		return &(node->domains[index]);
  46.309 +	return NULL;
  46.310 +}
  46.311 +
  46.312 +const char *xenstat_node_xen_ver(xenstat_node * node)
  46.313 +{
  46.314 +	return node->xen_version;
  46.315 +}
  46.316 +
  46.317 +unsigned long long xenstat_node_tot_mem(xenstat_node * node)
  46.318 +{
  46.319 +	return node->tot_mem;
  46.320 +}
  46.321 +
  46.322 +unsigned long long xenstat_node_free_mem(xenstat_node * node)
  46.323 +{
  46.324 +	return node->free_mem;
  46.325 +}
  46.326 +
  46.327 +unsigned int xenstat_node_num_domains(xenstat_node * node)
  46.328 +{
  46.329 +	return node->num_domains;
  46.330 +}
  46.331 +
  46.332 +unsigned int xenstat_node_num_cpus(xenstat_node * node)
  46.333 +{
  46.334 +	return node->num_cpus;
  46.335 +}
  46.336 +
  46.337 +/* Get information about the CPU speed */
  46.338 +unsigned long long xenstat_node_cpu_hz(xenstat_node * node)
  46.339 +{
  46.340 +	return node->cpu_hz;
  46.341 +}
  46.342 +
  46.343 +/* Get the domain ID for this domain */
  46.344 +unsigned xenstat_domain_id(xenstat_domain * domain)
  46.345 +{
  46.346 +	return domain->id;
  46.347 +}
  46.348 +
  46.349 +/* Get information about how much CPU time has been used */
  46.350 +unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain)
  46.351 +{
  46.352 +	return domain->cpu_ns;
  46.353 +}
  46.354 +
  46.355 +/* Find the number of VCPUs allocated to a domain */
  46.356 +unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain)
  46.357 +{
  46.358 +	return domain->num_vcpus;
  46.359 +}
  46.360 +
  46.361 +xenstat_vcpu *xenstat_domain_vcpu(xenstat_domain * domain, unsigned int vcpu)
  46.362 +{
  46.363 +	if (0 <= vcpu && vcpu < domain->num_vcpus)
  46.364 +		return &(domain->vcpus[vcpu]);
  46.365 +	return NULL;
  46.366 +}
  46.367 +
  46.368 +/* Find the current memory reservation for this domain */
  46.369 +unsigned long long xenstat_domain_cur_mem(xenstat_domain * domain)
  46.370 +{
  46.371 +	return domain->cur_mem;
  46.372 +}
  46.373 +
  46.374 +/* Find the maximum memory reservation for this domain */
  46.375 +unsigned long long xenstat_domain_max_mem(xenstat_domain * domain)
  46.376 +{
  46.377 +	return domain->max_mem;
  46.378 +}
  46.379 +
  46.380 +/* Find the domain's SSID */
  46.381 +unsigned int xenstat_domain_ssid(xenstat_domain * domain)
  46.382 +{
  46.383 +	return domain->ssid;
  46.384 +}
  46.385 +
  46.386 +/* Get domain states */
  46.387 +unsigned int xenstat_domain_dying(xenstat_domain * domain)
  46.388 +{
  46.389 +	return (domain->state & DOMFLAGS_DYING) == DOMFLAGS_DYING;
  46.390 +}
  46.391 +
  46.392 +unsigned int xenstat_domain_crashed(xenstat_domain * domain)
  46.393 +{
  46.394 +	return ((domain->state & DOMFLAGS_SHUTDOWN) == DOMFLAGS_SHUTDOWN)
  46.395 +	    && (((domain->state >> DOMFLAGS_SHUTDOWNSHIFT)
  46.396 +		 & DOMFLAGS_SHUTDOWNMASK) == SHUTDOWN_crash);
  46.397 +}
  46.398 +
  46.399 +unsigned int xenstat_domain_shutdown(xenstat_domain * domain)
  46.400 +{
  46.401 +	return ((domain->state & DOMFLAGS_SHUTDOWN) == DOMFLAGS_SHUTDOWN)
  46.402 +	    && (((domain->state >> DOMFLAGS_SHUTDOWNSHIFT)
  46.403 +		 & DOMFLAGS_SHUTDOWNMASK) != SHUTDOWN_crash);
  46.404 +}
  46.405 +
  46.406 +unsigned int xenstat_domain_paused(xenstat_domain * domain)
  46.407 +{
  46.408 +	return (domain->state & DOMFLAGS_PAUSED) == DOMFLAGS_PAUSED;
  46.409 +}
  46.410 +
  46.411 +unsigned int xenstat_domain_blocked(xenstat_domain * domain)
  46.412 +{
  46.413 +	return (domain->state & DOMFLAGS_BLOCKED) == DOMFLAGS_BLOCKED;
  46.414 +}
  46.415 +
  46.416 +unsigned int xenstat_domain_running(xenstat_domain * domain)
  46.417 +{
  46.418 +	return (domain->state & DOMFLAGS_RUNNING) == DOMFLAGS_RUNNING;
  46.419 +}
  46.420 +
  46.421 +/* Get the number of networks for a given domain */
  46.422 +unsigned int xenstat_domain_num_networks(xenstat_domain * domain)
  46.423 +{
  46.424 +	return domain->num_networks;
  46.425 +}
  46.426 +
  46.427 +/* Get the network handle to obtain network stats */
  46.428 +xenstat_network *xenstat_domain_network(xenstat_domain * domain,
  46.429 +					unsigned int network)
  46.430 +{
  46.431 +	if (domain->networks && 0 <= network && network < domain->num_networks)
  46.432 +		return &(domain->networks[network]);
  46.433 +	return NULL;
  46.434 +}
  46.435 +
  46.436 +/*
  46.437 + * VCPU functions
  46.438 + */
  46.439 +/* Collect information about VCPUs */
  46.440 +static int xenstat_collect_vcpus(xenstat_handle * handle, xenstat_node * node)
  46.441 +{
  46.442 +	unsigned int i, vcpu;
  46.443 +	/* Fill in VCPU information */
  46.444 +	for (i = 0; i < node->num_domains; i++) {
  46.445 +		node->domains[i].vcpus = malloc(node->domains[i].num_vcpus
  46.446 +						* sizeof(xenstat_vcpu));
  46.447 +		if (node->domains[i].vcpus == NULL)
  46.448 +			return 0;
  46.449 +
  46.450 +		for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) {
  46.451 +			/* FIXME: need to be using a more efficient mechanism*/
  46.452 +			long long vcpu_time;
  46.453 +			vcpu_time =
  46.454 +			    xi_get_vcpu_usage(handle->xihandle,
  46.455 +					      node->domains[i].id,
  46.456 +					      vcpu);
  46.457 +			if (vcpu_time < 0)
  46.458 +				return 0;
  46.459 +			node->domains[i].vcpus[vcpu].ns = vcpu_time;
  46.460 +		}
  46.461 +	}
  46.462 +	return 1;
  46.463 +}
  46.464 +
  46.465 +/* Free VCPU information */
  46.466 +static void xenstat_free_vcpus(xenstat_node * node)
  46.467 +{
  46.468 +	unsigned int i;
  46.469 +	for (i = 0; i < node->num_domains; i++)
  46.470 +		free(node->domains[i].vcpus);
  46.471 +}
  46.472 +
  46.473 +/* Free VCPU information in handle - nothing to do */
  46.474 +static void xenstat_uninit_vcpus(xenstat_handle * handle)
  46.475 +{
  46.476 +}
  46.477 +
  46.478 +/* Get VCPU usage */
  46.479 +unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu)
  46.480 +{
  46.481 +	return vcpu->ns;
  46.482 +}
  46.483 +
  46.484 +/*
  46.485 + * Network functions
  46.486 + */
  46.487 +
  46.488 +/* Expected format of /proc/net/dev */
  46.489 +static const char PROCNETDEV_HEADER[] =
  46.490 +    "Inter-|   Receive                                                |"
  46.491 +    "  Transmit\n"
  46.492 +    " face |bytes    packets errs drop fifo frame compressed multicast|"
  46.493 +    "bytes    packets errs drop fifo colls carrier compressed\n";
  46.494 +
  46.495 +/* Collect information about networks */
  46.496 +static int xenstat_collect_networks(xenstat_handle * handle,
  46.497 +				    xenstat_node * node)
  46.498 +{
  46.499 +	/* Open and validate /proc/net/dev if we haven't already */
  46.500 +	if (handle->procnetdev == NULL) {
  46.501 +		char header[sizeof(PROCNETDEV_HEADER)];
  46.502 +		handle->procnetdev = fopen("/proc/net/dev", "r");
  46.503 +		if (handle->procnetdev == NULL) {
  46.504 +			perror("Error opening /proc/net/dev");
  46.505 +			return 1;
  46.506 +		}
  46.507 +
  46.508 +		/* Validate the format of /proc/net/dev */
  46.509 +		if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1,
  46.510 +			  handle->procnetdev) != 1) {
  46.511 +			perror("Error reading /proc/net/dev header");
  46.512 +			return 1;
  46.513 +		}
  46.514 +		header[sizeof(PROCNETDEV_HEADER) - 1] = '\0';
  46.515 +		if (strcmp(header, PROCNETDEV_HEADER) != 0) {
  46.516 +			fprintf(stderr,
  46.517 +				"Unexpected /proc/net/dev format\n");
  46.518 +			return 1;
  46.519 +		}
  46.520 +	}
  46.521 +
  46.522 +	/* Fill in networks */
  46.523 +	/* FIXME: optimize this */
  46.524 +	fseek(handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1, SEEK_SET);
  46.525 +	while (1) {
  46.526 +		xenstat_domain *domain;
  46.527 +		xenstat_network net;
  46.528 +		unsigned int domid;
  46.529 +		int ret = fscanf(handle->procnetdev,
  46.530 +				 "vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u"
  46.531 +				 "%llu%llu%llu%llu%*u%*u%*u%*u\n",
  46.532 +				 &domid, &net.id,
  46.533 +				 &net.tbytes, &net.tpackets, &net.terrs,
  46.534 +				 &net.tdrop,
  46.535 +				 &net.rbytes, &net.rpackets, &net.rerrs,
  46.536 +				 &net.rdrop);
  46.537 +		if (ret == EOF)
  46.538 +			break;
  46.539 +		if (ret != 10) {
  46.540 +			unsigned int c;
  46.541 +			do {
  46.542 +				c = fgetc(handle->procnetdev);
  46.543 +			} while (c != '\n' && c != EOF);
  46.544 +			if (c == EOF)
  46.545 +				break;
  46.546 +			continue;
  46.547 +		}
  46.548 +
  46.549 +		/* FIXME: this does a search for the domid */
  46.550 +		domain = xenstat_node_domain(node, domid);
  46.551 +		if (domain == NULL) {
  46.552 +			fprintf(stderr,
  46.553 +				"Found interface vif%u.%u but domain %u"
  46.554 +				" does not exist.\n", domid, net.id,
  46.555 +				domid);
  46.556 +			continue;
  46.557 +		}
  46.558 +		if (domain->networks == NULL) {
  46.559 +			domain->num_networks = 1;
  46.560 +			domain->networks = malloc(sizeof(xenstat_network));
  46.561 +		} else {
  46.562 +			domain->num_networks++;
  46.563 +			domain->networks =
  46.564 +			    realloc(domain->networks,
  46.565 +				    domain->num_networks *
  46.566 +				    sizeof(xenstat_network));
  46.567 +		}
  46.568 +		if (domain->networks == NULL)
  46.569 +			return 1;
  46.570 +		domain->networks[domain->num_networks - 1] = net;
  46.571 +	}
  46.572 +
  46.573 +	return 1;
  46.574 +}
  46.575 +
  46.576 +/* Free network information */
  46.577 +static void xenstat_free_networks(xenstat_node * node)
  46.578 +{
  46.579 +	unsigned int i;
  46.580 +	for (i = 0; i < node->num_domains; i++)
  46.581 +		free(node->domains[i].networks);
  46.582 +}
  46.583 +
  46.584 +/* Free network information in handle */
  46.585 +static void xenstat_uninit_networks(xenstat_handle * handle)
  46.586 +{
  46.587 +	if(handle->procnetdev)
  46.588 +		fclose(handle->procnetdev);
  46.589 +}
  46.590 +
  46.591 +/* Get the network ID */
  46.592 +unsigned int xenstat_network_id(xenstat_network * network)
  46.593 +{
  46.594 +	return network->id;
  46.595 +}
  46.596 +
  46.597 +/* Get the number of receive bytes */
  46.598 +unsigned long long xenstat_network_rbytes(xenstat_network * network)
  46.599 +{
  46.600 +	return network->rbytes;
  46.601 +}
  46.602 +
  46.603 +/* Get the number of receive packets */
  46.604 +unsigned long long xenstat_network_rpackets(xenstat_network * network)
  46.605 +{
  46.606 +	return network->rpackets;
  46.607 +}
  46.608 +
  46.609 +/* Get the number of receive errors */
  46.610 +unsigned long long xenstat_network_rerrs(xenstat_network * network)
  46.611 +{
  46.612 +	return network->rerrs;
  46.613 +}
  46.614 +
  46.615 +/* Get the number of receive drops */
  46.616 +unsigned long long xenstat_network_rdrop(xenstat_network * network)
  46.617 +{
  46.618 +	return network->rdrop;
  46.619 +}
  46.620 +
  46.621 +/* Get the number of transmit bytes */
  46.622 +unsigned long long xenstat_network_tbytes(xenstat_network * network)
  46.623 +{
  46.624 +	return network->tbytes;
  46.625 +}
  46.626 +
  46.627 +/* Get the number of transmit packets */
  46.628 +unsigned long long xenstat_network_tpackets(xenstat_network * network)
  46.629 +{
  46.630 +	return network->tpackets;
  46.631 +}
  46.632 +
  46.633 +/* Get the number of transmit errors */
  46.634 +unsigned long long xenstat_network_terrs(xenstat_network * network)
  46.635 +{
  46.636 +	return network->terrs;
  46.637 +}
  46.638 +
  46.639 +/* Get the number of transmit dropped packets */
  46.640 +unsigned long long xenstat_network_tdrop(xenstat_network * network)
  46.641 +{
  46.642 +	return network->tdrop;
  46.643 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Tue Aug 23 12:03:21 2005 -0700
    47.3 @@ -0,0 +1,150 @@
    47.4 +/* libxenstat: statistics-collection library for Xen
    47.5 + * Copyright (C) International Business Machines Corp., 2005
    47.6 + * Authors: Josh Triplett <josht@us.ibm.com>
    47.7 + *          Judy Fischbach <jfisch@us.ibm.com>
    47.8 + *          David Hendricks <dhendrix@us.ibm.com>
    47.9 + *
   47.10 + * This library is free software; you can redistribute it and/or
   47.11 + * modify it under the terms of the GNU Lesser General Public
   47.12 + * License as published by the Free Software Foundation; either
   47.13 + * version 2.1 of the License, or (at your option) any later version.
   47.14 + *
   47.15 + * This library is distributed in the hope that it will be useful,
   47.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   47.18 + * Lesser General Public License for more details.
   47.19 + */
   47.20 +
   47.21 +/* libxenstat API */
   47.22 +
   47.23 +/* Opaque handles */
   47.24 +typedef struct xenstat_handle xenstat_handle;
   47.25 +typedef struct xenstat_domain xenstat_domain;
   47.26 +typedef struct xenstat_node xenstat_node;
   47.27 +typedef struct xenstat_vcpu xenstat_vcpu;
   47.28 +typedef struct xenstat_network xenstat_network;
   47.29 +
   47.30 +/* Initialize the xenstat library.  Returns a handle to be used with
   47.31 + * subsequent calls to the xenstat library, or NULL if an error occurs. */
   47.32 +xenstat_handle *xenstat_init();
   47.33 +
   47.34 +/* Release the handle to libxc, free resources, etc. */
   47.35 +void xenstat_uninit(xenstat_handle * handle);
   47.36 +
   47.37 +/* Get all available information about a node */
   47.38 +#define XENSTAT_VCPU 0x1
   47.39 +#define XENSTAT_NETWORK 0x2
   47.40 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK)
   47.41 +xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
   47.42 +
   47.43 +/* Free the information */
   47.44 +void xenstat_free_node(xenstat_node * node);
   47.45 +
   47.46 +/*
   47.47 + * Node functions - extract information from a xenstat_node
   47.48 + */
   47.49 +
   47.50 +/* Get information about the domain with the given domain ID */
   47.51 +xenstat_domain *xenstat_node_domain(xenstat_node * node,
   47.52 +				    unsigned int domid);
   47.53 +
   47.54 +/* Get the domain with the given index; used to loop over all domains. */
   47.55 +xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node,
   47.56 +					     unsigned index);
   47.57 +/* Get xen version of the node */
   47.58 +const char *xenstat_node_xen_ver(xenstat_node * node);
   47.59 +
   47.60 +/* Get amount of total memory on a node */
   47.61 +unsigned long long xenstat_node_tot_mem(xenstat_node * node);
   47.62 +
   47.63 +/* Get amount of free memory on a node */
   47.64 +unsigned long long xenstat_node_free_mem(xenstat_node * node);
   47.65 +
   47.66 +/* Find the number of domains existing on a node */
   47.67 +unsigned int xenstat_node_num_domains(xenstat_node * node);
   47.68 +
   47.69 +/* Find the number of CPUs existing on a node */
   47.70 +unsigned int xenstat_node_num_cpus(xenstat_node * node);
   47.71 +
   47.72 +/* Get information about the CPU speed */
   47.73 +unsigned long long xenstat_node_cpu_hz(xenstat_node * node);
   47.74 +
   47.75 +/*
   47.76 + * Domain functions - extract information from a xenstat_domain
   47.77 + */
   47.78 +
   47.79 +/* Get the domain ID for this domain */
   47.80 +unsigned xenstat_domain_id(xenstat_domain * domain);
   47.81 +
   47.82 +/* Get information about how much CPU time has been used */
   47.83 +unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain);
   47.84 +
   47.85 +/* Find the number of VCPUs allocated to a domain */
   47.86 +unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain);
   47.87 +
   47.88 +/* Get the VCPU handle to obtain VCPU stats */
   47.89 +xenstat_vcpu *xenstat_domain_vcpu(xenstat_domain * domain,
   47.90 +				  unsigned int vcpu);
   47.91 +
   47.92 +/* Find the current memory reservation for this domain */
   47.93 +unsigned long long xenstat_domain_cur_mem(xenstat_domain * domain);
   47.94 +
   47.95 +/* Find the maximum memory reservation for this domain */
   47.96 +unsigned long long xenstat_domain_max_mem(xenstat_domain * domain);
   47.97 +
   47.98 +/* Find the domain's SSID */
   47.99 +unsigned int xenstat_domain_ssid(xenstat_domain * domain);
  47.100 +
  47.101 +/* Get domain states */
  47.102 +unsigned int xenstat_domain_dying(xenstat_domain * domain);
  47.103 +unsigned int xenstat_domain_crashed(xenstat_domain * domain);
  47.104 +unsigned int xenstat_domain_shutdown(xenstat_domain * domain);
  47.105 +unsigned int xenstat_domain_paused(xenstat_domain * domain);
  47.106 +unsigned int xenstat_domain_blocked(xenstat_domain * domain);
  47.107 +unsigned int xenstat_domain_running(xenstat_domain * domain);
  47.108 +
  47.109 +/* Get the number of networks for a given domain */
  47.110 +unsigned int xenstat_domain_num_networks(xenstat_domain *);
  47.111 +
  47.112 +/* Get the network handle to obtain network stats */
  47.113 +xenstat_network *xenstat_domain_network(xenstat_domain * domain,
  47.114 +					unsigned int network);
  47.115 +
  47.116 +/*
  47.117 + * VCPU functions - extract information from a xenstat_vcpu
  47.118 + */
  47.119 +
  47.120 +/* Get VCPU usage */
  47.121 +unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu);
  47.122 +
  47.123 +
  47.124 +/*
  47.125 + * Network functions - extract information from a xenstat_network
  47.126 + */
  47.127 +
  47.128 +/* Get the ID for this network */
  47.129 +unsigned int xenstat_network_id(xenstat_network * network);
  47.130 +
  47.131 +/* Get the number of receive bytes for this network */
  47.132 +unsigned long long xenstat_network_rbytes(xenstat_network * network);
  47.133 +
  47.134 +/* Get the number of receive packets for this network */
  47.135 +unsigned long long xenstat_network_rpackets(xenstat_network * network);
  47.136 +
  47.137 +/* Get the number of receive errors for this network */
  47.138 +unsigned long long xenstat_network_rerrs(xenstat_network * network);
  47.139 +
  47.140 +/* Get the number of receive drops for this network */
  47.141 +unsigned long long xenstat_network_rdrop(xenstat_network * network);
  47.142 +
  47.143 +/* Get the number of transmit bytes for this network */
  47.144 +unsigned long long xenstat_network_tbytes(xenstat_network * network);
  47.145 +
  47.146 +/* Get the number of transmit packets for this network */
  47.147 +unsigned long long xenstat_network_tpackets(xenstat_network * network);
  47.148 +
  47.149 +/* Get the number of transmit errors for this network */
  47.150 +unsigned long long xenstat_network_terrs(xenstat_network * network);
  47.151 +
  47.152 +/* Get the number of transmit drops for this network */
  47.153 +unsigned long long xenstat_network_tdrop(xenstat_network * network);
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/xenstat/xentop/Makefile	Tue Aug 23 12:03:21 2005 -0700
    48.3 @@ -0,0 +1,44 @@
    48.4 +# Copyright (C) International Business Machines Corp., 2005
    48.5 +# Author: Josh Triplett <josht@us.ibm.com>
    48.6 +# 
    48.7 +# This program is free software; you can redistribute it and/or modify
    48.8 +# it under the terms of the GNU General Public License as published by
    48.9 +# the Free Software Foundation; under version 2 of the License.
   48.10 +#
   48.11 +# This program is distributed in the hope that it will be useful,
   48.12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   48.13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   48.14 +# GNU General Public License for more details.
   48.15 +
   48.16 +XEN_ROOT=../../..
   48.17 +include $(XEN_ROOT)/tools/Rules.mk
   48.18 +
   48.19 +ifneq ($(XENSTAT_XENTOP),y)
   48.20 +all install xentop:
   48.21 +else
   48.22 +
   48.23 +INSTALL         = install
   48.24 +INSTALL_PROG    = $(INSTALL) -m0755 -D
   48.25 +INSTALL_DATA    = $(INSTALL) -m0644 -D
   48.26 +
   48.27 +prefix=/usr
   48.28 +mandir=$(prefix)/share/man
   48.29 +man1dir=$(mandir)/man1
   48.30 +sbindir=$(prefix)/sbin
   48.31 +
   48.32 +CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT)
   48.33 +LDFLAGS += -L$(XEN_LIBXENSTAT)
   48.34 +LDLIBS += -lxenstat -lncurses
   48.35 +
   48.36 +all: xentop
   48.37 +
   48.38 +xentop: xentop.o
   48.39 +
   48.40 +install: xentop xentop.1
   48.41 +	$(INSTALL_PROG) xentop $(DESTDIR)$(sbindir)/xentop
   48.42 +	$(INSTALL_DATA) xentop.1 $(DESTDIR)$(man1dir)/xentop.1
   48.43 +
   48.44 +endif
   48.45 +
   48.46 +clean:
   48.47 +	rm -f xentop xentop.o
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/tools/xenstat/xentop/TODO	Tue Aug 23 12:03:21 2005 -0700
    49.3 @@ -0,0 +1,34 @@
    49.4 +Display error messages on the help line after bad input at a prompt.
    49.5 +Fractional delay times
    49.6 +Use prompting to search for domains
    49.7 +Better line editing?
    49.8 +
    49.9 +* Make CPU in % more accurate
   49.10 +* Domain total network TX % and RX %
   49.11 +
   49.12 +Like Top, f feature, field select of domain columns, toggle the display of
   49.13 +field by typing the letter associated with field, if displayed it shows in
   49.14 +bold and the letter is Capitalized along with a leading asterisk for the
   49.15 +field, if not selected for display letter is lowercase, no leading asterisk
   49.16 +and field is not bolded.
   49.17 +
   49.18 +Like Top, ordering of domain columns, o feature Capital letter shifts left,
   49.19 +lowercase letter shifts right?
   49.20 +
   49.21 +Color
   49.22 +Full management: pause, destroy, create domains
   49.23 +
   49.24 +Add support for Virtual Block Devices (vbd)
   49.25 +
   49.26 +To think about:
   49.27 +Support for one than one node display (distributed monitoring 
   49.28 +from any node of all other nodes in a cluster)
   49.29 +Bottom line option (Switch node, Search node [tab completion?])
   49.30 +
   49.31 +Capture/Logging of resource information generated during a time interval.
   49.32 +-b batch mode dump snapshots to standard output (used with -n)
   49.33 +-n number of iterations to dump to standard output (unlimited if not specified)
   49.34 +-d monitor DomIDs as -dD1,-dD2 or -dD1,D2...
   49.35 +   Monitor only domains with specified domain IDs
   49.36 +-m monitor nodeIDs as -mN1,-mN2 or -mN1,N2...
   49.37 +   Monitor only domains with specified node IDs
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tools/xenstat/xentop/xentop.1	Tue Aug 23 12:03:21 2005 -0700
    50.3 @@ -0,0 +1,88 @@
    50.4 +.\" Copyright (C) International Business Machines  Corp., 2005
    50.5 +.\" Author: Josh Triplett <josht@us.ibm.com>
    50.6 +.\"
    50.7 +.\" This program is free software; you can redistribute it and/or modify
    50.8 +.\" it under the terms of the GNU General Public License as published by
    50.9 +.\" the Free Software Foundation; under version 2 of the License.
   50.10 +.\"
   50.11 +.\" This program is distributed in the hope that it will be useful,
   50.12 +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.13 +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.14 +.\" GNU General Public License for more details.
   50.15 +.\"
   50.16 +.\" You should have received a copy of the GNU General Public License
   50.17 +.\" along with this program; if not, write to the Free Software
   50.18 +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   50.19 +.TH xentop 1 "August 2005"
   50.20 +.SH NAME
   50.21 +\fBxentop\fR \- displays real-time information about a Xen system and domains
   50.22 +
   50.23 +.SH SYNOPSIS
   50.24 +.B xentop
   50.25 +[\fB\-h\fR]
   50.26 +[\fB\-V\fR]
   50.27 +[\fB\-d\fRSECONDS]
   50.28 +[\fB\-n\fR]
   50.29 +[\fB\-r\fR]
   50.30 +[\fB\-v\fR]
   50.31 +
   50.32 +.SH DESCRIPTION
   50.33 +\fBxentop\fR displays information about the Xen system and domains, in a
   50.34 +continually-updating manner.  Command-line options and interactive commands
   50.35 +can change the detail and format of the information displayed by \fBxentop\fR.
   50.36 +
   50.37 +.SH OPTIONS
   50.38 +.TP
   50.39 +\fB\-h\fR, \fB\-\-help\fR
   50.40 +display help and exit
   50.41 +.TP
   50.42 +\fB\-V\fR, \fB\-\-version\fR
   50.43 +output version information and exit
   50.44 +.TP
   50.45 +\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR
   50.46 +seconds between updates (default 3)
   50.47 +.TP
   50.48 +\fB\-n\fR, \fB\-\-networks\fR
   50.49 +output network information
   50.50 +.TP
   50.51 +\fB\-r\fR, \fB\-\-repeat\-header\fR
   50.52 +repeat table header before each domain
   50.53 +.TP
   50.54 +\fB\-v\fR, \fB\-\-vcpus\fR
   50.55 +output VCPU data
   50.56 +
   50.57 +.SH "INTERACTIVE COMMANDS"
   50.58 +All interactive commands are case-insensitive.
   50.59 +.TP
   50.60 +.B D
   50.61 +set delay between updates
   50.62 +.TP
   50.63 +.B N
   50.64 +toggle display of network information
   50.65 +.TP
   50.66 +.B Q, Esc
   50.67 +quit
   50.68 +.TP
   50.69 +.B R
   50.70 +toggle table header before each domain
   50.71 +.TP
   50.72 +.B S
   50.73 +cycle sort order
   50.74 +.TP
   50.75 +.B V
   50.76 +toggle display of VCPU information
   50.77 +.TP
   50.78 +.B Arrows
   50.79 +scroll domain display
   50.80 +
   50.81 +.SH AUTHORS
   50.82 +Written by Judy Fischbach, David Hendricks, and Josh Triplett
   50.83 +
   50.84 +.SH "REPORTING BUGS"
   50.85 +Report bugs to <dsteklof@us.ibm.com>.
   50.86 +
   50.87 +.SH COPYRIGHT
   50.88 +Copyright \(co 2005  International Business Machines  Corp
   50.89 +.br
   50.90 +This is free software; see the source for copying conditions.  There is NO
   50.91 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tools/xenstat/xentop/xentop.c	Tue Aug 23 12:03:21 2005 -0700
    51.3 @@ -0,0 +1,876 @@
    51.4 +/*
    51.5 + *  Copyright (C) International Business Machines  Corp., 2005
    51.6 + *  Author(s): Judy Fischbach <jfisch@us.ibm.com>
    51.7 + *             David Hendricks <dhendrix@us.ibm.com>
    51.8 + *             Josh Triplett <josht@us.ibm.com>
    51.9 + *    based on code from Anthony Liguori <aliguori@us.ibm.com>
   51.10 + *
   51.11 + *  This program is free software; you can redistribute it and/or modify
   51.12 + *  it under the terms of the GNU General Public License as published by
   51.13 + *  the Free Software Foundation; under version 2 of the License.
   51.14 + *
   51.15 + *  This program is distributed in the hope that it will be useful,
   51.16 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   51.17 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   51.18 + *  GNU General Public License for more details.
   51.19 + *
   51.20 + *  You should have received a copy of the GNU General Public License
   51.21 + *  along with this program; if not, write to the Free Software
   51.22 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   51.23 + */
   51.24 +#include <curses.h>
   51.25 +#include <ctype.h>
   51.26 +#include <errno.h>
   51.27 +#include <stdio.h>
   51.28 +#include <stdlib.h>
   51.29 +#include <string.h>
   51.30 +#include <sys/time.h>
   51.31 +#include <time.h>
   51.32 +#include <unistd.h>
   51.33 +
   51.34 +#include <xenstat.h>
   51.35 +
   51.36 +#define XENTOP_VERSION "1.0"
   51.37 +
   51.38 +#define XENTOP_DISCLAIMER \
   51.39 +"Copyright (C) 2005  International Business Machines  Corp\n"\
   51.40 +"This is free software; see the source for copying conditions.There is NO\n"\
   51.41 +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
   51.42 +#define XENTOP_BUGSTO "Report bugs to <dsteklof@us.ibm.com>.\n"
   51.43 +
   51.44 +#define _GNU_SOURCE
   51.45 +#include <getopt.h>
   51.46 +
   51.47 +#if !defined(__GNUC__) && !defined(__GNUG__)
   51.48 +#define __attribute__(arg) /* empty */
   51.49 +#endif
   51.50 +
   51.51 +#define KEY_ESCAPE '\x1B'
   51.52 +
   51.53 +/*
   51.54 + * Function prototypes
   51.55 + */
   51.56 +/* Utility functions */
   51.57 +static void usage(const char *);
   51.58 +static void version(void);
   51.59 +static void cleanup(void);
   51.60 +static void fail(const char *);
   51.61 +static int current_row(void);
   51.62 +static int lines(void);
   51.63 +static void print(const char *, ...) __attribute__((format(printf,1,2)));
   51.64 +static void attr_addstr(int attr, const char *str);
   51.65 +static void set_delay(char *value);
   51.66 +static void set_prompt(char *new_prompt, void (*func)(char *));
   51.67 +static int handle_key(int);
   51.68 +static int compare(unsigned long long, unsigned long long);
   51.69 +static int compare_domains(xenstat_domain **, xenstat_domain **);
   51.70 +static unsigned long long tot_net_bytes( xenstat_domain *, int);
   51.71 +
   51.72 +/* Field functions */
   51.73 +static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2);
   51.74 +static void print_domid(xenstat_domain *domain);
   51.75 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
   51.76 +static void print_state(xenstat_domain *domain);
   51.77 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2);
   51.78 +static void print_cpu(xenstat_domain *domain);
   51.79 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2);
   51.80 +static void print_cpu_pct(xenstat_domain *domain);
   51.81 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2);
   51.82 +static void print_mem(xenstat_domain *domain);
   51.83 +static void print_mem_pct(xenstat_domain *domain);
   51.84 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2);
   51.85 +static void print_maxmem(xenstat_domain *domain);
   51.86 +static void print_max_pct(xenstat_domain *domain);
   51.87 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2);
   51.88 +static void print_vcpus(xenstat_domain *domain);
   51.89 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2);
   51.90 +static void print_nets(xenstat_domain *domain);
   51.91 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2);
   51.92 +static void print_net_tx(xenstat_domain *domain);
   51.93 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2);
   51.94 +static void print_net_rx(xenstat_domain *domain);
   51.95 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2);
   51.96 +static void print_ssid(xenstat_domain *domain);
   51.97 +
   51.98 +/* Section printing functions */
   51.99 +static void do_summary(void);
  51.100 +static void do_header(void);
  51.101 +static void do_bottom_line(void);
  51.102 +static void do_domain(xenstat_domain *);
  51.103 +static void do_vcpu(xenstat_domain *);
  51.104 +static void do_network(xenstat_domain *);
  51.105 +static void top(void);
  51.106 +
  51.107 +/* Field types */
  51.108 +typedef enum field_id {
  51.109 +	FIELD_DOMID,
  51.110 +	FIELD_STATE,
  51.111 +	FIELD_CPU,
  51.112 +	FIELD_CPU_PCT,
  51.113 +	FIELD_MEM,
  51.114 +	FIELD_MEM_PCT,
  51.115 +	FIELD_MAXMEM,
  51.116 +	FIELD_MAX_PCT,
  51.117 +	FIELD_VCPUS,
  51.118 +	FIELD_NETS,
  51.119 +	FIELD_NET_TX,
  51.120 +	FIELD_NET_RX,
  51.121 +	FIELD_SSID
  51.122 +} field_id;
  51.123 +
  51.124 +typedef struct field {
  51.125 +	field_id num;
  51.126 +	const char *header;
  51.127 +	unsigned int default_width;
  51.128 +	int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2);
  51.129 +	void (*print)(xenstat_domain *domain);
  51.130 +} field;
  51.131 +
  51.132 +field fields[] = {
  51.133 +	{ FIELD_DOMID,   "DOMID",      5, compare_domid,   print_domid   },
  51.134 +	{ FIELD_STATE,   "STATE",      6, compare_state,   print_state   },
  51.135 +	{ FIELD_CPU,     "CPU(sec)",  10, compare_cpu,     print_cpu     },
  51.136 +	{ FIELD_CPU_PCT, "CPU(%)",     6, compare_cpu_pct, print_cpu_pct },
  51.137 +	{ FIELD_MEM,     "MEM(k)",    10, compare_mem,     print_mem     },
  51.138 +	{ FIELD_MEM_PCT, "MEM(%)",     6, compare_mem,     print_mem_pct },
  51.139 +	{ FIELD_MAXMEM,  "MAXMEM(k)", 10, compare_maxmem,  print_maxmem  },
  51.140 +	{ FIELD_MAX_PCT, "MAXMEM(%)",  9, compare_maxmem,  print_max_pct },
  51.141 +	{ FIELD_VCPUS,   "VCPUS",      5, compare_vcpus,   print_vcpus   },
  51.142 +	{ FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
  51.143 +	{ FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
  51.144 +	{ FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
  51.145 +	{ FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
  51.146 +};
  51.147 +
  51.148 +const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
  51.149 +
  51.150 +/* Globals */
  51.151 +struct timeval curtime, oldtime;
  51.152 +xenstat_handle *xhandle = NULL;
  51.153 +xenstat_node *prev_node = NULL;
  51.154 +xenstat_node *cur_node = NULL;
  51.155 +field_id sort_field = FIELD_DOMID;
  51.156 +unsigned int first_domain_index = 0;
  51.157 +unsigned int delay = 3;
  51.158 +int show_vcpus = 0;
  51.159 +int show_networks = 0;
  51.160 +int repeat_header = 0;
  51.161 +#define PROMPT_VAL_LEN 80
  51.162 +char *prompt = NULL;
  51.163 +char prompt_val[PROMPT_VAL_LEN];
  51.164 +int prompt_val_len = 0;
  51.165 +void (*prompt_complete_func)(char *);
  51.166 +
  51.167 +/*
  51.168 + * Function definitions
  51.169 + */
  51.170 +
  51.171 +/* Utility functions */
  51.172 +
  51.173 +/* Print usage message, using given program name */
  51.174 +static void usage(const char *program)
  51.175 +{
  51.176 +	printf("Usage: %s [OPTION]\n"
  51.177 +	       "Displays ongoing information about xen vm resources \n\n"
  51.178 +	       "-h, --help           display this help and exit\n"
  51.179 +	       "-V, --version        output version information and exit\n"
  51.180 +	       "-d, --delay=SECONDS  seconds between updates (default 3)\n"
  51.181 +	       "-n, --networks       output vif network data\n"
  51.182 +	       "-r, --repeat-header  repeat table header before each domain\n"
  51.183 +	       "-v, --vcpus          output vcpu data\n"
  51.184 +	       "\n" XENTOP_BUGSTO,
  51.185 +	       program);
  51.186 +	return;
  51.187 +}
  51.188 +
  51.189 +/* Print program version information */
  51.190 +static void version(void)
  51.191 +{
  51.192 +	printf("xentop " XENTOP_VERSION "\n"
  51.193 +	       "Written by Judy Fischbach, David Hendricks, Josh Triplett\n"
  51.194 +	       "\n" XENTOP_DISCLAIMER);
  51.195 +}
  51.196 +
  51.197 +/* Clean up any open resources */
  51.198 +static void cleanup(void)
  51.199 +{
  51.200 +	if(!isendwin())
  51.201 +		endwin();
  51.202 +	if(prev_node != NULL)
  51.203 +		xenstat_free_node(prev_node);
  51.204 +	if(cur_node != NULL)
  51.205 +		xenstat_free_node(cur_node);
  51.206 +	if(xhandle != NULL)
  51.207 +		xenstat_uninit(xhandle);
  51.208 +}
  51.209 +
  51.210 +/* Display the given message and gracefully exit */
  51.211 +static void fail(const char *str)
  51.212 +{
  51.213 +	if(!isendwin())
  51.214 +		endwin();
  51.215 +	fprintf(stderr, str);
  51.216 +	exit(1);
  51.217 +}
  51.218 +
  51.219 +/* Return the row containing the cursor. */
  51.220 +static int current_row(void)
  51.221 +{
  51.222 +	int y, x;
  51.223 +	getyx(stdscr, y, x);
  51.224 +	return y;
  51.225 +}
  51.226 +
  51.227 +/* Return the number of lines on the screen. */
  51.228 +static int lines(void)
  51.229 +{
  51.230 +	int y, x;
  51.231 +	getmaxyx(stdscr, y, x);
  51.232 +	return y;
  51.233 +}
  51.234 +
  51.235 +/* printf-style print function which calls printw, but only if the cursor is
  51.236 + * not on the last line. */
  51.237 +static void print(const char *fmt, ...)
  51.238 +{
  51.239 +	va_list args;
  51.240 +
  51.241 +	if(current_row() < lines()-1) {
  51.242 +		va_start(args, fmt);
  51.243 +		vw_printw(stdscr, fmt, args);
  51.244 +		va_end(args);
  51.245 +	}
  51.246 +}
  51.247 +
  51.248 +/* Print a string with the given attributes set. */
  51.249 +static void attr_addstr(int attr, const char *str)
  51.250 +{
  51.251 +	attron(attr);
  51.252 +	addstr(str);
  51.253 +	attroff(attr);
  51.254 +}
  51.255 +
  51.256 +/* Handle setting the delay from the user-supplied value in prompt_val */
  51.257 +static void set_delay(char *value)
  51.258 +{
  51.259 +	int new_delay;
  51.260 +	new_delay = atoi(value);
  51.261 +	if(new_delay > 0)
  51.262 +		delay = new_delay;
  51.263 +}
  51.264 +
  51.265 +/* Enable prompting mode with the given prompt string; call the given function
  51.266 + * when a value is available. */
  51.267 +static void set_prompt(char *new_prompt, void (*func)(char *))
  51.268 +{
  51.269 +	prompt = new_prompt;
  51.270 +	prompt_val[0] = '\0';
  51.271 +	prompt_val_len = 0;
  51.272 +	prompt_complete_func = func;
  51.273 +}
  51.274 +
  51.275 +/* Handle user input, return 0 if the program should quit, or 1 if not */
  51.276 +static int handle_key(int ch)
  51.277 +{
  51.278 +	if(prompt == NULL) {
  51.279 +		/* Not prompting for input; handle interactive commands */
  51.280 +		switch(ch) {
  51.281 +		case 'n': case 'N':
  51.282 +			show_networks ^= 1;
  51.283 +			break;
  51.284 +		case 'r': case 'R':
  51.285 +			repeat_header ^= 1;
  51.286 +			break;
  51.287 +		case 's': case 'S':
  51.288 +			sort_field = (sort_field + 1) % NUM_FIELDS;
  51.289 +			break;
  51.290 +		case 'v': case 'V':
  51.291 +			show_vcpus ^= 1;
  51.292 +			break;
  51.293 +		case KEY_DOWN:
  51.294 +			first_domain_index++;
  51.295 +			break;
  51.296 +		case KEY_UP:
  51.297 +			if(first_domain_index > 0)
  51.298 +				first_domain_index--;
  51.299 +			break;
  51.300 +		case 'd': case 'D':
  51.301 +			set_prompt("Delay(sec)", set_delay);
  51.302 +			break;
  51.303 +		case 'q': case 'Q': case KEY_ESCAPE:
  51.304 +			return 0;
  51.305 +		}
  51.306 +	} else {
  51.307 +		/* Prompting for input; handle line editing */
  51.308 +		switch(ch) {
  51.309 +		case '\r':
  51.310 +			prompt_complete_func(prompt_val);
  51.311 +			set_prompt(NULL, NULL);
  51.312 +			break;
  51.313 +		case KEY_ESCAPE:
  51.314 +			set_prompt(NULL, NULL);
  51.315 +			break;
  51.316 +		case KEY_BACKSPACE:
  51.317 +			if(prompt_val_len > 0)
  51.318 +				prompt_val[--prompt_val_len] = '\0';
  51.319 +		default:
  51.320 +			if((prompt_val_len+1) < PROMPT_VAL_LEN
  51.321 +			   && isprint(ch)) {
  51.322 +				prompt_val[prompt_val_len++] = (char)ch;
  51.323 +				prompt_val[prompt_val_len] = '\0';
  51.324 +			}
  51.325 +		}
  51.326 +	}
  51.327 +
  51.328 +	return 1;
  51.329 +}
  51.330 +
  51.331 +/* Compares two integers, returning -1,0,1 for <,=,> */
  51.332 +static int compare(unsigned long long i1, unsigned long long i2)
  51.333 +{
  51.334 +	if(i1 < i2)
  51.335 +		return -1;
  51.336 +	if(i1 > i2)
  51.337 +		return 1;
  51.338 +	return 0;
  51.339 +}
  51.340 +
  51.341 +/* Comparison function for use with qsort.  Compares two domains using the
  51.342 + * current sort field. */
  51.343 +static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2)
  51.344 +{
  51.345 +	return fields[sort_field].compare(*domain1, *domain2);
  51.346 +}
  51.347 +
  51.348 +/* Field functions */
  51.349 +
  51.350 +/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */
  51.351 +int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2)
  51.352 +{
  51.353 +	return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2));
  51.354 +}
  51.355 +
  51.356 +/* Prints domain identification number */
  51.357 +void print_domid(xenstat_domain *domain)
  51.358 +{
  51.359 +	print("%5u", xenstat_domain_id(domain));
  51.360 +}
  51.361 +
  51.362 +struct {
  51.363 +	unsigned int (*get)(xenstat_domain *);
  51.364 +	char ch;
  51.365 +} state_funcs[] = {
  51.366 +	{ xenstat_domain_dying,    'd' },
  51.367 +	{ xenstat_domain_shutdown, 's' },
  51.368 +	{ xenstat_domain_blocked,  'b' },
  51.369 +	{ xenstat_domain_crashed,  'c' },
  51.370 +	{ xenstat_domain_paused,   'p' },
  51.371 +	{ xenstat_domain_running,  'r' }
  51.372 +};
  51.373 +const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs);
  51.374 +
  51.375 +/* Compare states of two domains, returning -1,0,1 for <,=,> */
  51.376 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2)
  51.377 +{
  51.378 +	unsigned int i, d1s, d2s;
  51.379 +	for(i = 0; i < NUM_STATES; i++) {
  51.380 +		d1s = state_funcs[i].get(domain1);
  51.381 +		d2s = state_funcs[i].get(domain2);
  51.382 +		if(d1s && !d2s)
  51.383 +			return -1;
  51.384 +		if(d2s && !d1s)
  51.385 +			return 1;
  51.386 +	}
  51.387 +	return 0;
  51.388 +}
  51.389 +
  51.390 +/* Prints domain state in abbreviated letter format */
  51.391 +static void print_state(xenstat_domain *domain)
  51.392 +{
  51.393 +	unsigned int i;
  51.394 +	for(i = 0; i < NUM_STATES; i++)
  51.395 +		print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch
  51.396 +		                                       : '-');
  51.397 +}
  51.398 +
  51.399 +/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */
  51.400 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2)
  51.401 +{
  51.402 +	return -compare(xenstat_domain_cpu_ns(domain1),
  51.403 +			xenstat_domain_cpu_ns(domain2));
  51.404 +}
  51.405 +
  51.406 +/* Prints domain cpu usage in seconds */
  51.407 +static void print_cpu(xenstat_domain *domain)
  51.408 +{
  51.409 +	print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000);
  51.410 +}
  51.411 +
  51.412 +/* Computes the CPU percentage used for a specified domain */
  51.413 +static double get_cpu_pct(xenstat_domain *domain)
  51.414 +{
  51.415 +	xenstat_domain *old_domain;
  51.416 +	double us_elapsed;
  51.417 +
  51.418 +	/* Can't calculate CPU percentage without a previous sample. */
  51.419 +	if(prev_node == NULL)
  51.420 +		return 0.0;
  51.421 +
  51.422 +	old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain));
  51.423 +	if(old_domain == NULL)
  51.424 +		return 0.0;
  51.425 +
  51.426 +	/* Calculate the time elapsed in microseconds */
  51.427 +	us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0
  51.428 +		      +(curtime.tv_usec - oldtime.tv_usec));
  51.429 +
  51.430 +	/* In the following, nanoseconds must be multiplied by 1000.0 to
  51.431 +	 * convert to microseconds, then divided by 100.0 to get a percentage,
  51.432 +	 * resulting in a multiplication by 10.0 */
  51.433 +	return ((xenstat_domain_cpu_ns(domain)
  51.434 +		 -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed;
  51.435 +}
  51.436 +
  51.437 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2)
  51.438 +{
  51.439 +	return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2));
  51.440 +}
  51.441 +
  51.442 +/* Prints cpu percentage statistic */
  51.443 +static void print_cpu_pct(xenstat_domain *domain)
  51.444 +{
  51.445 +	print("%6.1f", get_cpu_pct(domain));
  51.446 +}
  51.447 +
  51.448 +/* Compares current memory of two domains, returning -1,0,1 for <,=,> */
  51.449 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2)
  51.450 +{
  51.451 +	return -compare(xenstat_domain_cur_mem(domain1),
  51.452 +	                xenstat_domain_cur_mem(domain2));
  51.453 +}
  51.454 +
  51.455 +/* Prints current memory statistic */
  51.456 +static void print_mem(xenstat_domain *domain)
  51.457 +{
  51.458 +	print("%10llu", xenstat_domain_cur_mem(domain)/1024);
  51.459 +}
  51.460 +
  51.461 +/* Prints memory percentage statistic, ratio of current domain memory to total
  51.462 + * node memory */
  51.463 +static void print_mem_pct(xenstat_domain *domain)
  51.464 +{
  51.465 +	print("%6.1f", (double)xenstat_domain_cur_mem(domain) /
  51.466 +	               (double)xenstat_node_tot_mem(cur_node) * 100);
  51.467 +}
  51.468 +
  51.469 +/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */
  51.470 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2)
  51.471 +{
  51.472 +	return -compare(xenstat_domain_max_mem(domain1),
  51.473 +	                xenstat_domain_max_mem(domain2));
  51.474 +}
  51.475 +
  51.476 +/* Prints maximum domain memory statistic in KB */
  51.477 +static void print_maxmem(xenstat_domain *domain)
  51.478 +{
  51.479 +	unsigned long long max_mem = xenstat_domain_max_mem(domain);
  51.480 +	if(max_mem == ((unsigned long long)-1))
  51.481 +		print("%10s", "no limit");
  51.482 +	else
  51.483 +		print("%10llu", max_mem/1024);
  51.484 +}
  51.485 +
  51.486 +/* Prints memory percentage statistic, ratio of current domain memory to total
  51.487 + * node memory */
  51.488 +static void print_max_pct(xenstat_domain *domain)
  51.489 +{
  51.490 +	if (xenstat_domain_max_mem(domain) == (unsigned long long)-1)
  51.491 +		print("%9s", "n/a");
  51.492 +	else
  51.493 +		print("%9.1f", (double)xenstat_domain_max_mem(domain) /
  51.494 +		               (double)xenstat_node_tot_mem(cur_node) * 100);
  51.495 +}
  51.496 +
  51.497 +/* Compares number of virtual CPUs of two domains, returning -1,0,1 for
  51.498 + * <,=,> */
  51.499 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2)
  51.500 +{
  51.501 +	return -compare(xenstat_domain_num_vcpus(domain1),
  51.502 +	                xenstat_domain_num_vcpus(domain2));
  51.503 +}
  51.504 +
  51.505 +/* Prints number of virtual CPUs statistic */
  51.506 +static void print_vcpus(xenstat_domain *domain)
  51.507 +{
  51.508 +	print("%5u", xenstat_domain_num_vcpus(domain));
  51.509 +}
  51.510 +
  51.511 +/* Compares number of virtual networks of two domains, returning -1,0,1 for
  51.512 + * <,=,> */
  51.513 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2)
  51.514 +{
  51.515 +	return -compare(xenstat_domain_num_networks(domain1),
  51.516 +	                xenstat_domain_num_networks(domain2));
  51.517 +}
  51.518 +
  51.519 +/* Prints number of virtual networks statistic */
  51.520 +static void print_nets(xenstat_domain *domain)
  51.521 +{
  51.522 +	print("%4u", xenstat_domain_num_networks(domain));
  51.523 +}
  51.524 +
  51.525 +/* Compares number of total network tx bytes of two domains, returning -1,0,1 for
  51.526 + * <,=,> */
  51.527 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2)
  51.528 +{
  51.529 +	return -compare(tot_net_bytes(domain1, FALSE),
  51.530 +	                tot_net_bytes(domain2, FALSE));
  51.531 +}
  51.532 +
  51.533 +/* Prints number of total network tx bytes statistic */
  51.534 +static void print_net_tx(xenstat_domain *domain)
  51.535 +{
  51.536 +	print("%8llu", tot_net_bytes(domain, FALSE)/1024);
  51.537 +}
  51.538 +
  51.539 +/* Compares number of total network rx bytes of two domains, returning -1,0,1 for
  51.540 + * <,=,> */
  51.541 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2)
  51.542 +{
  51.543 +	return -compare(tot_net_bytes(domain1, TRUE),
  51.544 +	                tot_net_bytes(domain2, TRUE));
  51.545 +}
  51.546 +
  51.547 +/* Prints number of total network rx bytes statistic */
  51.548 +static void print_net_rx(xenstat_domain *domain)
  51.549 +{
  51.550 +	print("%8llu", tot_net_bytes(domain, TRUE)/1024);
  51.551 +}
  51.552 +
  51.553 +/* Gets number of total network bytes statistic, if rx true, then rx bytes
  51.554 + * otherwise tx bytes
  51.555 + */
  51.556 +static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag)
  51.557 +{
  51.558 +	int i = 0;
  51.559 +	xenstat_network *network;
  51.560 +	unsigned num_networks = 0;
  51.561 +        unsigned long long total = 0;
  51.562 +
  51.563 +	/* How many networks? */
  51.564 +	num_networks = xenstat_domain_num_networks(domain);
  51.565 +
  51.566 +	/* Dump information for each network */
  51.567 +	for (i=0; i < num_networks; i++) {
  51.568 +		/* Next get the network information */
  51.569 +		network = xenstat_domain_network(domain,i);
  51.570 +                if (rx_flag) 
  51.571 +			total += xenstat_network_rbytes(network);
  51.572 +                else 
  51.573 +			total += xenstat_network_tbytes(network);
  51.574 +	}
  51.575 +        return (total);
  51.576 +}
  51.577 +
  51.578 +/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
  51.579 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
  51.580 +{
  51.581 +	return compare(xenstat_domain_ssid(domain1),
  51.582 +		       xenstat_domain_ssid(domain2));
  51.583 +}
  51.584 +
  51.585 +/* Prints ssid statistic */
  51.586 +static void print_ssid(xenstat_domain *domain)
  51.587 +{
  51.588 +	print("%4u", xenstat_domain_ssid(domain));
  51.589 +}
  51.590 +
  51.591 +/* Section printing functions */
  51.592 +/* Prints the top summary, above the domain table */
  51.593 +void do_summary(void)
  51.594 +{
  51.595 +#define TIME_STR_LEN 9
  51.596 +	const char *TIME_STR_FORMAT = "%H:%M:%S";
  51.597 +	char time_str[TIME_STR_LEN];
  51.598 +	unsigned run = 0, block = 0, pause = 0,
  51.599 +	         crash = 0, dying = 0, shutdown = 0;
  51.600 +	unsigned i, num_domains = 0;
  51.601 +	unsigned long long used = 0;
  51.602 +	xenstat_domain *domain;
  51.603 +
  51.604 +	/* Print program name, current time, and number of domains */
  51.605 +	strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT,
  51.606 +	         localtime(&curtime.tv_sec));
  51.607 +	num_domains = xenstat_node_num_domains(cur_node);
  51.608 +	print("xentop - %s\n", time_str);
  51.609 +
  51.610 +	/* Tabulate what states domains are in for summary */
  51.611 +	for (i=0; i < num_domains; i++) {
  51.612 +		domain = xenstat_node_domain_by_index(cur_node,i);
  51.613 +		if (xenstat_domain_running(domain)) run++;
  51.614 +		else if (xenstat_domain_blocked(domain)) block++;
  51.615 +		else if (xenstat_domain_paused(domain)) pause++;
  51.616 +		else if (xenstat_domain_shutdown(domain)) shutdown++;
  51.617 +		else if (xenstat_domain_crashed(domain)) crash++;
  51.618 +		else if (xenstat_domain_dying(domain)) dying++;
  51.619 +	}
  51.620 +
  51.621 +	print("%u domains: %u running, %u blocked, %u paused, "
  51.622 +	      "%u crashed, %u dying, %u shutdown \n",
  51.623 +	      num_domains, run, block, pause, crash, dying, shutdown);
  51.624 +
  51.625 +	used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node);
  51.626 +
  51.627 +	/* Dump node memory and cpu information */
  51.628 +	print("Mem: %lluk total, %lluk used, %lluk free    "
  51.629 +	      "CPUs: %u @ %lluMHz\n",
  51.630 +	      xenstat_node_tot_mem(cur_node)/1024, used/1024,
  51.631 +	      xenstat_node_free_mem(cur_node)/1024,
  51.632 +	      xenstat_node_num_cpus(cur_node),
  51.633 +	      xenstat_node_cpu_hz(cur_node)/1000000);
  51.634 +}
  51.635 +
  51.636 +/* Display the top header for the domain table */
  51.637 +void do_header(void)
  51.638 +{
  51.639 +	field_id i;
  51.640 +
  51.641 +	/* Turn on REVERSE highlight attribute for headings */
  51.642 +	attron(A_REVERSE);
  51.643 +	for(i = 0; i < NUM_FIELDS; i++) {
  51.644 +		if(i != 0)
  51.645 +			print(" ");
  51.646 +		/* The BOLD attribute is turned on for the sort column */
  51.647 +		if(i == sort_field)
  51.648 +			attron(A_BOLD);
  51.649 +		print("%*s", fields[i].default_width, fields[i].header);
  51.650 +		if(i == sort_field)
  51.651 +			attroff(A_BOLD);
  51.652 +	}
  51.653 +	attroff(A_REVERSE);
  51.654 +	print("\n");
  51.655 +}
  51.656 +
  51.657 +/* Displays bottom status line or current prompt */
  51.658 +void do_bottom_line(void)
  51.659 +{
  51.660 +	move(lines()-1, 2);
  51.661 +
  51.662 +	if (prompt != NULL) {
  51.663 +		printw("%s: %s", prompt, prompt_val);
  51.664 +	} else {
  51.665 +		addch(A_REVERSE | 'D'); addstr("elay  ");
  51.666 +
  51.667 +		/* network */
  51.668 +		addch(A_REVERSE | 'N');
  51.669 +		attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
  51.670 +		addstr("  ");
  51.671 +
  51.672 +		/* vcpus */
  51.673 +		addch(A_REVERSE | 'V');
  51.674 +		attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs");
  51.675 +		addstr("  ");
  51.676 +
  51.677 +		/* repeat */
  51.678 +		addch(A_REVERSE | 'R');
  51.679 +		attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header");
  51.680 +		addstr("  ");
  51.681 +
  51.682 +		/* sort order */
  51.683 +		addch(A_REVERSE | 'S'); addstr("ort order  ");
  51.684 +
  51.685 +		addch(A_REVERSE | 'Q'); addstr("uit  ");
  51.686 +	}
  51.687 +}
  51.688 +
  51.689 +/* Prints Domain information */
  51.690 +void do_domain(xenstat_domain *domain)
  51.691 +{
  51.692 +	unsigned int i;
  51.693 +	for(i = 0; i < NUM_FIELDS; i++) {
  51.694 +		if(i != 0)
  51.695 +			print(" ");
  51.696 +		if(i == sort_field)
  51.697 +			attron(A_BOLD);
  51.698 +		fields[i].print(domain);
  51.699 +		if(i == sort_field)
  51.700 +			attroff(A_BOLD);
  51.701 +	}
  51.702 +	print("\n");
  51.703 +}
  51.704 +
  51.705 +/* Output all vcpu information */
  51.706 +void do_vcpu(xenstat_domain *domain)
  51.707 +{
  51.708 +	int i = 0;
  51.709 +	unsigned num_vcpus = 0;
  51.710 +	xenstat_vcpu *vcpu;
  51.711 +
  51.712 +	print("VCPUs(sec): ");
  51.713 +
  51.714 +	num_vcpus = xenstat_domain_num_vcpus(domain);
  51.715 +
  51.716 +	/* for all vcpus dump out values */
  51.717 +	for (i=0; i< num_vcpus; i++) {
  51.718 +		vcpu = xenstat_domain_vcpu(domain,i);
  51.719 +
  51.720 +		if (i != 0 && (i%5)==0)
  51.721 +			print("\n        ");
  51.722 +		print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000);
  51.723 +	}
  51.724 +	print("\n");
  51.725 +}
  51.726 +
  51.727 +/* Output all network information */
  51.728 +void do_network(xenstat_domain *domain)
  51.729 +{
  51.730 +	int i = 0;
  51.731 +	xenstat_network *network;
  51.732 +	unsigned num_networks = 0;
  51.733 +
  51.734 +	/* How many networks? */
  51.735 +	num_networks = xenstat_domain_num_networks(domain);
  51.736 +
  51.737 +	/* Dump information for each network */
  51.738 +	for (i=0; i < num_networks; i++) {
  51.739 +		/* Next get the network information */
  51.740 +		network = xenstat_domain_network(domain,i);
  51.741 +
  51.742 +		print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop  ",
  51.743 +		      i,
  51.744 +		      xenstat_network_rbytes(network),
  51.745 +		      xenstat_network_rpackets(network),
  51.746 +		      xenstat_network_rerrs(network),
  51.747 +		      xenstat_network_rdrop(network));
  51.748 +
  51.749 +		print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n",
  51.750 +		      xenstat_network_tbytes(network),
  51.751 +		      xenstat_network_tpackets(network),
  51.752 +		      xenstat_network_terrs(network),
  51.753 +		      xenstat_network_tdrop(network));
  51.754 +	}
  51.755 +}
  51.756 +
  51.757 +static void top(void)
  51.758 +{
  51.759 +	xenstat_domain **domains;
  51.760 +	unsigned int i, num_domains = 0;
  51.761 +
  51.762 +	/* Now get the node information */
  51.763 +	if (prev_node != NULL)
  51.764 +		xenstat_free_node(prev_node);
  51.765 +	prev_node = cur_node;
  51.766 +	cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
  51.767 +	if (cur_node == NULL)
  51.768 +		fail("Failed to retrieve statistics from libxenstat\n");
  51.769 +
  51.770 +	/* dump summary top information */
  51.771 +	do_summary();
  51.772 +
  51.773 +	/* Count the number of domains for which to report data */
  51.774 +	num_domains = xenstat_node_num_domains(cur_node);
  51.775 +
  51.776 +	domains = malloc(num_domains*sizeof(xenstat_domain *));
  51.777 +	if(domains == NULL)
  51.778 +		fail("Failed to allocate memory\n");
  51.779 +
  51.780 +	for (i=0; i < num_domains; i++)
  51.781 +		domains[i] = xenstat_node_domain_by_index(cur_node, i);
  51.782 +
  51.783 +	/* Sort */
  51.784 +	qsort(domains, num_domains, sizeof(xenstat_domain *),
  51.785 +	      (int(*)(const void *, const void *))compare_domains);
  51.786 +
  51.787 +	if(first_domain_index >= num_domains)
  51.788 +		first_domain_index = num_domains-1;
  51.789 +
  51.790 +	for (i = first_domain_index; i < num_domains; i++) {
  51.791 +		if(current_row() == lines()-1)
  51.792 +			break;
  51.793 +		if (i == first_domain_index || repeat_header)
  51.794 +			do_header();
  51.795 +		do_domain(domains[i]);
  51.796 +		if (show_vcpus)
  51.797 +			do_vcpu(domains[i]);
  51.798 +		if (show_networks)
  51.799 +			do_network(domains[i]);
  51.800 +	}
  51.801 +
  51.802 +	do_bottom_line();
  51.803 +}
  51.804 +
  51.805 +int main(int argc, char **argv)
  51.806 +{
  51.807 +	int opt, optind = 0;
  51.808 +	int ch = ERR;
  51.809 +
  51.810 +	struct option lopts[] = {
  51.811 +		{ "help",          no_argument,       NULL, 'h' },
  51.812 +		{ "version",       no_argument,       NULL, 'V' },
  51.813 +		{ "networks",      no_argument,       NULL, 'n' },
  51.814 +		{ "repeat-header", no_argument,       NULL, 'r' },
  51.815 +		{ "vcpus",         no_argument,       NULL, 'v' },
  51.816 +		{ "delay",         required_argument, NULL, 'd' },
  51.817 +		{ 0, 0, 0, 0 },
  51.818 +	};
  51.819 +	const char *sopts = "hVbnvd:";
  51.820 +
  51.821 +	if (atexit(cleanup) != 0)
  51.822 +		fail("Failed to install cleanup handler.\n");
  51.823 +
  51.824 +	while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) {
  51.825 +		switch (opt) {
  51.826 +		case 'h':
  51.827 +		case '?':
  51.828 +		default:
  51.829 +			usage(argv[0]);
  51.830 +			exit(0);
  51.831 +		case 'V':
  51.832 +			version();
  51.833 +			exit(0);
  51.834 +		case 'n':
  51.835 +			show_networks = 1;
  51.836 +			break;
  51.837 +		case 'r':
  51.838 +			repeat_header = 1;
  51.839 +			break;
  51.840 +		case 'v':
  51.841 +			show_vcpus = 1;
  51.842 +			break;
  51.843 +		case 'd':
  51.844 +			delay = atoi(optarg);
  51.845 +			break;
  51.846 +		}
  51.847 +	}
  51.848 +
  51.849 +	/* Get xenstat handle */
  51.850 +	xhandle = xenstat_init();
  51.851 +	if (xhandle == NULL)
  51.852 +		fail("Failed to initialize xenstat library\n");
  51.853 +
  51.854 +	/* Begin curses stuff */
  51.855 +	initscr();
  51.856 +	start_color();
  51.857 +	cbreak();
  51.858 +	noecho();
  51.859 +	nonl();
  51.860 +	keypad(stdscr, TRUE);
  51.861 +	halfdelay(5);
  51.862 +	use_default_colors();
  51.863 +	init_pair(1, -1, COLOR_YELLOW);
  51.864 +
  51.865 +	do {
  51.866 +		gettimeofday(&curtime, NULL);
  51.867 +		if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
  51.868 +			clear();
  51.869 +			top();
  51.870 +			oldtime = curtime;
  51.871 +			refresh();
  51.872 +		}
  51.873 +		ch = getch();
  51.874 +	} while (handle_key(ch));
  51.875 +
  51.876 +	/* Cleanup occurs in cleanup(), so no work to do here. */
  51.877 +
  51.878 +	return 0;
  51.879 +}
    52.1 --- a/xen/arch/x86/io_apic.c	Mon Aug 22 11:37:48 2005 -0700
    52.2 +++ b/xen/arch/x86/io_apic.c	Tue Aug 23 12:03:21 2005 -0700
    52.3 @@ -1751,8 +1751,30 @@ int ioapic_guest_write(int apicid, int a
    52.4      
    52.5      pin = (address - 0x10) >> 1;
    52.6  
    52.7 +    *(u32 *)&rte = val;
    52.8      rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
    52.9 -    *(int *)&rte = val;
   52.10 +
   52.11 +    /*
   52.12 +     * What about weird destination types?
   52.13 +     *  SMI:    Ignore? Ought to be set up by the BIOS.
   52.14 +     *  NMI:    Ignore? Watchdog functionality is Xen's concern.
   52.15 +     *  INIT:   Definitely ignore: probably a guest OS bug.
   52.16 +     *  ExtINT: Ignore? Linux only asserts this at start of day.
   52.17 +     * For now, print a message and return an error. We can fix up on demand.
   52.18 +     */
   52.19 +    if ( rte.delivery_mode > dest_LowestPrio )
   52.20 +    {
   52.21 +        printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
   52.22 +        printk("       APIC=%d/%d, lo-reg=%x\n", apicid, pin, val);
   52.23 +        return -EINVAL;
   52.24 +    }
   52.25 +
   52.26 +    /*
   52.27 +     * The guest does not know physical APIC arrangement (flat vs. cluster).
   52.28 +     * Apply genapic conventions for this platform.
   52.29 +     */
   52.30 +    rte.delivery_mode = INT_DELIVERY_MODE;
   52.31 +    rte.dest_mode     = INT_DEST_MODE;
   52.32  
   52.33      if ( rte.vector >= FIRST_DEVICE_VECTOR )
   52.34      {
    53.1 --- a/xen/arch/x86/mm.c	Mon Aug 22 11:37:48 2005 -0700
    53.2 +++ b/xen/arch/x86/mm.c	Tue Aug 23 12:03:21 2005 -0700
    53.3 @@ -444,7 +444,7 @@ get_page_from_l1e(
    53.4  
    53.5      if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) )
    53.6      {
    53.7 -        MEM_LOG("Bad L1 flags %x\n", l1e_get_flags(l1e) & L1_DISALLOW_MASK);
    53.8 +        MEM_LOG("Bad L1 flags %x", l1e_get_flags(l1e) & L1_DISALLOW_MASK);
    53.9          return 0;
   53.10      }
   53.11  
   53.12 @@ -490,7 +490,7 @@ get_page_from_l2e(
   53.13  
   53.14      if ( unlikely((l2e_get_flags(l2e) & L2_DISALLOW_MASK)) )
   53.15      {
   53.16 -        MEM_LOG("Bad L2 flags %x\n", l2e_get_flags(l2e) & L2_DISALLOW_MASK);
   53.17 +        MEM_LOG("Bad L2 flags %x", l2e_get_flags(l2e) & L2_DISALLOW_MASK);
   53.18          return 0;
   53.19      }
   53.20  
   53.21 @@ -523,7 +523,7 @@ get_page_from_l3e(
   53.22  
   53.23      if ( unlikely((l3e_get_flags(l3e) & L3_DISALLOW_MASK)) )
   53.24      {
   53.25 -        MEM_LOG("Bad L3 flags %x\n", l3e_get_flags(l3e) & L3_DISALLOW_MASK);
   53.26 +        MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & L3_DISALLOW_MASK);
   53.27          return 0;
   53.28      }
   53.29  
   53.30 @@ -557,7 +557,7 @@ get_page_from_l4e(
   53.31  
   53.32      if ( unlikely((l4e_get_flags(l4e) & L4_DISALLOW_MASK)) )
   53.33      {
   53.34 -        MEM_LOG("Bad L4 flags %x\n", l4e_get_flags(l4e) & L4_DISALLOW_MASK);
   53.35 +        MEM_LOG("Bad L4 flags %x", l4e_get_flags(l4e) & L4_DISALLOW_MASK);
   53.36          return 0;
   53.37      }
   53.38  
   53.39 @@ -1025,7 +1025,7 @@ static inline int update_l1e(l1_pgentry_
   53.40           unlikely(o != l1e_get_intpte(ol1e)) )
   53.41      {
   53.42          MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
   53.43 -                ": saw %" PRIpte "\n",
   53.44 +                ": saw %" PRIpte,
   53.45                  l1e_get_intpte(ol1e),
   53.46                  l1e_get_intpte(nl1e),
   53.47                  o);
   53.48 @@ -1051,7 +1051,7 @@ static int mod_l1_entry(l1_pgentry_t *pl
   53.49      {
   53.50          if ( unlikely(l1e_get_flags(nl1e) & L1_DISALLOW_MASK) )
   53.51          {
   53.52 -            MEM_LOG("Bad L1 flags %x\n",
   53.53 +            MEM_LOG("Bad L1 flags %x",
   53.54                      l1e_get_flags(nl1e) & L1_DISALLOW_MASK);
   53.55              return 0;
   53.56          }
   53.57 @@ -1113,7 +1113,7 @@ static int mod_l2_entry(l2_pgentry_t *pl
   53.58      {
   53.59          if ( unlikely(l2e_get_flags(nl2e) & L2_DISALLOW_MASK) )
   53.60          {
   53.61 -            MEM_LOG("Bad L2 flags %x\n",
   53.62 +            MEM_LOG("Bad L2 flags %x",
   53.63                      l2e_get_flags(nl2e) & L2_DISALLOW_MASK);
   53.64              return 0;
   53.65          }
   53.66 @@ -1175,7 +1175,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
   53.67      {
   53.68          if ( unlikely(l3e_get_flags(nl3e) & L3_DISALLOW_MASK) )
   53.69          {
   53.70 -            MEM_LOG("Bad L3 flags %x\n",
   53.71 +            MEM_LOG("Bad L3 flags %x",
   53.72                      l3e_get_flags(nl3e) & L3_DISALLOW_MASK);
   53.73              return 0;
   53.74          }
   53.75 @@ -1237,7 +1237,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
   53.76      {
   53.77          if ( unlikely(l4e_get_flags(nl4e) & L4_DISALLOW_MASK) )
   53.78          {
   53.79 -            MEM_LOG("Bad L4 flags %x\n",
   53.80 +            MEM_LOG("Bad L4 flags %x",
   53.81                      l4e_get_flags(nl4e) & L4_DISALLOW_MASK);
   53.82              return 0;
   53.83          }
   53.84 @@ -1598,7 +1598,7 @@ static int set_foreigndom(unsigned int c
   53.85              percpu_info[cpu].foreign = dom_io;
   53.86              break;
   53.87          default:
   53.88 -            MEM_LOG("Dom %u cannot set foreign dom\n", d->domain_id);
   53.89 +            MEM_LOG("Dom %u cannot set foreign dom", d->domain_id);
   53.90              okay = 0;
   53.91              break;
   53.92          }
   53.93 @@ -1831,7 +1831,7 @@ int do_mmuext_op(
   53.94          case MMUEXT_FLUSH_CACHE:
   53.95              if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
   53.96              {
   53.97 -                MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.\n");
   53.98 +                MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.");
   53.99                  okay = 0;
  53.100              }
  53.101              else
  53.102 @@ -1845,7 +1845,7 @@ int do_mmuext_op(
  53.103              if ( shadow_mode_external(d) )
  53.104              {
  53.105                  MEM_LOG("ignoring SET_LDT hypercall from external "
  53.106 -                        "domain %u\n", d->domain_id);
  53.107 +                        "domain %u", d->domain_id);
  53.108                  okay = 0;
  53.109                  break;
  53.110              }
  53.111 @@ -1916,7 +1916,7 @@ int do_mmuext_op(
  53.112                   unlikely(IS_XEN_HEAP_FRAME(page)) )
  53.113              {
  53.114                  MEM_LOG("Transferee has no reservation headroom (%d,%d), or "
  53.115 -                        "page is in Xen heap (%lx), or dom is dying (%ld).\n",
  53.116 +                        "page is in Xen heap (%lx), or dom is dying (%ld).",
  53.117                          e->tot_pages, e->max_pages, op.mfn, e->domain_flags);
  53.118                  okay = 0;
  53.119                  goto reassign_fail;
  53.120 @@ -1937,7 +1937,7 @@ int do_mmuext_op(
  53.121                       unlikely(_nd != _d) )
  53.122                  {
  53.123                      MEM_LOG("Bad page values %lx: ed=%p(%u), sd=%p,"
  53.124 -                            " caf=%08x, taf=%" PRtype_info "\n",
  53.125 +                            " caf=%08x, taf=%" PRtype_info,
  53.126                              page_to_pfn(page), d, d->domain_id,
  53.127                              unpickle_domptr(_nd), x, page->u.inuse.type_info);
  53.128                      okay = 0;
  53.129 @@ -2301,7 +2301,7 @@ int update_grant_pte_mapping(
  53.130      if ( ((type_info & PGT_type_mask) != PGT_l1_page_table) ||
  53.131           !get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask)) )
  53.132      {
  53.133 -        DPRINTK("Grant map attempted to update a non-L1 page\n");
  53.134 +        MEM_LOG("Grant map attempted to update a non-L1 page");
  53.135          rc = GNTST_general_error;
  53.136          goto failed;
  53.137      }
  53.138 @@ -2363,7 +2363,7 @@ int clear_grant_pte_mapping(
  53.139      if ( ((type_info & PGT_type_mask) != PGT_l1_page_table) ||
  53.140           !get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask)) )
  53.141      {
  53.142 -        DPRINTK("Grant map attempted to update a non-L1 page\n");
  53.143 +        MEM_LOG("Grant map attempted to update a non-L1 page");
  53.144          rc = GNTST_general_error;
  53.145          goto failed;
  53.146      }
  53.147 @@ -2378,7 +2378,7 @@ int clear_grant_pte_mapping(
  53.148      /* Check that the virtual address supplied is actually mapped to frame. */
  53.149      if ( unlikely((l1e_get_intpte(ol1e) >> PAGE_SHIFT) != frame) )
  53.150      {
  53.151 -        DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
  53.152 +        MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
  53.153                  (unsigned long)l1e_get_intpte(ol1e), addr, frame);
  53.154          put_page_type(page);
  53.155          rc = GNTST_general_error;
  53.156 @@ -2388,7 +2388,7 @@ int clear_grant_pte_mapping(
  53.157      /* Delete pagetable entry. */
  53.158      if ( unlikely(__put_user(0, (intpte_t *)va)))
  53.159      {
  53.160 -        DPRINTK("Cannot delete PTE entry at %p.\n", va);
  53.161 +        MEM_LOG("Cannot delete PTE entry at %p", va);
  53.162          put_page_type(page);
  53.163          rc = GNTST_general_error;
  53.164          goto failed;
  53.165 @@ -2452,7 +2452,7 @@ int clear_grant_va_mapping(unsigned long
  53.166  
  53.167      if ( unlikely(__get_user(ol1e.l1, &pl1e->l1) != 0) )
  53.168      {
  53.169 -        DPRINTK("Could not find PTE entry for address %lx\n", addr);
  53.170 +        MEM_LOG("Could not find PTE entry for address %lx", addr);
  53.171          return GNTST_general_error;
  53.172      }
  53.173  
  53.174 @@ -2462,7 +2462,7 @@ int clear_grant_va_mapping(unsigned long
  53.175       */
  53.176      if ( unlikely(l1e_get_pfn(ol1e) != frame) )
  53.177      {
  53.178 -        DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
  53.179 +        MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
  53.180                  l1e_get_pfn(ol1e), addr, frame);
  53.181          return GNTST_general_error;
  53.182      }
  53.183 @@ -2470,7 +2470,7 @@ int clear_grant_va_mapping(unsigned long
  53.184      /* Delete pagetable entry. */
  53.185      if ( unlikely(__put_user(0, &pl1e->l1)) )
  53.186      {
  53.187 -        DPRINTK("Cannot delete PTE entry at %p.\n", (unsigned long *)pl1e);
  53.188 +        MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
  53.189          return GNTST_general_error;
  53.190      }
  53.191      
  53.192 @@ -2930,7 +2930,7 @@ int revalidate_l1(
  53.193  
  53.194          if ( unlikely(!get_page_from_l1e(nl1e, d)) )
  53.195          {
  53.196 -            MEM_LOG("ptwr: Could not re-validate l1 page\n");
  53.197 +            MEM_LOG("ptwr: Could not re-validate l1 page");
  53.198              /*
  53.199               * Make the remaining p.t's consistent before crashing, so the
  53.200               * reference counts are correct.
  53.201 @@ -3056,7 +3056,7 @@ static int ptwr_emulated_update(
  53.202      /* Aligned access only, thank you. */
  53.203      if ( !access_ok(addr, bytes) || ((addr & (bytes-1)) != 0) )
  53.204      {
  53.205 -        MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)\n",
  53.206 +        MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)",
  53.207                  bytes, addr);
  53.208          return X86EMUL_UNHANDLEABLE;
  53.209      }
  53.210 @@ -3089,7 +3089,7 @@ static int ptwr_emulated_update(
  53.211      if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
  53.212                           sizeof(pte)))
  53.213      {
  53.214 -        MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table\n");
  53.215 +        MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table");
  53.216          return X86EMUL_UNHANDLEABLE;
  53.217      }
  53.218  
  53.219 @@ -3102,7 +3102,7 @@ static int ptwr_emulated_update(
  53.220           (page_get_owner(page) != d) )
  53.221      {
  53.222          MEM_LOG("ptwr_emulate: Page is mistyped or bad pte "
  53.223 -                "(%lx, %" PRtype_info ")\n",
  53.224 +                "(%lx, %" PRtype_info ")",
  53.225                  l1e_get_pfn(pte), page->u.inuse.type_info);
  53.226          return X86EMUL_UNHANDLEABLE;
  53.227      }
    54.1 --- a/xen/arch/x86/vmx.c	Mon Aug 22 11:37:48 2005 -0700
    54.2 +++ b/xen/arch/x86/vmx.c	Tue Aug 23 12:03:21 2005 -0700
    54.3 @@ -1712,8 +1712,6 @@ asmlinkage void vmx_vmexit_handler(struc
    54.4      default:
    54.5          __vmx_bug(&regs);       /* should not happen */
    54.6      }
    54.7 -
    54.8 -    return;
    54.9  }
   54.10  
   54.11  asmlinkage void load_cr2(void)
    55.1 --- a/xen/arch/x86/vmx_io.c	Mon Aug 22 11:37:48 2005 -0700
    55.2 +++ b/xen/arch/x86/vmx_io.c	Tue Aug 23 12:03:21 2005 -0700
    55.3 @@ -631,7 +631,7 @@ static inline int irq_masked(unsigned lo
    55.4      return ((eflags & X86_EFLAGS_IF) == 0);
    55.5  }
    55.6  
    55.7 -asmlinkage void vmx_intr_assist() 
    55.8 +asmlinkage void vmx_intr_assist(void) 
    55.9  {
   55.10      int intr_type = 0;
   55.11      int highest_vector;
   55.12 @@ -714,8 +714,6 @@ void vmx_do_resume(struct vcpu *d)
   55.13  
   55.14      /* We can't resume the guest if we're waiting on I/O */
   55.15      ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags));
   55.16 -
   55.17 -    /* We always check for interrupts before resuming guest */
   55.18  }
   55.19  
   55.20  #endif /* CONFIG_VMX */
    56.1 --- a/xen/arch/x86/x86_32/traps.c	Mon Aug 22 11:37:48 2005 -0700
    56.2 +++ b/xen/arch/x86/x86_32/traps.c	Tue Aug 23 12:03:21 2005 -0700
    56.3 @@ -1,5 +1,6 @@
    56.4  
    56.5  #include <xen/config.h>
    56.6 +#include <xen/domain_page.h>
    56.7  #include <xen/init.h>
    56.8  #include <xen/sched.h>
    56.9  #include <xen/lib.h>
   56.10 @@ -86,24 +87,33 @@ void show_registers(struct cpu_user_regs
   56.11  
   56.12  void show_page_walk(unsigned long addr)
   56.13  {
   56.14 -    l2_pgentry_t pmd;
   56.15 -    l1_pgentry_t *pte;
   56.16 -
   56.17 -    if ( addr < PAGE_OFFSET )
   56.18 -        return;
   56.19 +    unsigned long pfn = read_cr3() >> PAGE_SHIFT;
   56.20 +    intpte_t *ptab, ent;
   56.21  
   56.22      printk("Pagetable walk from %08lx:\n", addr);
   56.23 -    
   56.24 -    pmd = idle_pg_table_l2[l2_linear_offset(addr)];
   56.25 -    printk(" L2 = %"PRIpte" %s\n", l2e_get_intpte(pmd),
   56.26 -           (l2e_get_flags(pmd) & _PAGE_PSE) ? "(2/4MB)" : "");
   56.27 -    if ( !(l2e_get_flags(pmd) & _PAGE_PRESENT) ||
   56.28 -         (l2e_get_flags(pmd) & _PAGE_PSE) )
   56.29 +
   56.30 +#ifdef CONFIG_X86_PAE
   56.31 +    ptab = map_domain_page(pfn);
   56.32 +    ent = ptab[l3_table_offset(addr)];
   56.33 +    printk(" L3 = %"PRIpte"\n", ent);
   56.34 +    unmap_domain_page(ptab);
   56.35 +    if ( !(ent & _PAGE_PRESENT) )
   56.36          return;
   56.37 +    pfn = ent >> PAGE_SHIFT;
   56.38 +#endif
   56.39  
   56.40 -    pte  = __va(l2e_get_paddr(pmd));
   56.41 -    pte += l1_table_offset(addr);
   56.42 -    printk("  L1 = %"PRIpte"\n", l1e_get_intpte(*pte));
   56.43 +    ptab = map_domain_page(pfn);
   56.44 +    ent = ptab[l2_table_offset(addr)];
   56.45 +    printk("  L2 = %"PRIpte" %s\n", ent, (ent & _PAGE_PSE) ? "(PSE)" : "");
   56.46 +    unmap_domain_page(ptab);
   56.47 +    if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
   56.48 +        return;
   56.49 +    pfn = ent >> PAGE_SHIFT;
   56.50 +
   56.51 +    ptab = map_domain_page(ent >> PAGE_SHIFT);
   56.52 +    ent = ptab[l2_table_offset(addr)];
   56.53 +    printk("   L1 = %"PRIpte"\n", ent);
   56.54 +    unmap_domain_page(ptab);
   56.55  }
   56.56  
   56.57  #define DOUBLEFAULT_STACK_SIZE 1024
    57.1 --- a/xen/include/asm-x86/vmx.h	Mon Aug 22 11:37:48 2005 -0700
    57.2 +++ b/xen/include/asm-x86/vmx.h	Tue Aug 23 12:03:21 2005 -0700
    57.3 @@ -31,7 +31,7 @@
    57.4  extern void vmx_asm_vmexit_handler(struct cpu_user_regs);
    57.5  extern void vmx_asm_do_resume(void);
    57.6  extern void vmx_asm_do_launch(void);
    57.7 -extern void vmx_intr_assist();
    57.8 +extern void vmx_intr_assist(void);
    57.9  
   57.10  extern void arch_vmx_do_launch(struct vcpu *);
   57.11  extern void arch_vmx_do_resume(struct vcpu *);
   57.12 @@ -355,7 +355,7 @@ static inline int __vmxon (u64 addr)
   57.13  }
   57.14  
   57.15  /* Make sure that xen intercepts any FP accesses from current */
   57.16 -static inline void vmx_stts()
   57.17 +static inline void vmx_stts(void)
   57.18  {
   57.19      unsigned long cr0;
   57.20  
    58.1 --- a/xen/include/public/io/blkif.h	Mon Aug 22 11:37:48 2005 -0700
    58.2 +++ b/xen/include/public/io/blkif.h	Tue Aug 23 12:03:21 2005 -0700
    58.3 @@ -58,6 +58,9 @@ typedef struct blkif_response {
    58.4  #define BLKIF_RSP_ERROR  -1 /* non-specific 'error' */
    58.5  #define BLKIF_RSP_OKAY    0 /* non-specific 'okay'  */
    58.6  
    58.7 +#define BLKIF_MAJOR(dev) ((dev)>>8)
    58.8 +#define BLKIF_MINOR(dev) ((dev) & 0xff)
    58.9 +
   58.10  /*
   58.11   * Generate blkif ring structures and types.
   58.12   */