ia64/xen-unstable

changeset 6531:1ae656509f02

Merge.
author adsharma@los-vmm.sc.intel.com
date Tue Aug 16 10:09:07 2005 -0800 (2005-08-16)
parents e3d811cca4e1 26c03c17c418
children dc93023f4221
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/misc/shype4xen_readme.txt docs/src/user.tex 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/entry.S linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S 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/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/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/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/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/x86_64/Kconfig linux-2.6-xen-sparse/arch/xen/x86_64/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/xen_entry.S linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/ioremap.c 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/control.c 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/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/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/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/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/dma-mapping.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/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 tools/Makefile 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/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/ioemu/hw/pckbd.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/policyprocessor/XmlToBinInterface.java 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/secpol_tool.c 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/xenstore/Makefile tools/xenstore/TODO tools/xenstore/testsuite/test.sh tools/xenstore/utils.c tools/xenstore/utils.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/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/grant_table.c xen/common/page_alloc.c xen/common/perfc.c xen/common/sched_sedf.c xen/common/symbols.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/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/vmx.h xen/include/asm-x86/vmx_virpit.h xen/include/asm-x86/vmx_vmcs.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/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/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/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Tue Aug 16 12:15:23 2005 +0800
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Tue Aug 16 10:09:07 2005 -0800
     1.3 @@ -130,6 +130,7 @@ CONFIG_PREEMPT_BKL=y
     1.4  # CONFIG_X86_REBOOTFIXUPS is not set
     1.5  CONFIG_MICROCODE=y
     1.6  CONFIG_X86_CPUID=y
     1.7 +CONFIG_SWIOTLB=y
     1.8  
     1.9  #
    1.10  # Firmware Drivers
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Tue Aug 16 12:15:23 2005 +0800
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Tue Aug 16 10:09:07 2005 -0800
     2.3 @@ -1,7 +1,7 @@
     2.4  #
     2.5  # Automatically generated make config: don't edit
     2.6 -# Linux kernel version: 2.6.12.3-xen0
     2.7 -# Mon Aug 15 11:36:25 2005
     2.8 +# Linux kernel version: 2.6.12.4-xen0
     2.9 +# Mon Aug 15 18:57:19 2005
    2.10  #
    2.11  CONFIG_XEN=y
    2.12  CONFIG_ARCH_XEN=y
    2.13 @@ -52,6 +52,7 @@ CONFIG_KOBJECT_UEVENT=y
    2.14  # CONFIG_IKCONFIG is not set
    2.15  # CONFIG_EMBEDDED is not set
    2.16  CONFIG_KALLSYMS=y
    2.17 +# CONFIG_KALLSYMS_ALL is not set
    2.18  # CONFIG_KALLSYMS_EXTRA_PASS is not set
    2.19  CONFIG_PRINTK=y
    2.20  CONFIG_BUG=y
    2.21 @@ -122,6 +123,7 @@ CONFIG_X86_XEN_GENAPIC=y
    2.22  # CONFIG_X86_MSR is not set
    2.23  # CONFIG_GART_IOMMU is not set
    2.24  CONFIG_DUMMY_IOMMU=y
    2.25 +CONFIG_SWIOTLB=y
    2.26  # CONFIG_X86_MCE is not set
    2.27  
    2.28  #
    2.29 @@ -163,6 +165,7 @@ CONFIG_BINFMT_MISC=y
    2.30  CONFIG_STANDALONE=y
    2.31  # CONFIG_PREVENT_FIRMWARE_BUILD is not set
    2.32  # CONFIG_FW_LOADER is not set
    2.33 +# CONFIG_DEBUG_DRIVER is not set
    2.34  
    2.35  #
    2.36  # Memory Technology Devices (MTD)
    2.37 @@ -1060,7 +1063,22 @@ CONFIG_ZLIB_INFLATE=y
    2.38  # Kernel hacking
    2.39  #
    2.40  # CONFIG_PRINTK_TIME is not set
    2.41 -# CONFIG_DEBUG_KERNEL is not set
    2.42 -CONFIG_LOG_BUF_SHIFT=14
    2.43 +CONFIG_DEBUG_KERNEL=y
    2.44 +CONFIG_MAGIC_SYSRQ=y
    2.45 +CONFIG_LOG_BUF_SHIFT=15
    2.46 +# CONFIG_SCHEDSTATS is not set
    2.47 +# CONFIG_DEBUG_SLAB is not set
    2.48 +# CONFIG_DEBUG_SPINLOCK is not set
    2.49 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
    2.50 +# CONFIG_DEBUG_KOBJECT is not set
    2.51 +# CONFIG_DEBUG_INFO is not set
    2.52 +# CONFIG_DEBUG_FS is not set
    2.53 +# CONFIG_DEBUG_STACKOVERFLOW is not set
    2.54 +# CONFIG_KPROBES is not set
    2.55 +# CONFIG_DEBUG_STACK_USAGE is not set
    2.56 +# CONFIG_DEBUG_PAGEALLOC is not set
    2.57 +# CONFIG_4KSTACKS is not set
    2.58  CONFIG_X86_FIND_SMP_CONFIG=y
    2.59  CONFIG_X86_MPPARSE=y
    2.60 +# CONFIG_CHECKING is not set
    2.61 +# CONFIG_INIT_DEBUG is not set
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Tue Aug 16 12:15:23 2005 +0800
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Tue Aug 16 10:09:07 2005 -0800
     3.3 @@ -1,7 +1,7 @@
     3.4  #
     3.5  # Automatically generated make config: don't edit
     3.6 -# Linux kernel version: 2.6.12-xenU
     3.7 -# Tue Aug  2 23:56:13 2005
     3.8 +# Linux kernel version: 2.6.12.4-xenU
     3.9 +# Mon Aug 15 19:25:22 2005
    3.10  #
    3.11  CONFIG_XEN=y
    3.12  CONFIG_ARCH_XEN=y
    3.13 @@ -30,7 +30,7 @@ CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
    3.14  #
    3.15  CONFIG_EXPERIMENTAL=y
    3.16  CONFIG_CLEAN_COMPILE=y
    3.17 -CONFIG_BROKEN_ON_SMP=y
    3.18 +CONFIG_LOCK_KERNEL=y
    3.19  CONFIG_INIT_ENV_ARG_LIMIT=32
    3.20  
    3.21  #
    3.22 @@ -48,8 +48,10 @@ CONFIG_AUDITSYSCALL=y
    3.23  CONFIG_HOTPLUG=y
    3.24  CONFIG_KOBJECT_UEVENT=y
    3.25  # CONFIG_IKCONFIG is not set
    3.26 +# CONFIG_CPUSETS is not set
    3.27  # CONFIG_EMBEDDED is not set
    3.28  CONFIG_KALLSYMS=y
    3.29 +# CONFIG_KALLSYMS_ALL is not set
    3.30  CONFIG_KALLSYMS_EXTRA_PASS=y
    3.31  CONFIG_PRINTK=y
    3.32  CONFIG_BUG=y
    3.33 @@ -74,6 +76,7 @@ CONFIG_OBSOLETE_MODPARM=y
    3.34  CONFIG_MODVERSIONS=y
    3.35  # CONFIG_MODULE_SRCVERSION_ALL is not set
    3.36  CONFIG_KMOD=y
    3.37 +CONFIG_STOP_MACHINE=y
    3.38  CONFIG_XENARCH="x86_64"
    3.39  CONFIG_X86=y
    3.40  CONFIG_MMU=y
    3.41 @@ -86,12 +89,15 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
    3.42  CONFIG_GENERIC_CALIBRATE_DELAY=y
    3.43  CONFIG_X86_GOOD_APIC=y
    3.44  # CONFIG_HPET_TIMER is not set
    3.45 -# CONFIG_SMP is not set
    3.46 +CONFIG_SMP=y
    3.47 +CONFIG_NR_CPUS=8
    3.48 +# CONFIG_SCHED_SMT is not set
    3.49  # CONFIG_PREEMPT is not set
    3.50  # CONFIG_MICROCODE is not set
    3.51  CONFIG_X86_CPUID=y
    3.52  # CONFIG_NUMA is not set
    3.53  # CONFIG_MTRR is not set
    3.54 +CONFIG_HAVE_DEC_LOCK=y
    3.55  # CONFIG_X86_LOCAL_APIC is not set
    3.56  # CONFIG_X86_IO_APIC is not set
    3.57  # CONFIG_PCI is not set
    3.58 @@ -114,7 +120,11 @@ CONFIG_MPSC=y
    3.59  # CONFIG_GENERIC_CPU is not set
    3.60  CONFIG_X86_L1_CACHE_BYTES=128
    3.61  # CONFIG_X86_TSC is not set
    3.62 +CONFIG_X86_XEN_GENAPIC=y
    3.63  # CONFIG_X86_MSR is not set
    3.64 +CONFIG_X86_HT=y
    3.65 +# CONFIG_K8_NUMA is not set
    3.66 +# CONFIG_NUMA_EMU is not set
    3.67  CONFIG_DUMMY_IOMMU=y
    3.68  # CONFIG_X86_MCE is not set
    3.69  
    3.70 @@ -157,6 +167,7 @@ CONFIG_BINFMT_MISC=y
    3.71  CONFIG_STANDALONE=y
    3.72  CONFIG_PREVENT_FIRMWARE_BUILD=y
    3.73  CONFIG_FW_LOADER=y
    3.74 +# CONFIG_DEBUG_DRIVER is not set
    3.75  
    3.76  #
    3.77  # Block devices
    3.78 @@ -559,7 +570,6 @@ CONFIG_ACT200L_DONGLE=m
    3.79  #
    3.80  # Old SIR device drivers
    3.81  #
    3.82 -# CONFIG_IRPORT_SIR is not set
    3.83  
    3.84  #
    3.85  # Old Serial dongle support
    3.86 @@ -861,17 +871,7 @@ CONFIG_NLS_UTF8=m
    3.87  # Security options
    3.88  #
    3.89  # CONFIG_KEYS is not set
    3.90 -CONFIG_SECURITY=y
    3.91 -CONFIG_SECURITY_NETWORK=y
    3.92 -CONFIG_SECURITY_CAPABILITIES=y
    3.93 -# CONFIG_SECURITY_SECLVL is not set
    3.94 -CONFIG_SECURITY_SELINUX=y
    3.95 -CONFIG_SECURITY_SELINUX_BOOTPARAM=y
    3.96 -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
    3.97 -CONFIG_SECURITY_SELINUX_DISABLE=y
    3.98 -CONFIG_SECURITY_SELINUX_DEVELOP=y
    3.99 -CONFIG_SECURITY_SELINUX_AVC_STATS=y
   3.100 -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
   3.101 +# CONFIG_SECURITY is not set
   3.102  
   3.103  #
   3.104  # Cryptographic options
   3.105 @@ -919,5 +919,19 @@ CONFIG_ZLIB_DEFLATE=m
   3.106  # Kernel hacking
   3.107  #
   3.108  # CONFIG_PRINTK_TIME is not set
   3.109 -# CONFIG_DEBUG_KERNEL is not set
   3.110 -CONFIG_LOG_BUF_SHIFT=14
   3.111 +CONFIG_DEBUG_KERNEL=y
   3.112 +CONFIG_MAGIC_SYSRQ=y
   3.113 +CONFIG_LOG_BUF_SHIFT=15
   3.114 +# CONFIG_SCHEDSTATS is not set
   3.115 +# CONFIG_DEBUG_SLAB is not set
   3.116 +# CONFIG_DEBUG_SPINLOCK is not set
   3.117 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
   3.118 +# CONFIG_DEBUG_KOBJECT is not set
   3.119 +# CONFIG_DEBUG_INFO is not set
   3.120 +# CONFIG_DEBUG_FS is not set
   3.121 +# CONFIG_DEBUG_STACKOVERFLOW is not set
   3.122 +# CONFIG_KPROBES is not set
   3.123 +# CONFIG_DEBUG_STACK_USAGE is not set
   3.124 +# CONFIG_DEBUG_PAGEALLOC is not set
   3.125 +# CONFIG_4KSTACKS is not set
   3.126 +# CONFIG_INIT_DEBUG is not set
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Tue Aug 16 12:15:23 2005 +0800
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Tue Aug 16 10:09:07 2005 -0800
     4.3 @@ -137,6 +137,7 @@ CONFIG_PREEMPT_BKL=y
     4.4  # CONFIG_X86_REBOOTFIXUPS is not set
     4.5  CONFIG_MICROCODE=m
     4.6  CONFIG_X86_CPUID=m
     4.7 +CONFIG_SWIOTLB=y
     4.8  
     4.9  #
    4.10  # Firmware Drivers
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Tue Aug 16 12:15:23 2005 +0800
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Tue Aug 16 10:09:07 2005 -0800
     5.3 @@ -1,7 +1,7 @@
     5.4  #
     5.5  # Automatically generated make config: don't edit
     5.6 -# Linux kernel version: 2.6.12.3-xen0
     5.7 -# Mon Aug 15 19:46:39 2005
     5.8 +# Linux kernel version: 2.6.12.4-xen
     5.9 +# Mon Aug 15 19:54:11 2005
    5.10  #
    5.11  CONFIG_XEN=y
    5.12  CONFIG_ARCH_XEN=y
    5.13 @@ -35,6 +35,7 @@ CONFIG_EXPERIMENTAL=y
    5.14  # CONFIG_CLEAN_COMPILE is not set
    5.15  CONFIG_BROKEN=y
    5.16  CONFIG_BROKEN_ON_SMP=y
    5.17 +CONFIG_LOCK_KERNEL=y
    5.18  CONFIG_INIT_ENV_ARG_LIMIT=32
    5.19  
    5.20  #
    5.21 @@ -50,8 +51,10 @@ CONFIG_SYSCTL=y
    5.22  CONFIG_HOTPLUG=y
    5.23  CONFIG_KOBJECT_UEVENT=y
    5.24  # CONFIG_IKCONFIG is not set
    5.25 +# CONFIG_CPUSETS is not set
    5.26  # CONFIG_EMBEDDED is not set
    5.27  CONFIG_KALLSYMS=y
    5.28 +# CONFIG_KALLSYMS_ALL is not set
    5.29  CONFIG_KALLSYMS_EXTRA_PASS=y
    5.30  CONFIG_PRINTK=y
    5.31  CONFIG_BUG=y
    5.32 @@ -76,6 +79,7 @@ CONFIG_OBSOLETE_MODPARM=y
    5.33  # CONFIG_MODVERSIONS is not set
    5.34  CONFIG_MODULE_SRCVERSION_ALL=y
    5.35  CONFIG_KMOD=y
    5.36 +CONFIG_STOP_MACHINE=y
    5.37  CONFIG_XENARCH="x86_64"
    5.38  CONFIG_X86=y
    5.39  CONFIG_MMU=y
    5.40 @@ -88,12 +92,15 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
    5.41  CONFIG_GENERIC_CALIBRATE_DELAY=y
    5.42  CONFIG_X86_GOOD_APIC=y
    5.43  # CONFIG_HPET_TIMER is not set
    5.44 -# CONFIG_SMP is not set
    5.45 +CONFIG_SMP=y
    5.46 +CONFIG_NR_CPUS=8
    5.47 +# CONFIG_SCHED_SMT is not set
    5.48  # CONFIG_PREEMPT is not set
    5.49  CONFIG_MICROCODE=y
    5.50  # CONFIG_X86_CPUID is not set
    5.51  # CONFIG_NUMA is not set
    5.52  # CONFIG_MTRR is not set
    5.53 +CONFIG_HAVE_DEC_LOCK=y
    5.54  CONFIG_X86_LOCAL_APIC=y
    5.55  CONFIG_X86_IO_APIC=y
    5.56  CONFIG_PCI=y
    5.57 @@ -120,8 +127,12 @@ CONFIG_X86_L1_CACHE_BYTES=128
    5.58  # CONFIG_X86_TSC is not set
    5.59  CONFIG_X86_XEN_GENAPIC=y
    5.60  # CONFIG_X86_MSR is not set
    5.61 +CONFIG_X86_HT=y
    5.62 +# CONFIG_K8_NUMA is not set
    5.63 +# CONFIG_NUMA_EMU is not set
    5.64  # CONFIG_GART_IOMMU is not set
    5.65  CONFIG_DUMMY_IOMMU=y
    5.66 +CONFIG_SWIOTLB=y
    5.67  # CONFIG_X86_MCE is not set
    5.68  
    5.69  #
    5.70 @@ -163,6 +174,7 @@ CONFIG_BINFMT_MISC=y
    5.71  CONFIG_STANDALONE=y
    5.72  CONFIG_PREVENT_FIRMWARE_BUILD=y
    5.73  CONFIG_FW_LOADER=y
    5.74 +# CONFIG_DEBUG_DRIVER is not set
    5.75  
    5.76  #
    5.77  # Memory Technology Devices (MTD)
    5.78 @@ -214,7 +226,6 @@ CONFIG_MTD_RAM=m
    5.79  CONFIG_MTD_ROM=m
    5.80  CONFIG_MTD_ABSENT=m
    5.81  # CONFIG_MTD_OBSOLETE_CHIPS is not set
    5.82 -# CONFIG_MTD_XIP is not set
    5.83  
    5.84  #
    5.85  # Mapping drivers for chip access
    5.86 @@ -2395,7 +2406,21 @@ CONFIG_ZLIB_DEFLATE=m
    5.87  # Kernel hacking
    5.88  #
    5.89  # CONFIG_PRINTK_TIME is not set
    5.90 -# CONFIG_DEBUG_KERNEL is not set
    5.91 -CONFIG_LOG_BUF_SHIFT=14
    5.92 +CONFIG_DEBUG_KERNEL=y
    5.93 +CONFIG_MAGIC_SYSRQ=y
    5.94 +CONFIG_LOG_BUF_SHIFT=15
    5.95 +# CONFIG_SCHEDSTATS is not set
    5.96 +# CONFIG_DEBUG_SLAB is not set
    5.97 +# CONFIG_DEBUG_SPINLOCK is not set
    5.98 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
    5.99 +# CONFIG_DEBUG_KOBJECT is not set
   5.100 +# CONFIG_DEBUG_INFO is not set
   5.101 +# CONFIG_DEBUG_FS is not set
   5.102 +# CONFIG_DEBUG_STACKOVERFLOW is not set
   5.103 +# CONFIG_KPROBES is not set
   5.104 +# CONFIG_DEBUG_STACK_USAGE is not set
   5.105 +# CONFIG_DEBUG_PAGEALLOC is not set
   5.106 +# CONFIG_4KSTACKS is not set
   5.107  CONFIG_X86_FIND_SMP_CONFIG=y
   5.108  CONFIG_X86_MPPARSE=y
   5.109 +# CONFIG_INIT_DEBUG is not set
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/Kconfig	Tue Aug 16 12:15:23 2005 +0800
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/Kconfig	Tue Aug 16 10:09:07 2005 -0800
     6.3 @@ -533,6 +533,11 @@ config X86_CPUID
     6.4  	  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
     6.5  	  /dev/cpu/31/cpuid.
     6.6  
     6.7 +config SWIOTLB
     6.8 +       bool
     6.9 +       depends on PCI
    6.10 +       default y
    6.11 +
    6.12  source "drivers/firmware/Kconfig"
    6.13  
    6.14  choice
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile	Tue Aug 16 12:15:23 2005 +0800
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile	Tue Aug 16 10:09:07 2005 -0800
     7.3 @@ -44,6 +44,7 @@ c-obj-$(CONFIG_HPET_TIMER) 	+= time_hpet
     7.4  c-obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
     7.5  c-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
     7.6  c-obj-$(CONFIG_SMP_ALTERNATIVES)+= smpalts.o
     7.7 +c-obj-$(CONFIG_SWIOTLB)		+= swiotlb.o
     7.8  
     7.9  EXTRA_AFLAGS   := -traditional
    7.10  
     8.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Tue Aug 16 12:15:23 2005 +0800
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Tue Aug 16 10:09:07 2005 -0800
     8.3 @@ -24,6 +24,103 @@ struct dma_coherent_mem {
     8.4  	unsigned long	*bitmap;
     8.5  };
     8.6  
     8.7 +static void iommu_bug(void)
     8.8 +{
     8.9 +	printk(KERN_ALERT "Fatal DMA error! Please use 'swiotlb=force'\n");
    8.10 +	BUG();
    8.11 +}
    8.12 +
    8.13 +#define IOMMU_BUG_ON(test) do { if (unlikely(test)) iommu_bug(); } while(0)
    8.14 +
    8.15 +int
    8.16 +dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
    8.17 +	   enum dma_data_direction direction)
    8.18 +{
    8.19 +	int i, rc;
    8.20 +
    8.21 +	BUG_ON(direction == DMA_NONE);
    8.22 +
    8.23 +	if (swiotlb) {
    8.24 +		rc = swiotlb_map_sg(hwdev, sg, nents, direction);
    8.25 +	} else {
    8.26 +		for (i = 0; i < nents; i++ ) {
    8.27 +			sg[i].dma_address =
    8.28 +				page_to_phys(sg[i].page) + sg[i].offset;
    8.29 +			sg[i].dma_length  = sg[i].length;
    8.30 +			BUG_ON(!sg[i].page);
    8.31 +			IOMMU_BUG_ON(address_needs_mapping(
    8.32 +				hwdev, sg[i].dma_address));
    8.33 +		}
    8.34 +		rc = nents;
    8.35 +	}
    8.36 +
    8.37 +	flush_write_buffers();
    8.38 +	return rc;
    8.39 +}
    8.40 +EXPORT_SYMBOL(dma_map_sg);
    8.41 +
    8.42 +void
    8.43 +dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
    8.44 +	     enum dma_data_direction direction)
    8.45 +{
    8.46 +	BUG_ON(direction == DMA_NONE);
    8.47 +	if (swiotlb)
    8.48 +		swiotlb_unmap_sg(hwdev, sg, nents, direction);
    8.49 +}
    8.50 +EXPORT_SYMBOL(dma_unmap_sg);
    8.51 +
    8.52 +dma_addr_t
    8.53 +dma_map_page(struct device *dev, struct page *page, unsigned long offset,
    8.54 +	     size_t size, enum dma_data_direction direction)
    8.55 +{
    8.56 +	dma_addr_t dma_addr;
    8.57 +
    8.58 +	BUG_ON(direction == DMA_NONE);
    8.59 +
    8.60 +	if (swiotlb) {
    8.61 +		dma_addr = swiotlb_map_page(
    8.62 +			dev, page, offset, size, direction);
    8.63 +	} else {
    8.64 +		dma_addr = page_to_phys(page) + offset;
    8.65 +		IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
    8.66 +	}
    8.67 +
    8.68 +	return dma_addr;
    8.69 +}
    8.70 +EXPORT_SYMBOL(dma_map_page);
    8.71 +
    8.72 +void
    8.73 +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
    8.74 +	       enum dma_data_direction direction)
    8.75 +{
    8.76 +	BUG_ON(direction == DMA_NONE);
    8.77 +	if (swiotlb)
    8.78 +		swiotlb_unmap_page(dev, dma_address, size, direction);
    8.79 +}
    8.80 +EXPORT_SYMBOL(dma_unmap_page);
    8.81 +
    8.82 +int
    8.83 +dma_mapping_error(dma_addr_t dma_addr)
    8.84 +{
    8.85 +	if (swiotlb)
    8.86 +		return swiotlb_dma_mapping_error(dma_addr);
    8.87 +	return 0;
    8.88 +}
    8.89 +EXPORT_SYMBOL(dma_mapping_error);
    8.90 +
    8.91 +int
    8.92 +dma_supported(struct device *dev, u64 mask)
    8.93 +{
    8.94 +	if (swiotlb)
    8.95 +		return swiotlb_dma_supported(dev, mask);
    8.96 +	/*
    8.97 +         * By default we'll BUG when an infeasible DMA is requested, and
    8.98 +         * request swiotlb=force (see IOMMU_BUG_ON).
    8.99 +         */
   8.100 +	return 1;
   8.101 +}
   8.102 +EXPORT_SYMBOL(dma_supported);
   8.103 +
   8.104  void *dma_alloc_coherent(struct device *dev, size_t size,
   8.105  			   dma_addr_t *dma_handle, unsigned int __nocast gfp)
   8.106  {
   8.107 @@ -54,13 +151,14 @@ void *dma_alloc_coherent(struct device *
   8.108  	ret = (void *)vstart;
   8.109  
   8.110  	if (ret != NULL) {
   8.111 -		xen_contig_memory(vstart, order);
   8.112 +		xen_create_contiguous_region(vstart, order);
   8.113  
   8.114  		memset(ret, 0, size);
   8.115  		*dma_handle = virt_to_bus(ret);
   8.116  	}
   8.117  	return ret;
   8.118  }
   8.119 +EXPORT_SYMBOL(dma_alloc_coherent);
   8.120  
   8.121  void dma_free_coherent(struct device *dev, size_t size,
   8.122  			 void *vaddr, dma_addr_t dma_handle)
   8.123 @@ -72,9 +170,12 @@ void dma_free_coherent(struct device *de
   8.124  		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
   8.125  
   8.126  		bitmap_release_region(mem->bitmap, page, order);
   8.127 -	} else
   8.128 +	} else {
   8.129 +		xen_destroy_contiguous_region((unsigned long)vaddr, order);
   8.130  		free_pages((unsigned long)vaddr, order);
   8.131 +	}
   8.132  }
   8.133 +EXPORT_SYMBOL(dma_free_coherent);
   8.134  
   8.135  int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
   8.136  				dma_addr_t device_addr, size_t size, int flags)
   8.137 @@ -153,46 +254,20 @@ void *dma_mark_declared_memory_occupied(
   8.138  }
   8.139  EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
   8.140  
   8.141 -static LIST_HEAD(dma_map_head);
   8.142 -static DEFINE_SPINLOCK(dma_map_lock);
   8.143 -struct dma_map_entry {
   8.144 -	struct list_head list;
   8.145 -	dma_addr_t dma;
   8.146 -	char *bounce, *host;
   8.147 -	size_t size;
   8.148 -};
   8.149 -#define DMA_MAP_MATCHES(e,d) (((e)->dma<=(d)) && (((e)->dma+(e)->size)>(d)))
   8.150 -
   8.151  dma_addr_t
   8.152  dma_map_single(struct device *dev, void *ptr, size_t size,
   8.153  	       enum dma_data_direction direction)
   8.154  {
   8.155 -	struct dma_map_entry *ent;
   8.156 -	void *bnc;
   8.157  	dma_addr_t dma;
   8.158 -	unsigned long flags;
   8.159  
   8.160  	BUG_ON(direction == DMA_NONE);
   8.161  
   8.162 -	/*
   8.163 -	 * Even if size is sub-page, the buffer may still straddle a page
   8.164 -	 * boundary. Take into account buffer start offset. All other calls are
   8.165 -	 * conservative and always search the dma_map list if it's non-empty.
   8.166 -	 */
   8.167 -	if ((((unsigned int)ptr & ~PAGE_MASK) + size) <= PAGE_SIZE) {
   8.168 -		dma = virt_to_bus(ptr);
   8.169 +	if (swiotlb) {
   8.170 +		dma = swiotlb_map_single(dev, ptr, size, direction);
   8.171  	} else {
   8.172 -		BUG_ON((bnc = dma_alloc_coherent(dev, size, &dma, GFP_ATOMIC)) == NULL);
   8.173 -		BUG_ON((ent = kmalloc(sizeof(*ent), GFP_ATOMIC)) == NULL);
   8.174 -		if (direction != DMA_FROM_DEVICE)
   8.175 -			memcpy(bnc, ptr, size);
   8.176 -		ent->dma    = dma;
   8.177 -		ent->bounce = bnc;
   8.178 -		ent->host   = ptr;
   8.179 -		ent->size   = size;
   8.180 -		spin_lock_irqsave(&dma_map_lock, flags);
   8.181 -		list_add(&ent->list, &dma_map_head);
   8.182 -		spin_unlock_irqrestore(&dma_map_lock, flags);
   8.183 +		dma = virt_to_bus(ptr);
   8.184 +		IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size));
   8.185 +		IOMMU_BUG_ON(address_needs_mapping(dev, dma));
   8.186  	}
   8.187  
   8.188  	flush_write_buffers();
   8.189 @@ -204,30 +279,9 @@ void
   8.190  dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
   8.191  		 enum dma_data_direction direction)
   8.192  {
   8.193 -	struct dma_map_entry *ent;
   8.194 -	unsigned long flags;
   8.195 -
   8.196  	BUG_ON(direction == DMA_NONE);
   8.197 -
   8.198 -	/* Fast-path check: are there any multi-page DMA mappings? */
   8.199 -	if (!list_empty(&dma_map_head)) {
   8.200 -		spin_lock_irqsave(&dma_map_lock, flags);
   8.201 -		list_for_each_entry ( ent, &dma_map_head, list ) {
   8.202 -			if (DMA_MAP_MATCHES(ent, dma_addr)) {
   8.203 -				list_del(&ent->list);
   8.204 -				break;
   8.205 -			}
   8.206 -		}
   8.207 -		spin_unlock_irqrestore(&dma_map_lock, flags);
   8.208 -		if (&ent->list != &dma_map_head) {
   8.209 -			BUG_ON(dma_addr != ent->dma);
   8.210 -			BUG_ON(size != ent->size);
   8.211 -			if (direction != DMA_TO_DEVICE)
   8.212 -				memcpy(ent->host, ent->bounce, size);
   8.213 -			dma_free_coherent(dev, size, ent->bounce, ent->dma);
   8.214 -			kfree(ent);
   8.215 -		}
   8.216 -	}
   8.217 +	if (swiotlb)
   8.218 +		swiotlb_unmap_single(dev, dma_addr, size, direction);
   8.219  }
   8.220  EXPORT_SYMBOL(dma_unmap_single);
   8.221  
   8.222 @@ -235,23 +289,8 @@ void
   8.223  dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
   8.224  			enum dma_data_direction direction)
   8.225  {
   8.226 -	struct dma_map_entry *ent;
   8.227 -	unsigned long flags, off;
   8.228 -
   8.229 -	/* Fast-path check: are there any multi-page DMA mappings? */
   8.230 -	if (!list_empty(&dma_map_head)) {
   8.231 -		spin_lock_irqsave(&dma_map_lock, flags);
   8.232 -		list_for_each_entry ( ent, &dma_map_head, list )
   8.233 -			if (DMA_MAP_MATCHES(ent, dma_handle))
   8.234 -				break;
   8.235 -		spin_unlock_irqrestore(&dma_map_lock, flags);
   8.236 -		if (&ent->list != &dma_map_head) {
   8.237 -			off = dma_handle - ent->dma;
   8.238 -			BUG_ON((off + size) > ent->size);
   8.239 -			/*if (direction != DMA_TO_DEVICE)*/
   8.240 -				memcpy(ent->host+off, ent->bounce+off, size);
   8.241 -		}
   8.242 -	}
   8.243 +	if (swiotlb)
   8.244 +		swiotlb_sync_single_for_cpu(dev, dma_handle, size, direction);
   8.245  }
   8.246  EXPORT_SYMBOL(dma_sync_single_for_cpu);
   8.247  
   8.248 @@ -259,24 +298,17 @@ void
   8.249  dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
   8.250                             enum dma_data_direction direction)
   8.251  {
   8.252 -	struct dma_map_entry *ent;
   8.253 -	unsigned long flags, off;
   8.254 -
   8.255 -	/* Fast-path check: are there any multi-page DMA mappings? */
   8.256 -	if (!list_empty(&dma_map_head)) {
   8.257 -		spin_lock_irqsave(&dma_map_lock, flags);
   8.258 -		list_for_each_entry ( ent, &dma_map_head, list )
   8.259 -			if (DMA_MAP_MATCHES(ent, dma_handle))
   8.260 -				break;
   8.261 -		spin_unlock_irqrestore(&dma_map_lock, flags);
   8.262 -		if (&ent->list != &dma_map_head) {
   8.263 -			off = dma_handle - ent->dma;
   8.264 -			BUG_ON((off + size) > ent->size);
   8.265 -			/*if (direction != DMA_FROM_DEVICE)*/
   8.266 -				memcpy(ent->bounce+off, ent->host+off, size);
   8.267 -		}
   8.268 -	}
   8.269 -
   8.270 -	flush_write_buffers();
   8.271 +	if (swiotlb)
   8.272 +		swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
   8.273  }
   8.274  EXPORT_SYMBOL(dma_sync_single_for_device);
   8.275 +
   8.276 +/*
   8.277 + * Local variables:
   8.278 + *  c-file-style: "linux"
   8.279 + *  indent-tabs-mode: t
   8.280 + *  c-indent-level: 8
   8.281 + *  c-basic-offset: 8
   8.282 + *  tab-width: 8
   8.283 + * End:
   8.284 + */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c	Tue Aug 16 10:09:07 2005 -0800
     9.3 @@ -0,0 +1,653 @@
     9.4 +/*
     9.5 + * Dynamic DMA mapping support.
     9.6 + *
     9.7 + * This implementation is a fallback for platforms that do not support
     9.8 + * I/O TLBs (aka DMA address translation hardware).
     9.9 + * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
    9.10 + * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
    9.11 + * Copyright (C) 2000, 2003 Hewlett-Packard Co
    9.12 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    9.13 + * Copyright (C) 2005 Keir Fraser <keir@xensource.com>
    9.14 + */
    9.15 +
    9.16 +#include <linux/cache.h>
    9.17 +#include <linux/mm.h>
    9.18 +#include <linux/module.h>
    9.19 +#include <linux/pci.h>
    9.20 +#include <linux/spinlock.h>
    9.21 +#include <linux/string.h>
    9.22 +#include <linux/types.h>
    9.23 +#include <linux/ctype.h>
    9.24 +#include <linux/init.h>
    9.25 +#include <linux/bootmem.h>
    9.26 +#include <linux/highmem.h>
    9.27 +#include <asm/io.h>
    9.28 +#include <asm/pci.h>
    9.29 +#include <asm/dma.h>
    9.30 +
    9.31 +#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
    9.32 +
    9.33 +#define SG_ENT_PHYS_ADDRESS(sg)	(page_to_phys((sg)->page) + (sg)->offset)
    9.34 +
    9.35 +/*
    9.36 + * Maximum allowable number of contiguous slabs to map,
    9.37 + * must be a power of 2.  What is the appropriate value ?
    9.38 + * The complexity of {map,unmap}_single is linearly dependent on this value.
    9.39 + */
    9.40 +#define IO_TLB_SEGSIZE	128
    9.41 +
    9.42 +/*
    9.43 + * log of the size of each IO TLB slab.  The number of slabs is command line
    9.44 + * controllable.
    9.45 + */
    9.46 +#define IO_TLB_SHIFT 11
    9.47 +
    9.48 +int swiotlb_force;
    9.49 +
    9.50 +/*
    9.51 + * Used to do a quick range check in swiotlb_unmap_single and
    9.52 + * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
    9.53 + * API.
    9.54 + */
    9.55 +static char *io_tlb_start, *io_tlb_end;
    9.56 +
    9.57 +/*
    9.58 + * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
    9.59 + * io_tlb_end.  This is command line adjustable via setup_io_tlb_npages.
    9.60 + */
    9.61 +static unsigned long io_tlb_nslabs;
    9.62 +
    9.63 +/*
    9.64 + * When the IOMMU overflows we return a fallback buffer. This sets the size.
    9.65 + */
    9.66 +static unsigned long io_tlb_overflow = 32*1024;
    9.67 +
    9.68 +void *io_tlb_overflow_buffer;
    9.69 +
    9.70 +/*
    9.71 + * This is a free list describing the number of free entries available from
    9.72 + * each index
    9.73 + */
    9.74 +static unsigned int *io_tlb_list;
    9.75 +static unsigned int io_tlb_index;
    9.76 +
    9.77 +/*
    9.78 + * We need to save away the original address corresponding to a mapped entry
    9.79 + * for the sync operations.
    9.80 + */
    9.81 +static struct phys_addr {
    9.82 +	struct page *page;
    9.83 +	unsigned int offset;
    9.84 +} *io_tlb_orig_addr;
    9.85 +
    9.86 +/*
    9.87 + * Protect the above data structures in the map and unmap calls
    9.88 + */
    9.89 +static DEFINE_SPINLOCK(io_tlb_lock);
    9.90 +
    9.91 +static int __init
    9.92 +setup_io_tlb_npages(char *str)
    9.93 +{
    9.94 +	if (isdigit(*str)) {
    9.95 +		io_tlb_nslabs = simple_strtoul(str, &str, 0) <<
    9.96 +			(PAGE_SHIFT - IO_TLB_SHIFT);
    9.97 +		/* avoid tail segment of size < IO_TLB_SEGSIZE */
    9.98 +		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
    9.99 +	}
   9.100 +	if (*str == ',')
   9.101 +		++str;
   9.102 +	/*
   9.103 +         * NB. 'force' enables the swiotlb, but doesn't force its use for
   9.104 +         * every DMA like it does on native Linux.
   9.105 +         */
   9.106 +	if (!strcmp(str, "force"))
   9.107 +		swiotlb_force = 1;
   9.108 +	return 1;
   9.109 +}
   9.110 +__setup("swiotlb=", setup_io_tlb_npages);
   9.111 +/* make io_tlb_overflow tunable too? */
   9.112 +
   9.113 +/*
   9.114 + * Statically reserve bounce buffer space and initialize bounce buffer data
   9.115 + * structures for the software IO TLB used to implement the PCI DMA API.
   9.116 + */
   9.117 +void
   9.118 +swiotlb_init_with_default_size (size_t default_size)
   9.119 +{
   9.120 +	unsigned long i;
   9.121 +
   9.122 +	if (!io_tlb_nslabs) {
   9.123 +		io_tlb_nslabs = (default_size >> PAGE_SHIFT);
   9.124 +		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
   9.125 +	}
   9.126 +
   9.127 +	/*
   9.128 +	 * Get IO TLB memory from the low pages
   9.129 +	 */
   9.130 +	io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs *
   9.131 +					       (1 << IO_TLB_SHIFT));
   9.132 +	if (!io_tlb_start)
   9.133 +		panic("Cannot allocate SWIOTLB buffer");
   9.134 +
   9.135 +	xen_create_contiguous_region(
   9.136 +		(unsigned long)io_tlb_start, 
   9.137 +		get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT)));
   9.138 +
   9.139 +	io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
   9.140 +
   9.141 +	/*
   9.142 +	 * Allocate and initialize the free list array.  This array is used
   9.143 +	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
   9.144 +	 * between io_tlb_start and io_tlb_end.
   9.145 +	 */
   9.146 +	io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int));
   9.147 +	for (i = 0; i < io_tlb_nslabs; i++)
   9.148 + 		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
   9.149 +	io_tlb_index = 0;
   9.150 +	io_tlb_orig_addr = alloc_bootmem(
   9.151 +		io_tlb_nslabs * sizeof(*io_tlb_orig_addr));
   9.152 +
   9.153 +	/*
   9.154 +	 * Get the overflow emergency buffer
   9.155 +	 */
   9.156 +	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
   9.157 +	printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
   9.158 +	       virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end-1));
   9.159 +}
   9.160 +
   9.161 +void
   9.162 +swiotlb_init(void)
   9.163 +{
   9.164 +	/* The user can forcibly enable swiotlb. */
   9.165 +	if (swiotlb_force)
   9.166 +		swiotlb = 1;
   9.167 +
   9.168 +	/*
   9.169 +         * Otherwise, enable for domain 0 if the machine has 'lots of memory',
   9.170 +         * which we take to mean more than 2GB.
   9.171 +         */
   9.172 +	if (xen_start_info.flags & SIF_INITDOMAIN) {
   9.173 +		dom0_op_t op;
   9.174 +		op.cmd = DOM0_PHYSINFO;
   9.175 +		if ((HYPERVISOR_dom0_op(&op) == 0) &&
   9.176 +		    (op.u.physinfo.total_pages > 0x7ffff))
   9.177 +			swiotlb = 1;
   9.178 +	}
   9.179 +
   9.180 +	if (swiotlb)
   9.181 +		swiotlb_init_with_default_size(64 * (1<<20));
   9.182 +}
   9.183 +
   9.184 +static void
   9.185 +__sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
   9.186 +{
   9.187 +	if (PageHighMem(buffer.page)) {
   9.188 +		size_t len, bytes;
   9.189 +		char *dev, *host, *kmp;
   9.190 +		len = size;
   9.191 +		while (len != 0) {
   9.192 +			if (((bytes = len) + buffer.offset) > PAGE_SIZE)
   9.193 +				bytes = PAGE_SIZE - buffer.offset;
   9.194 +			kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
   9.195 +			dev  = dma_addr + size - len;
   9.196 +			host = kmp + buffer.offset;
   9.197 +			memcpy((dir == DMA_FROM_DEVICE) ? host : dev,
   9.198 +			       (dir == DMA_FROM_DEVICE) ? dev : host,
   9.199 +			       bytes);
   9.200 +			kunmap_atomic(kmp, KM_SWIOTLB);
   9.201 +			len -= bytes;
   9.202 +			buffer.page++;
   9.203 +			buffer.offset = 0;
   9.204 +		}
   9.205 +	} else {
   9.206 +		char *host = (char *)phys_to_virt(
   9.207 +			page_to_pseudophys(buffer.page)) + buffer.offset;
   9.208 +		if (dir == DMA_FROM_DEVICE)
   9.209 +			memcpy(host, dma_addr, size);
   9.210 +		else if (dir == DMA_TO_DEVICE)
   9.211 +			memcpy(dma_addr, host, size);
   9.212 +	}
   9.213 +}
   9.214 +
   9.215 +/*
   9.216 + * Allocates bounce buffer and returns its kernel virtual address.
   9.217 + */
   9.218 +static void *
   9.219 +map_single(struct device *hwdev, struct phys_addr buffer, size_t size, int dir)
   9.220 +{
   9.221 +	unsigned long flags;
   9.222 +	char *dma_addr;
   9.223 +	unsigned int nslots, stride, index, wrap;
   9.224 +	int i;
   9.225 +
   9.226 +	/*
   9.227 +	 * For mappings greater than a page, we limit the stride (and
   9.228 +	 * hence alignment) to a page size.
   9.229 +	 */
   9.230 +	nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
   9.231 +	if (size > PAGE_SIZE)
   9.232 +		stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
   9.233 +	else
   9.234 +		stride = 1;
   9.235 +
   9.236 +	BUG_ON(!nslots);
   9.237 +
   9.238 +	/*
   9.239 +	 * Find suitable number of IO TLB entries size that will fit this
   9.240 +	 * request and allocate a buffer from that IO TLB pool.
   9.241 +	 */
   9.242 +	spin_lock_irqsave(&io_tlb_lock, flags);
   9.243 +	{
   9.244 +		wrap = index = ALIGN(io_tlb_index, stride);
   9.245 +
   9.246 +		if (index >= io_tlb_nslabs)
   9.247 +			wrap = index = 0;
   9.248 +
   9.249 +		do {
   9.250 +			/*
   9.251 +			 * If we find a slot that indicates we have 'nslots'
   9.252 +			 * number of contiguous buffers, we allocate the
   9.253 +			 * buffers from that slot and mark the entries as '0'
   9.254 +			 * indicating unavailable.
   9.255 +			 */
   9.256 +			if (io_tlb_list[index] >= nslots) {
   9.257 +				int count = 0;
   9.258 +
   9.259 +				for (i = index; i < (int)(index + nslots); i++)
   9.260 +					io_tlb_list[i] = 0;
   9.261 +				for (i = index - 1;
   9.262 +				     (OFFSET(i, IO_TLB_SEGSIZE) !=
   9.263 +				      IO_TLB_SEGSIZE -1) && io_tlb_list[i];
   9.264 +				     i--)
   9.265 +					io_tlb_list[i] = ++count;
   9.266 +				dma_addr = io_tlb_start +
   9.267 +					(index << IO_TLB_SHIFT);
   9.268 +
   9.269 +				/*
   9.270 +				 * Update the indices to avoid searching in
   9.271 +				 * the next round.
   9.272 +				 */
   9.273 +				io_tlb_index = 
   9.274 +					((index + nslots) < io_tlb_nslabs
   9.275 +					 ? (index + nslots) : 0);
   9.276 +
   9.277 +				goto found;
   9.278 +			}
   9.279 +			index += stride;
   9.280 +			if (index >= io_tlb_nslabs)
   9.281 +				index = 0;
   9.282 +		} while (index != wrap);
   9.283 +
   9.284 +		spin_unlock_irqrestore(&io_tlb_lock, flags);
   9.285 +		return NULL;
   9.286 +	}
   9.287 +  found:
   9.288 +	spin_unlock_irqrestore(&io_tlb_lock, flags);
   9.289 +
   9.290 +	/*
   9.291 +	 * Save away the mapping from the original address to the DMA address.
   9.292 +	 * This is needed when we sync the memory.  Then we sync the buffer if
   9.293 +	 * needed.
   9.294 +	 */
   9.295 +	io_tlb_orig_addr[index] = buffer;
   9.296 +	if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL))
   9.297 +		__sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
   9.298 +
   9.299 +	return dma_addr;
   9.300 +}
   9.301 +
   9.302 +/*
   9.303 + * dma_addr is the kernel virtual address of the bounce buffer to unmap.
   9.304 + */
   9.305 +static void
   9.306 +unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
   9.307 +{
   9.308 +	unsigned long flags;
   9.309 +	int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
   9.310 +	int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
   9.311 +	struct phys_addr buffer = io_tlb_orig_addr[index];
   9.312 +
   9.313 +	/*
   9.314 +	 * First, sync the memory before unmapping the entry
   9.315 +	 */
   9.316 +	if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))
   9.317 +		__sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE);
   9.318 +
   9.319 +	/*
   9.320 +	 * Return the buffer to the free list by setting the corresponding
   9.321 +	 * entries to indicate the number of contigous entries available.
   9.322 +	 * While returning the entries to the free list, we merge the entries
   9.323 +	 * with slots below and above the pool being returned.
   9.324 +	 */
   9.325 +	spin_lock_irqsave(&io_tlb_lock, flags);
   9.326 +	{
   9.327 +		count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
   9.328 +			 io_tlb_list[index + nslots] : 0);
   9.329 +		/*
   9.330 +		 * Step 1: return the slots to the free list, merging the
   9.331 +		 * slots with superceeding slots
   9.332 +		 */
   9.333 +		for (i = index + nslots - 1; i >= index; i--)
   9.334 +			io_tlb_list[i] = ++count;
   9.335 +		/*
   9.336 +		 * Step 2: merge the returned slots with the preceding slots,
   9.337 +		 * if available (non zero)
   9.338 +		 */
   9.339 +		for (i = index - 1;
   9.340 +		     (OFFSET(i, IO_TLB_SEGSIZE) !=
   9.341 +		      IO_TLB_SEGSIZE -1) && io_tlb_list[i];
   9.342 +		     i--)
   9.343 +			io_tlb_list[i] = ++count;
   9.344 +	}
   9.345 +	spin_unlock_irqrestore(&io_tlb_lock, flags);
   9.346 +}
   9.347 +
   9.348 +static void
   9.349 +sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
   9.350 +{
   9.351 +	int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
   9.352 +	struct phys_addr buffer = io_tlb_orig_addr[index];
   9.353 +	BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
   9.354 +	__sync_single(buffer, dma_addr, size, dir);
   9.355 +}
   9.356 +
   9.357 +static void
   9.358 +swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
   9.359 +{
   9.360 +	/*
   9.361 +	 * Ran out of IOMMU space for this operation. This is very bad.
   9.362 +	 * Unfortunately the drivers cannot handle this operation properly.
   9.363 +	 * unless they check for pci_dma_mapping_error (most don't)
   9.364 +	 * When the mapping is small enough return a static buffer to limit
   9.365 +	 * the damage, or panic when the transfer is too big.
   9.366 +	 */
   9.367 +	printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
   9.368 +	       "device %s\n", (unsigned long)size, dev ? dev->bus_id : "?");
   9.369 +
   9.370 +	if (size > io_tlb_overflow && do_panic) {
   9.371 +		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
   9.372 +			panic("PCI-DMA: Memory would be corrupted\n");
   9.373 +		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
   9.374 +			panic("PCI-DMA: Random memory would be DMAed\n");
   9.375 +	}
   9.376 +}
   9.377 +
   9.378 +/*
   9.379 + * Map a single buffer of the indicated size for DMA in streaming mode.  The
   9.380 + * PCI address to use is returned.
   9.381 + *
   9.382 + * Once the device is given the dma address, the device owns this memory until
   9.383 + * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
   9.384 + */
   9.385 +dma_addr_t
   9.386 +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
   9.387 +{
   9.388 +	dma_addr_t dev_addr = virt_to_bus(ptr);
   9.389 +	void *map;
   9.390 +	struct phys_addr buffer;
   9.391 +
   9.392 +	BUG_ON(dir == DMA_NONE);
   9.393 +
   9.394 +	/*
   9.395 +	 * If the pointer passed in happens to be in the device's DMA window,
   9.396 +	 * we can safely return the device addr and not worry about bounce
   9.397 +	 * buffering it.
   9.398 +	 */
   9.399 +	if (!range_straddles_page_boundary(ptr, size) &&
   9.400 +	    !address_needs_mapping(hwdev, dev_addr))
   9.401 +		return dev_addr;
   9.402 +
   9.403 +	/*
   9.404 +	 * Oh well, have to allocate and map a bounce buffer.
   9.405 +	 */
   9.406 +	buffer.page   = virt_to_page(ptr);
   9.407 +	buffer.offset = (unsigned long)ptr & ~PAGE_MASK;
   9.408 +	map = map_single(hwdev, buffer, size, dir);
   9.409 +	if (!map) {
   9.410 +		swiotlb_full(hwdev, size, dir, 1);
   9.411 +		map = io_tlb_overflow_buffer;
   9.412 +	}
   9.413 +
   9.414 +	dev_addr = virt_to_bus(map);
   9.415 +
   9.416 +	/*
   9.417 +	 * Ensure that the address returned is DMA'ble
   9.418 +	 */
   9.419 +	if (address_needs_mapping(hwdev, dev_addr))
   9.420 +		panic("map_single: bounce buffer is not DMA'ble");
   9.421 +
   9.422 +	return dev_addr;
   9.423 +}
   9.424 +
   9.425 +/*
   9.426 + * Unmap a single streaming mode DMA translation.  The dma_addr and size must
   9.427 + * match what was provided for in a previous swiotlb_map_single call.  All
   9.428 + * other usages are undefined.
   9.429 + *
   9.430 + * After this call, reads by the cpu to the buffer are guaranteed to see
   9.431 + * whatever the device wrote there.
   9.432 + */
   9.433 +void
   9.434 +swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
   9.435 +		     int dir)
   9.436 +{
   9.437 +	char *dma_addr = bus_to_virt(dev_addr);
   9.438 +
   9.439 +	BUG_ON(dir == DMA_NONE);
   9.440 +	if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
   9.441 +		unmap_single(hwdev, dma_addr, size, dir);
   9.442 +}
   9.443 +
   9.444 +/*
   9.445 + * Make physical memory consistent for a single streaming mode DMA translation
   9.446 + * after a transfer.
   9.447 + *
   9.448 + * If you perform a swiotlb_map_single() but wish to interrogate the buffer
   9.449 + * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
   9.450 + * call this function before doing so.  At the next point you give the PCI dma
   9.451 + * address back to the card, you must first perform a
   9.452 + * swiotlb_dma_sync_for_device, and then the device again owns the buffer
   9.453 + */
   9.454 +void
   9.455 +swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
   9.456 +			    size_t size, int dir)
   9.457 +{
   9.458 +	char *dma_addr = bus_to_virt(dev_addr);
   9.459 +
   9.460 +	BUG_ON(dir == DMA_NONE);
   9.461 +	if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
   9.462 +		sync_single(hwdev, dma_addr, size, dir);
   9.463 +}
   9.464 +
   9.465 +void
   9.466 +swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
   9.467 +			       size_t size, int dir)
   9.468 +{
   9.469 +	char *dma_addr = bus_to_virt(dev_addr);
   9.470 +
   9.471 +	BUG_ON(dir == DMA_NONE);
   9.472 +	if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
   9.473 +		sync_single(hwdev, dma_addr, size, dir);
   9.474 +}
   9.475 +
   9.476 +/*
   9.477 + * Map a set of buffers described by scatterlist in streaming mode for DMA.
   9.478 + * This is the scatter-gather version of the above swiotlb_map_single
   9.479 + * interface.  Here the scatter gather list elements are each tagged with the
   9.480 + * appropriate dma address and length.  They are obtained via
   9.481 + * sg_dma_{address,length}(SG).
   9.482 + *
   9.483 + * NOTE: An implementation may be able to use a smaller number of
   9.484 + *       DMA address/length pairs than there are SG table elements.
   9.485 + *       (for example via virtual mapping capabilities)
   9.486 + *       The routine returns the number of addr/length pairs actually
   9.487 + *       used, at most nents.
   9.488 + *
   9.489 + * Device ownership issues as mentioned above for swiotlb_map_single are the
   9.490 + * same here.
   9.491 + */
   9.492 +int
   9.493 +swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
   9.494 +	       int dir)
   9.495 +{
   9.496 +	struct phys_addr buffer;
   9.497 +	dma_addr_t dev_addr;
   9.498 +	char *map;
   9.499 +	int i;
   9.500 +
   9.501 +	BUG_ON(dir == DMA_NONE);
   9.502 +
   9.503 +	for (i = 0; i < nelems; i++, sg++) {
   9.504 +		dev_addr = SG_ENT_PHYS_ADDRESS(sg);
   9.505 +		if (address_needs_mapping(hwdev, dev_addr)) {
   9.506 +			buffer.page   = sg->page;
   9.507 +			buffer.offset = sg->offset;
   9.508 +			map = map_single(hwdev, buffer, sg->length, dir);
   9.509 +			if (!map) {
   9.510 +				/* Don't panic here, we expect map_sg users
   9.511 +				   to do proper error handling. */
   9.512 +				swiotlb_full(hwdev, sg->length, dir, 0);
   9.513 +				swiotlb_unmap_sg(hwdev, sg - i, i, dir);
   9.514 +				sg[0].dma_length = 0;
   9.515 +				return 0;
   9.516 +			}
   9.517 +			sg->dma_address = (dma_addr_t)virt_to_bus(map);
   9.518 +		} else
   9.519 +			sg->dma_address = dev_addr;
   9.520 +		sg->dma_length = sg->length;
   9.521 +	}
   9.522 +	return nelems;
   9.523 +}
   9.524 +
   9.525 +/*
   9.526 + * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
   9.527 + * concerning calls here are the same as for swiotlb_unmap_single() above.
   9.528 + */
   9.529 +void
   9.530 +swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
   9.531 +		 int dir)
   9.532 +{
   9.533 +	int i;
   9.534 +
   9.535 +	BUG_ON(dir == DMA_NONE);
   9.536 +
   9.537 +	for (i = 0; i < nelems; i++, sg++)
   9.538 +		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
   9.539 +			unmap_single(hwdev, 
   9.540 +				     (void *)bus_to_virt(sg->dma_address),
   9.541 +				     sg->dma_length, dir);
   9.542 +}
   9.543 +
   9.544 +/*
   9.545 + * Make physical memory consistent for a set of streaming mode DMA translations
   9.546 + * after a transfer.
   9.547 + *
   9.548 + * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
   9.549 + * and usage.
   9.550 + */
   9.551 +void
   9.552 +swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
   9.553 +			int nelems, int dir)
   9.554 +{
   9.555 +	int i;
   9.556 +
   9.557 +	BUG_ON(dir == DMA_NONE);
   9.558 +
   9.559 +	for (i = 0; i < nelems; i++, sg++)
   9.560 +		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
   9.561 +			sync_single(hwdev,
   9.562 +				    (void *)bus_to_virt(sg->dma_address),
   9.563 +				    sg->dma_length, dir);
   9.564 +}
   9.565 +
   9.566 +void
   9.567 +swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
   9.568 +			   int nelems, int dir)
   9.569 +{
   9.570 +	int i;
   9.571 +
   9.572 +	BUG_ON(dir == DMA_NONE);
   9.573 +
   9.574 +	for (i = 0; i < nelems; i++, sg++)
   9.575 +		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
   9.576 +			sync_single(hwdev,
   9.577 +				    (void *)bus_to_virt(sg->dma_address),
   9.578 +				    sg->dma_length, dir);
   9.579 +}
   9.580 +
   9.581 +dma_addr_t
   9.582 +swiotlb_map_page(struct device *hwdev, struct page *page,
   9.583 +		 unsigned long offset, size_t size,
   9.584 +		 enum dma_data_direction direction)
   9.585 +{
   9.586 +	struct phys_addr buffer;
   9.587 +	dma_addr_t dev_addr;
   9.588 +	char *map;
   9.589 +
   9.590 +	dev_addr = page_to_phys(page) + offset;
   9.591 +	if (address_needs_mapping(hwdev, dev_addr)) {
   9.592 +		buffer.page   = page;
   9.593 +		buffer.offset = offset;
   9.594 +		map = map_single(hwdev, buffer, size, direction);
   9.595 +		if (!map) {
   9.596 +			swiotlb_full(hwdev, size, direction, 1);
   9.597 +			map = io_tlb_overflow_buffer;
   9.598 +		}
   9.599 +		dev_addr = (dma_addr_t)virt_to_bus(map);
   9.600 +	}
   9.601 +
   9.602 +	return dev_addr;
   9.603 +}
   9.604 +
   9.605 +void
   9.606 +swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
   9.607 +		   size_t size, enum dma_data_direction direction)
   9.608 +{
   9.609 +	char *dma_addr = bus_to_virt(dma_address);
   9.610 +
   9.611 +	BUG_ON(direction == DMA_NONE);
   9.612 +	if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
   9.613 +		unmap_single(hwdev, dma_addr, size, direction);
   9.614 +}
   9.615 +
   9.616 +int
   9.617 +swiotlb_dma_mapping_error(dma_addr_t dma_addr)
   9.618 +{
   9.619 +	return (dma_addr == virt_to_bus(io_tlb_overflow_buffer));
   9.620 +}
   9.621 +
   9.622 +/*
   9.623 + * Return whether the given PCI device DMA address mask can be supported
   9.624 + * properly.  For example, if your device can only drive the low 24-bits
   9.625 + * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
   9.626 + * this function.
   9.627 + */
   9.628 +int
   9.629 +swiotlb_dma_supported (struct device *hwdev, u64 mask)
   9.630 +{
   9.631 +	return (mask >= 0xffffffffUL);
   9.632 +}
   9.633 +
   9.634 +EXPORT_SYMBOL(swiotlb_init);
   9.635 +EXPORT_SYMBOL(swiotlb_map_single);
   9.636 +EXPORT_SYMBOL(swiotlb_unmap_single);
   9.637 +EXPORT_SYMBOL(swiotlb_map_sg);
   9.638 +EXPORT_SYMBOL(swiotlb_unmap_sg);
   9.639 +EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
   9.640 +EXPORT_SYMBOL(swiotlb_sync_single_for_device);
   9.641 +EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
   9.642 +EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
   9.643 +EXPORT_SYMBOL(swiotlb_map_page);
   9.644 +EXPORT_SYMBOL(swiotlb_unmap_page);
   9.645 +EXPORT_SYMBOL(swiotlb_dma_mapping_error);
   9.646 +EXPORT_SYMBOL(swiotlb_dma_supported);
   9.647 +
   9.648 +/*
   9.649 + * Local variables:
   9.650 + *  c-file-style: "linux"
   9.651 + *  indent-tabs-mode: t
   9.652 + *  c-indent-level: 8
   9.653 + *  c-basic-offset: 8
   9.654 + *  tab-width: 8
   9.655 + * End:
   9.656 + */
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Aug 16 12:15:23 2005 +0800
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Aug 16 10:09:07 2005 -0800
    10.3 @@ -540,17 +540,14 @@ unsigned long profile_pc(struct pt_regs 
    10.4  EXPORT_SYMBOL(profile_pc);
    10.5  #endif
    10.6  
    10.7 -/*
    10.8 - * timer_interrupt() needs to keep up the real-time clock,
    10.9 - * as well as call the "do_timer()" routine every clocktick
   10.10 - */
   10.11 -static inline void do_timer_interrupt(int irq, void *dev_id,
   10.12 -					struct pt_regs *regs)
   10.13 +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   10.14  {
   10.15  	s64 delta, delta_cpu;
   10.16  	int cpu = smp_processor_id();
   10.17  	struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
   10.18  
   10.19 +	write_seqlock(&xtime_lock);
   10.20 +
   10.21  	do {
   10.22  		get_time_values_from_xen();
   10.23  
   10.24 @@ -572,7 +569,6 @@ static inline void do_timer_interrupt(in
   10.25  		for (cpu = 0; cpu < num_online_cpus(); cpu++)
   10.26  			printk(" %d: %lld\n", cpu,
   10.27  			       per_cpu(processed_system_time, cpu));
   10.28 -		return;
   10.29  	}
   10.30  
   10.31  	/* System-wide jiffy work. */
   10.32 @@ -582,7 +578,18 @@ static inline void do_timer_interrupt(in
   10.33  		do_timer(regs);
   10.34  	}
   10.35  
   10.36 -	/* Local CPU jiffy work. */
   10.37 +	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
   10.38 +		update_wallclock();
   10.39 +		clock_was_set();
   10.40 +	}
   10.41 +
   10.42 +	write_sequnlock(&xtime_lock);
   10.43 +
   10.44 +	/*
   10.45 +         * Local CPU jiffy work. No need to hold xtime_lock, and I'm not sure
   10.46 +         * if there is risk of deadlock if we do (since update_process_times
   10.47 +         * may do scheduler rebalancing work and thus acquire runqueue locks).
   10.48 +         */
   10.49  	while (delta_cpu >= NS_PER_TICK) {
   10.50  		delta_cpu -= NS_PER_TICK;
   10.51  		per_cpu(processed_system_time, cpu) += NS_PER_TICK;
   10.52 @@ -590,29 +597,6 @@ static inline void do_timer_interrupt(in
   10.53  		profile_tick(CPU_PROFILING, regs);
   10.54  	}
   10.55  
   10.56 -	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
   10.57 -		update_wallclock();
   10.58 -		clock_was_set();
   10.59 -	}
   10.60 -}
   10.61 -
   10.62 -/*
   10.63 - * This is the same as the above, except we _also_ save the current
   10.64 - * Time Stamp Counter value at the time of the timer interrupt, so that
   10.65 - * we later on can estimate the time of day more exactly.
   10.66 - */
   10.67 -irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   10.68 -{
   10.69 -	/*
   10.70 -	 * Here we are in the timer irq handler. We just have irqs locally
   10.71 -	 * disabled but we don't know if the timer_bh is running on the other
   10.72 -	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
   10.73 -	 * the irq version of write_lock because as just said we have irq
   10.74 -	 * locally disabled. -arca
   10.75 -	 */
   10.76 -	write_seqlock(&xtime_lock);
   10.77 -	do_timer_interrupt(irq, NULL, regs);
   10.78 -	write_sequnlock(&xtime_lock);
   10.79  	return IRQ_HANDLED;
   10.80  }
   10.81  
    11.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Tue Aug 16 12:15:23 2005 +0800
    11.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Tue Aug 16 10:09:07 2005 -0800
    11.3 @@ -263,12 +263,9 @@ void xen_set_ldt(unsigned long ptr, unsi
    11.4      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
    11.5  }
    11.6  
    11.7 -void xen_contig_memory(unsigned long vstart, unsigned int order)
    11.8 +/* Ensure multi-page extents are contiguous in machine memory. */
    11.9 +void xen_create_contiguous_region(unsigned long vstart, unsigned int order)
   11.10  {
   11.11 -    /*
   11.12 -     * Ensure multi-page extents are contiguous in machine memory. This code 
   11.13 -     * could be cleaned up some, and the number of hypercalls reduced.
   11.14 -     */
   11.15      pgd_t         *pgd; 
   11.16      pud_t         *pud; 
   11.17      pmd_t         *pmd;
   11.18 @@ -312,6 +309,49 @@ void xen_contig_memory(unsigned long vst
   11.19      balloon_unlock(flags);
   11.20  }
   11.21  
   11.22 +void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
   11.23 +{
   11.24 +    pgd_t         *pgd; 
   11.25 +    pud_t         *pud; 
   11.26 +    pmd_t         *pmd;
   11.27 +    pte_t         *pte;
   11.28 +    unsigned long  mfn, i, flags;
   11.29 +
   11.30 +    scrub_pages(vstart, 1 << order);
   11.31 +
   11.32 +    balloon_lock(flags);
   11.33 +
   11.34 +    /* 1. Zap current PTEs, giving away the underlying pages. */
   11.35 +    for (i = 0; i < (1<<order); i++) {
   11.36 +        pgd = pgd_offset_k(vstart + (i*PAGE_SIZE));
   11.37 +        pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
   11.38 +        pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
   11.39 +        pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
   11.40 +        mfn = pte_mfn(*pte);
   11.41 +        BUG_ON(HYPERVISOR_update_va_mapping(
   11.42 +            vstart + (i*PAGE_SIZE), __pte_ma(0), 0));
   11.43 +        phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
   11.44 +            INVALID_P2M_ENTRY;
   11.45 +        BUG_ON(HYPERVISOR_dom_mem_op(
   11.46 +            MEMOP_decrease_reservation, &mfn, 1, 0) != 1);
   11.47 +    }
   11.48 +
   11.49 +    /* 2. Map new pages in place of old pages. */
   11.50 +    for (i = 0; i < (1<<order); i++) {
   11.51 +        BUG_ON(HYPERVISOR_dom_mem_op(
   11.52 +            MEMOP_increase_reservation, &mfn, 1, 0) != 1);
   11.53 +        BUG_ON(HYPERVISOR_update_va_mapping(
   11.54 +            vstart + (i*PAGE_SIZE),
   11.55 +            __pte_ma((mfn<<PAGE_SHIFT)|__PAGE_KERNEL), 0));
   11.56 +        xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
   11.57 +        phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn;
   11.58 +    }
   11.59 +
   11.60 +    flush_tlb_all();
   11.61 +
   11.62 +    balloon_unlock(flags);
   11.63 +}
   11.64 +
   11.65  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
   11.66  
   11.67  unsigned long allocate_empty_lowmem_region(unsigned long pages)
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Tue Aug 16 12:15:23 2005 +0800
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Tue Aug 16 10:09:07 2005 -0800
    12.3 @@ -41,6 +41,12 @@
    12.4  #include <asm/sections.h>
    12.5  #include <asm-xen/hypervisor.h>
    12.6  
    12.7 +#if defined(CONFIG_SWIOTLB)
    12.8 +extern void swiotlb_init(void);
    12.9 +int swiotlb;
   12.10 +EXPORT_SYMBOL(swiotlb);
   12.11 +#endif
   12.12 +
   12.13  unsigned int __VMALLOC_RESERVE = 128 << 20;
   12.14  
   12.15  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
   12.16 @@ -631,6 +637,10 @@ void __init mem_init(void)
   12.17  	int bad_ppro;
   12.18  	unsigned long pfn;
   12.19  
   12.20 +#if defined(CONFIG_SWIOTLB)
   12.21 +	swiotlb_init();	
   12.22 +#endif
   12.23 +
   12.24  #ifndef CONFIG_DISCONTIGMEM
   12.25  	if (!mem_map)
   12.26  		BUG();
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Aug 16 12:15:23 2005 +0800
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Aug 16 10:09:07 2005 -0800
    13.3 @@ -332,10 +332,10 @@ int direct_remap_area_pages(struct mm_st
    13.4  	for (i = 0; i < size; i += PAGE_SIZE) {
    13.5  		if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
    13.6  			/* Fill in the PTE pointers. */
    13.7 -                        generic_page_range(mm, start_address, 
    13.8 -                                           address-start_address,
    13.9 -                                           direct_remap_area_pte_fn, &w);
   13.10 - 
   13.11 +			generic_page_range(mm, start_address, 
   13.12 +					   address - start_address,
   13.13 +					   direct_remap_area_pte_fn, &w);
   13.14 +			w = u;
   13.15  			if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
   13.16  				return -EFAULT;
   13.17  			v = u;
   13.18 @@ -355,9 +355,8 @@ int direct_remap_area_pages(struct mm_st
   13.19  
   13.20  	if (v != u) {
   13.21  		/* get the ptep's filled in */
   13.22 -                generic_page_range(mm, start_address, 
   13.23 -                                   address-start_address,
   13.24 -                                   direct_remap_area_pte_fn, &w);
   13.25 +		generic_page_range(mm, start_address, address - start_address,
   13.26 +				   direct_remap_area_pte_fn, &w);
   13.27  		if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
   13.28  			return -EFAULT;
   13.29  	}
   13.30 @@ -370,32 +369,34 @@ int direct_remap_area_pages(struct mm_st
   13.31  EXPORT_SYMBOL(direct_remap_area_pages);
   13.32  
   13.33  int create_lookup_pte_addr(struct mm_struct *mm, 
   13.34 -                           unsigned long address,
   13.35 -                           unsigned long *ptep)
   13.36 +			   unsigned long address,
   13.37 +			   unsigned long *ptep)
   13.38  {
   13.39 -    int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data) 
   13.40 -    {
   13.41 -        unsigned long *ptep = (unsigned long *)data;
   13.42 -        if (ptep) *ptep = (pfn_to_mfn(page_to_pfn(pte_page)) << PAGE_SHIFT)
   13.43 -                       | ((unsigned long)pte & ~PAGE_MASK);
   13.44 -        return 0;
   13.45 -    }
   13.46 +	int f(pte_t *pte, struct page *pte_page, unsigned long addr,
   13.47 +	      void *data) {
   13.48 +		unsigned long *ptep = (unsigned long *)data;
   13.49 +		if (ptep)
   13.50 +			*ptep = (pfn_to_mfn(page_to_pfn(pte_page)) <<
   13.51 +				 PAGE_SHIFT) |
   13.52 +				((unsigned long)pte & ~PAGE_MASK);
   13.53 +		return 0;
   13.54 +	}
   13.55  
   13.56 -    return generic_page_range(mm, address, PAGE_SIZE, f, ptep);
   13.57 +	return generic_page_range(mm, address, PAGE_SIZE, f, ptep);
   13.58  }
   13.59  
   13.60  EXPORT_SYMBOL(create_lookup_pte_addr);
   13.61  
   13.62  int touch_pte_range(struct mm_struct *mm,
   13.63 -                    unsigned long address,
   13.64 -                    unsigned long size)
   13.65 +		    unsigned long address,
   13.66 +		    unsigned long size)
   13.67  {
   13.68 -    int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data) 
   13.69 -    {
   13.70 -        return 0;
   13.71 -    }
   13.72 +	int f(pte_t *pte, struct page *pte_page, unsigned long addr,
   13.73 +	      void *data) {
   13.74 +		return 0;
   13.75 +	}
   13.76  
   13.77 -    return generic_page_range(mm, address, size, f, NULL);
   13.78 +	return generic_page_range(mm, address, size, f, NULL);
   13.79  }                 
   13.80  
   13.81  EXPORT_SYMBOL(touch_pte_range);
    14.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Tue Aug 16 12:15:23 2005 +0800
    14.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Tue Aug 16 10:09:07 2005 -0800
    14.3 @@ -277,7 +277,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
    14.4  
    14.5  #ifdef CONFIG_X86_PAE
    14.6  	/* this gives us a page below 4GB */
    14.7 -	xen_contig_memory((unsigned long)pgd, 0);
    14.8 +	xen_create_contiguous_region((unsigned long)pgd, 0);
    14.9  #endif
   14.10  
   14.11  	if (!HAVE_SHARED_KERNEL_PMD)
    15.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig	Tue Aug 16 12:15:23 2005 +0800
    15.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig	Tue Aug 16 10:09:07 2005 -0800
    15.3 @@ -329,12 +329,12 @@ config GART_IOMMU
    15.4  # need this always enabled with GART_IOMMU for the VIA workaround
    15.5  config SWIOTLB
    15.6         bool
    15.7 -       depends on GART_IOMMU
    15.8 +       depends on PCI
    15.9         default y
   15.10  
   15.11  config DUMMY_IOMMU
   15.12  	bool
   15.13 -	depends on !GART_IOMMU && !SWIOTLB
   15.14 +	depends on !GART_IOMMU
   15.15  	default y
   15.16  	help
   15.17  	  Don't use IOMMU code. This will cause problems when you have more than 4GB
    16.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Tue Aug 16 12:15:23 2005 +0800
    16.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Tue Aug 16 10:09:07 2005 -0800
    16.3 @@ -36,8 +36,9 @@ c-obj-$(CONFIG_X86_IO_APIC)	+= genapic_c
    16.4  #obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
    16.5  #obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
    16.6  #obj-$(CONFIG_GART_IOMMU)	+= pci-gart.o aperture.o
    16.7 -obj-$(CONFIG_DUMMY_IOMMU)	+= pci-nommu.o pci-dma.o
    16.8 -#obj-$(CONFIG_SWIOTLB)		+= swiotlb.o
    16.9 +obj-$(CONFIG_DUMMY_IOMMU)	+= pci-nommu.o
   16.10 +i386-obj-$(CONFIG_DUMMY_IOMMU)	+= pci-dma.o
   16.11 +i386-obj-$(CONFIG_SWIOTLB)	+= swiotlb.o
   16.12  obj-$(CONFIG_KPROBES)		+= kprobes.o
   16.13  obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer.o
   16.14  
   16.15 @@ -49,7 +50,7 @@ c-obj-y				+= intel_cacheinfo.o
   16.16  bootflag-y			+= ../../../i386/kernel/bootflag.o
   16.17  cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../../i386/kernel/cpuid.o
   16.18  topology-y                     += ../../../i386/mach-default/topology.o
   16.19 -swiotlb-$(CONFIG_SWIOTLB)      += ../../../ia64/lib/swiotlb.o
   16.20 +#swiotlb-$(CONFIG_SWIOTLB)      += ../../../ia64/lib/swiotlb.o
   16.21  microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../../i386/kernel/microcode.o
   16.22  intel_cacheinfo-y		+= ../../../i386/kernel/cpu/intel_cacheinfo.o
   16.23  quirks-y			+= ../../i386/kernel/quirks.o
    17.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/pci-dma.c	Tue Aug 16 12:15:23 2005 +0800
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,336 +0,0 @@
    17.4 -/*
    17.5 - * Dynamic DMA mapping support.
    17.6 - */
    17.7 -
    17.8 -#include <linux/types.h>
    17.9 -#include <linux/mm.h>
   17.10 -#include <linux/string.h>
   17.11 -#include <linux/pci.h>
   17.12 -#include <linux/module.h>
   17.13 -#include <asm/io.h>
   17.14 -#include <asm-xen/balloon.h>
   17.15 -
   17.16 -/* Map a set of buffers described by scatterlist in streaming
   17.17 - * mode for DMA.  This is the scatter-gather version of the
   17.18 - * above pci_map_single interface.  Here the scatter gather list
   17.19 - * elements are each tagged with the appropriate dma address
   17.20 - * and length.  They are obtained via sg_dma_{address,length}(SG).
   17.21 - *
   17.22 - * NOTE: An implementation may be able to use a smaller number of
   17.23 - *       DMA address/length pairs than there are SG table elements.
   17.24 - *       (for example via virtual mapping capabilities)
   17.25 - *       The routine returns the number of addr/length pairs actually
   17.26 - *       used, at most nents.
   17.27 - *
   17.28 - * Device ownership issues as mentioned above for pci_map_single are
   17.29 - * the same here.
   17.30 - */
   17.31 -int dma_map_sg(struct device *hwdev, struct scatterlist *sg,
   17.32 -	       int nents, int direction)
   17.33 -{
   17.34 -	int i;
   17.35 -
   17.36 -	BUG_ON(direction == DMA_NONE);
   17.37 - 	for (i = 0; i < nents; i++ ) {
   17.38 -		struct scatterlist *s = &sg[i];
   17.39 -		BUG_ON(!s->page); 
   17.40 -		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
   17.41 -		s->dma_length = s->length;
   17.42 -	}
   17.43 -	return nents;
   17.44 -}
   17.45 -
   17.46 -EXPORT_SYMBOL(dma_map_sg);
   17.47 -
   17.48 -/* Unmap a set of streaming mode DMA translations.
   17.49 - * Again, cpu read rules concerning calls here are the same as for
   17.50 - * pci_unmap_single() above.
   17.51 - */
   17.52 -void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
   17.53 -		  int nents, int dir)
   17.54 -{
   17.55 -	int i;
   17.56 -	for (i = 0; i < nents; i++) { 
   17.57 -		struct scatterlist *s = &sg[i];
   17.58 -		BUG_ON(s->page == NULL); 
   17.59 -		BUG_ON(s->dma_address == 0); 
   17.60 -		dma_unmap_single(dev, s->dma_address, s->dma_length, dir);
   17.61 -	} 
   17.62 -}
   17.63 -
   17.64 -EXPORT_SYMBOL(dma_unmap_sg);
   17.65 -
   17.66 -struct dma_coherent_mem {
   17.67 -	void		*virt_base;
   17.68 -	u32		device_base;
   17.69 -	int		size;
   17.70 -	int		flags;
   17.71 -	unsigned long	*bitmap;
   17.72 -};
   17.73 -
   17.74 -void *dma_alloc_coherent(struct device *dev, size_t size,
   17.75 -			   dma_addr_t *dma_handle, unsigned gfp)
   17.76 -{
   17.77 -	void *ret;
   17.78 -	unsigned int order = get_order(size);
   17.79 -	unsigned long vstart;
   17.80 -
   17.81 -	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
   17.82 -
   17.83 -	/* ignore region specifiers */
   17.84 -	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
   17.85 -
   17.86 -	if (mem) {
   17.87 -		int page = bitmap_find_free_region(mem->bitmap, mem->size,
   17.88 -						     order);
   17.89 -		if (page >= 0) {
   17.90 -			*dma_handle = mem->device_base + (page << PAGE_SHIFT);
   17.91 -			ret = mem->virt_base + (page << PAGE_SHIFT);
   17.92 -			memset(ret, 0, size);
   17.93 -			return ret;
   17.94 -		}
   17.95 -		if (mem->flags & DMA_MEMORY_EXCLUSIVE)
   17.96 -			return NULL;
   17.97 -	}
   17.98 -
   17.99 -	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
  17.100 -		gfp |= GFP_DMA;
  17.101 -
  17.102 -	vstart = __get_free_pages(gfp, order);
  17.103 -	ret = (void *)vstart;
  17.104 -	if (ret == NULL)
  17.105 -		return ret;
  17.106 -
  17.107 -	xen_contig_memory(vstart, order);
  17.108 -
  17.109 -	memset(ret, 0, size);
  17.110 -	*dma_handle = virt_to_bus(ret);
  17.111 -
  17.112 -	return ret;
  17.113 -}
  17.114 -EXPORT_SYMBOL(dma_alloc_coherent);
  17.115 -
  17.116 -void dma_free_coherent(struct device *dev, size_t size,
  17.117 -			 void *vaddr, dma_addr_t dma_handle)
  17.118 -{
  17.119 -	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
  17.120 -	int order = get_order(size);
  17.121 -	
  17.122 -	if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
  17.123 -		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
  17.124 -
  17.125 -		bitmap_release_region(mem->bitmap, page, order);
  17.126 -	} else
  17.127 -		free_pages((unsigned long)vaddr, order);
  17.128 -}
  17.129 -EXPORT_SYMBOL(dma_free_coherent);
  17.130 -
  17.131 -#if 0
  17.132 -int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
  17.133 -				dma_addr_t device_addr, size_t size, int flags)
  17.134 -{
  17.135 -	void __iomem *mem_base;
  17.136 -	int pages = size >> PAGE_SHIFT;
  17.137 -	int bitmap_size = (pages + 31)/32;
  17.138 -
  17.139 -	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
  17.140 -		goto out;
  17.141 -	if (!size)
  17.142 -		goto out;
  17.143 -	if (dev->dma_mem)
  17.144 -		goto out;
  17.145 -
  17.146 -	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
  17.147 -
  17.148 -	mem_base = ioremap(bus_addr, size);
  17.149 -	if (!mem_base)
  17.150 -		goto out;
  17.151 -
  17.152 -	dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
  17.153 -	if (!dev->dma_mem)
  17.154 -		goto out;
  17.155 -	memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem));
  17.156 -	dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL);
  17.157 -	if (!dev->dma_mem->bitmap)
  17.158 -		goto free1_out;
  17.159 -	memset(dev->dma_mem->bitmap, 0, bitmap_size);
  17.160 -
  17.161 -	dev->dma_mem->virt_base = mem_base;
  17.162 -	dev->dma_mem->device_base = device_addr;
  17.163 -	dev->dma_mem->size = pages;
  17.164 -	dev->dma_mem->flags = flags;
  17.165 -
  17.166 -	if (flags & DMA_MEMORY_MAP)
  17.167 -		return DMA_MEMORY_MAP;
  17.168 -
  17.169 -	return DMA_MEMORY_IO;
  17.170 -
  17.171 - free1_out:
  17.172 -	kfree(dev->dma_mem->bitmap);
  17.173 - out:
  17.174 -	return 0;
  17.175 -}
  17.176 -EXPORT_SYMBOL(dma_declare_coherent_memory);
  17.177 -
  17.178 -void dma_release_declared_memory(struct device *dev)
  17.179 -{
  17.180 -	struct dma_coherent_mem *mem = dev->dma_mem;
  17.181 -	
  17.182 -	if(!mem)
  17.183 -		return;
  17.184 -	dev->dma_mem = NULL;
  17.185 -	iounmap(mem->virt_base);
  17.186 -	kfree(mem->bitmap);
  17.187 -	kfree(mem);
  17.188 -}
  17.189 -EXPORT_SYMBOL(dma_release_declared_memory);
  17.190 -
  17.191 -void *dma_mark_declared_memory_occupied(struct device *dev,
  17.192 -					dma_addr_t device_addr, size_t size)
  17.193 -{
  17.194 -	struct dma_coherent_mem *mem = dev->dma_mem;
  17.195 -	int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
  17.196 -	int pos, err;
  17.197 -
  17.198 -	if (!mem)
  17.199 -		return ERR_PTR(-EINVAL);
  17.200 -
  17.201 -	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
  17.202 -	err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
  17.203 -	if (err != 0)
  17.204 -		return ERR_PTR(err);
  17.205 -	return mem->virt_base + (pos << PAGE_SHIFT);
  17.206 -}
  17.207 -EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
  17.208 -#endif
  17.209 -
  17.210 -static LIST_HEAD(dma_map_head);
  17.211 -static DEFINE_SPINLOCK(dma_map_lock);
  17.212 -struct dma_map_entry {
  17.213 -	struct list_head list;
  17.214 -	dma_addr_t dma;
  17.215 -	char *bounce, *host;
  17.216 -	size_t size;
  17.217 -};
  17.218 -#define DMA_MAP_MATCHES(e,d) (((e)->dma<=(d)) && (((e)->dma+(e)->size)>(d)))
  17.219 -
  17.220 -dma_addr_t
  17.221 -dma_map_single(struct device *dev, void *ptr, size_t size,
  17.222 -	       enum dma_data_direction direction)
  17.223 -{
  17.224 -	struct dma_map_entry *ent;
  17.225 -	void *bnc;
  17.226 -	dma_addr_t dma;
  17.227 -	unsigned long flags;
  17.228 -
  17.229 -	if (direction == DMA_NONE)
  17.230 -		out_of_line_bug();
  17.231 -
  17.232 -	/*
  17.233 -	 * Even if size is sub-page, the buffer may still straddle a page
  17.234 -	 * boundary. Take into account buffer start offset. All other calls are
  17.235 -	 * conservative and always search the dma_map list if it's non-empty.
  17.236 -	 */
  17.237 -	if (((((unsigned long)ptr) & ~PAGE_MASK) + size) <= PAGE_SIZE) {
  17.238 -		dma = virt_to_bus(ptr);
  17.239 -	} else {
  17.240 -		BUG_ON((bnc = dma_alloc_coherent(dev, size, &dma, GFP_ATOMIC)) == NULL);
  17.241 -		BUG_ON((ent = kmalloc(sizeof(*ent), GFP_ATOMIC)) == NULL);
  17.242 -		if (direction != DMA_FROM_DEVICE)
  17.243 -			memcpy(bnc, ptr, size);
  17.244 -		ent->dma    = dma;
  17.245 -		ent->bounce = bnc;
  17.246 -		ent->host   = ptr;
  17.247 -		ent->size   = size;
  17.248 -		spin_lock_irqsave(&dma_map_lock, flags);
  17.249 -		list_add(&ent->list, &dma_map_head);
  17.250 -		spin_unlock_irqrestore(&dma_map_lock, flags);
  17.251 -	}
  17.252 -
  17.253 -	if ((dma+size) & ~*dev->dma_mask)
  17.254 -		out_of_line_bug();
  17.255 -	return dma;
  17.256 -}
  17.257 -EXPORT_SYMBOL(dma_map_single);
  17.258 -
  17.259 -void
  17.260 -dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
  17.261 -		 enum dma_data_direction direction)
  17.262 -{
  17.263 -	struct dma_map_entry *ent;
  17.264 -	unsigned long flags;
  17.265 -
  17.266 -	if (direction == DMA_NONE)
  17.267 -		out_of_line_bug();
  17.268 -
  17.269 -	/* Fast-path check: are there any multi-page DMA mappings? */
  17.270 -	if (!list_empty(&dma_map_head)) {
  17.271 -		spin_lock_irqsave(&dma_map_lock, flags);
  17.272 -		list_for_each_entry ( ent, &dma_map_head, list ) {
  17.273 -			if (DMA_MAP_MATCHES(ent, dma_addr)) {
  17.274 -				list_del(&ent->list);
  17.275 -				break;
  17.276 -			}
  17.277 -		}
  17.278 -		spin_unlock_irqrestore(&dma_map_lock, flags);
  17.279 -		if (&ent->list != &dma_map_head) {
  17.280 -			BUG_ON(dma_addr != ent->dma);
  17.281 -			BUG_ON(size != ent->size);
  17.282 -			if (direction != DMA_TO_DEVICE)
  17.283 -				memcpy(ent->host, ent->bounce, size);
  17.284 -			dma_free_coherent(dev, size, ent->bounce, ent->dma);
  17.285 -			kfree(ent);
  17.286 -		}
  17.287 -	}
  17.288 -}
  17.289 -EXPORT_SYMBOL(dma_unmap_single);
  17.290 -
  17.291 -void
  17.292 -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
  17.293 -			enum dma_data_direction direction)
  17.294 -{
  17.295 -	struct dma_map_entry *ent;
  17.296 -	unsigned long flags, off;
  17.297 -
  17.298 -	/* Fast-path check: are there any multi-page DMA mappings? */
  17.299 -	if (!list_empty(&dma_map_head)) {
  17.300 -		spin_lock_irqsave(&dma_map_lock, flags);
  17.301 -		list_for_each_entry ( ent, &dma_map_head, list )
  17.302 -			if (DMA_MAP_MATCHES(ent, dma_handle))
  17.303 -				break;
  17.304 -		spin_unlock_irqrestore(&dma_map_lock, flags);
  17.305 -		if (&ent->list != &dma_map_head) {
  17.306 -			off = dma_handle - ent->dma;
  17.307 -			BUG_ON((off + size) > ent->size);
  17.308 -			/*if (direction != DMA_TO_DEVICE)*/
  17.309 -				memcpy(ent->host+off, ent->bounce+off, size);
  17.310 -		}
  17.311 -	}
  17.312 -}
  17.313 -EXPORT_SYMBOL(dma_sync_single_for_cpu);
  17.314 -
  17.315 -void
  17.316 -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
  17.317 -                           enum dma_data_direction direction)
  17.318 -{
  17.319 -	struct dma_map_entry *ent;
  17.320 -	unsigned long flags, off;
  17.321 -
  17.322 -	/* Fast-path check: are there any multi-page DMA mappings? */
  17.323 -	if (!list_empty(&dma_map_head)) {
  17.324 -		spin_lock_irqsave(&dma_map_lock, flags);
  17.325 -		list_for_each_entry ( ent, &dma_map_head, list )
  17.326 -			if (DMA_MAP_MATCHES(ent, dma_handle))
  17.327 -				break;
  17.328 -		spin_unlock_irqrestore(&dma_map_lock, flags);
  17.329 -		if (&ent->list != &dma_map_head) {
  17.330 -			off = dma_handle - ent->dma;
  17.331 -			BUG_ON((off + size) > ent->size);
  17.332 -			/*if (direction != DMA_FROM_DEVICE)*/
  17.333 -				memcpy(ent->bounce+off, ent->host+off, size);
  17.334 -		}
  17.335 -	}
  17.336 -
  17.337 -	flush_write_buffers();
  17.338 -}
  17.339 -EXPORT_SYMBOL(dma_sync_single_for_device);
    18.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/pci-nommu.c	Tue Aug 16 12:15:23 2005 +0800
    18.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/pci-nommu.c	Tue Aug 16 10:09:07 2005 -0800
    18.3 @@ -61,6 +61,7 @@ void dma_free_coherent(struct device *hw
    18.4  EXPORT_SYMBOL(dma_free_coherent);
    18.5  #endif
    18.6  
    18.7 +#if 0
    18.8  int dma_supported(struct device *hwdev, u64 mask)
    18.9  {
   18.10          /*
   18.11 @@ -76,6 +77,7 @@ int dma_supported(struct device *hwdev, 
   18.12  	return 1;
   18.13  } 
   18.14  EXPORT_SYMBOL(dma_supported);
   18.15 +#endif
   18.16  
   18.17  int dma_get_cache_alignment(void)
   18.18  {
    19.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Tue Aug 16 12:15:23 2005 +0800
    19.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Tue Aug 16 10:09:07 2005 -0800
    19.3 @@ -44,10 +44,6 @@
    19.4  #define Dprintk(x...)
    19.5  #endif
    19.6  
    19.7 -#ifdef CONFIG_GART_IOMMU
    19.8 -extern int swiotlb;
    19.9 -#endif
   19.10 -
   19.11  extern char _stext[];
   19.12  
   19.13  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
   19.14 @@ -790,8 +786,6 @@ static inline int page_is_ram (unsigned 
   19.15          return 1;
   19.16  }
   19.17  
   19.18 -extern int swiotlb_force;
   19.19 -
   19.20  static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
   19.21  			 kcore_vsyscall;
   19.22  
   19.23 @@ -800,14 +794,9 @@ void __init mem_init(void)
   19.24  	int codesize, reservedpages, datasize, initsize;
   19.25  	int tmp;
   19.26  
   19.27 -#ifdef CONFIG_SWIOTLB
   19.28 -	if (swiotlb_force)
   19.29 -		swiotlb = 1;
   19.30 -	if (!iommu_aperture &&
   19.31 -	    (end_pfn >= 0xffffffff>>PAGE_SHIFT || force_iommu))
   19.32 -	       swiotlb = 1;
   19.33 -	if (swiotlb)
   19.34 -		swiotlb_init();	
   19.35 +#if defined(CONFIG_SWIOTLB)
   19.36 +	extern void swiotlb_init(void);
   19.37 +	swiotlb_init();	
   19.38  #endif
   19.39  
   19.40  	/* How many end-of-memory variables you have, grandma! */
    20.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Tue Aug 16 12:15:23 2005 +0800
    20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Tue Aug 16 10:09:07 2005 -0800
    20.3 @@ -23,6 +23,9 @@ int __init xlblktap_init(void)
    20.4      blkif_be_driver_status_t be_st;
    20.5  
    20.6      printk(KERN_INFO "Initialising Xen block tap device\n");
    20.7 +#ifdef CONFIG_XEN_BLKDEV_GRANT
    20.8 +    printk(KERN_INFO "Block tap is using grant tables.\n");
    20.9 +#endif
   20.10  
   20.11      DPRINTK("   tap - Backend connection init:\n");
   20.12  
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h	Tue Aug 16 12:15:23 2005 +0800
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h	Tue Aug 16 10:09:07 2005 -0800
    21.3 @@ -85,6 +85,11 @@ typedef struct blkif_st {
    21.4      spinlock_t          blk_ring_lock;
    21.5      atomic_t            refcnt;
    21.6      struct work_struct work;
    21.7 +#ifdef CONFIG_XEN_BLKDEV_GRANT
    21.8 +    u16 shmem_handle;
    21.9 +    memory_t shmem_vaddr;
   21.10 +    grant_ref_t shmem_ref;
   21.11 +#endif
   21.12  } blkif_t;
   21.13  
   21.14  blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Tue Aug 16 12:15:23 2005 +0800
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Tue Aug 16 10:09:07 2005 -0800
    22.3 @@ -9,6 +9,7 @@
    22.4   */
    22.5   
    22.6  #include "blktap.h"
    22.7 +#include <asm-xen/evtchn.h>
    22.8  
    22.9  static char *blkif_state_name[] = {
   22.10      [BLKIF_STATE_CLOSED]       = "closed",
   22.11 @@ -48,12 +49,21 @@ static void __blkif_disconnect_complete(
   22.12      blkif_t              *blkif = (blkif_t *)arg;
   22.13      ctrl_msg_t            cmsg;
   22.14      blkif_be_disconnect_t disc;
   22.15 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   22.16 +    struct gnttab_unmap_grant_ref op;
   22.17 +#endif
   22.18  
   22.19      /*
   22.20       * These can't be done in blkif_disconnect() because at that point there
   22.21       * may be outstanding requests at the disc whose asynchronous responses
   22.22       * must still be notified to the remote driver.
   22.23       */
   22.24 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   22.25 +    op.host_addr = blkif->shmem_vaddr;
   22.26 +    op.handle         = blkif->shmem_handle;
   22.27 +    op.dev_bus_addr   = 0;
   22.28 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   22.29 +#endif
   22.30      vfree(blkif->blk_ring.sring);
   22.31  
   22.32      /* Construct the deferred response message. */
   22.33 @@ -177,8 +187,12 @@ void blkif_ptfe_connect(blkif_be_connect
   22.34      unsigned int   evtchn = connect->evtchn;
   22.35      unsigned long  shmem_frame = connect->shmem_frame;
   22.36      struct vm_struct *vma;
   22.37 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   22.38 +    int ref = connect->shmem_ref;
   22.39 +#else
   22.40      pgprot_t       prot;
   22.41      int            error;
   22.42 +#endif
   22.43      blkif_t       *blkif;
   22.44      blkif_sring_t *sring;
   22.45  
   22.46 @@ -199,24 +213,46 @@ void blkif_ptfe_connect(blkif_be_connect
   22.47          return;
   22.48      }
   22.49  
   22.50 -    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED);
   22.51 +#ifndef CONFIG_XEN_BLKDEV_GRANT
   22.52 +    prot = __pgprot(_KERNPG_TABLE);
   22.53      error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr),
   22.54                                      shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
   22.55                                      prot, domid);
   22.56      if ( error != 0 )
   22.57      {
   22.58 -        WPRINTK("BE_CONNECT: error! (%d)\n", error);
   22.59          if ( error == -ENOMEM ) 
   22.60              connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   22.61 -        else if ( error == -EFAULT ) {
   22.62 +        else if ( error == -EFAULT )
   22.63              connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   22.64 -            WPRINTK("BE_CONNECT: MAPPING error!\n");
   22.65 -        }
   22.66          else
   22.67              connect->status = BLKIF_BE_STATUS_ERROR;
   22.68          vfree(vma->addr);
   22.69          return;
   22.70      }
   22.71 +#else
   22.72 +    { /* Map: Use the Grant table reference */
   22.73 +        struct gnttab_map_grant_ref op;
   22.74 +        op.host_addr = VMALLOC_VMADDR(vma->addr);
   22.75 +        op.flags            = GNTMAP_host_map;
   22.76 +        op.ref              = ref;
   22.77 +        op.dom              = domid;
   22.78 +       
   22.79 +        BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   22.80 +       
   22.81 +        handle = op.handle;
   22.82 +       
   22.83 +        if (op.handle < 0) {
   22.84 +            DPRINTK(" Grant table operation failure !\n");
   22.85 +            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   22.86 +            vfree(vma->addr);
   22.87 +            return;
   22.88 +        }
   22.89 +
   22.90 +        blkif->shmem_ref = ref;
   22.91 +        blkif->shmem_handle = handle;
   22.92 +        blkif->shmem_vaddr = VMALLOC_VMADDR(vma->addr);
   22.93 +    }
   22.94 +#endif
   22.95  
   22.96      if ( blkif->status != DISCONNECTED )
   22.97      {
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Tue Aug 16 12:15:23 2005 +0800
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Tue Aug 16 10:09:07 2005 -0800
    23.3 @@ -21,6 +21,9 @@
    23.4  #include <asm/pgalloc.h>
    23.5  #include <asm/tlbflush.h>
    23.6  #include <asm-xen/xen-public/io/blkif.h> /* for control ring. */
    23.7 +#ifdef CONFIG_XEN_BLKDEV_GRANT
    23.8 +#include <asm-xen/xen-public/grant_table.h>
    23.9 +#endif
   23.10  
   23.11  #include "blktap.h"
   23.12  
   23.13 @@ -43,6 +46,7 @@ static ctrl_front_ring_t  blktap_uctrl_r
   23.14  static int blktap_read_fe_ring(void);
   23.15  static int blktap_read_be_ring(void);
   23.16  
   23.17 +
   23.18  /* -------[ mmap region ]--------------------------------------------- */
   23.19  /*
   23.20   * We use a big chunk of address space to map in-flight requests into,
   23.21 @@ -73,7 +77,28 @@ unsigned long user_vstart;  /* start of 
   23.22       ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \
   23.23       ((_seg) * PAGE_SIZE))
   23.24  
   23.25 +/* -------[ grant handles ]------------------------------------------- */
   23.26  
   23.27 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   23.28 +/* When using grant tables to map a frame for device access then the
   23.29 + * handle returned must be used to unmap the frame. This is needed to
   23.30 + * drop the ref count on the frame.
   23.31 + */
   23.32 +struct grant_handle_pair
   23.33 +{
   23.34 +    u16  kernel;
   23.35 +    u16  user;
   23.36 +};
   23.37 +static struct grant_handle_pair pending_grant_handles[MMAP_PAGES];
   23.38 +#define pending_handle(_idx, _i) \
   23.39 +    (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
   23.40 +#define BLKTAP_INVALID_HANDLE(_g) \
   23.41 +    (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
   23.42 +#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
   23.43 +    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
   23.44 +    } while(0)
   23.45 +    
   23.46 +#endif
   23.47  
   23.48  
   23.49  /* -------[ blktap vm ops ]------------------------------------------- */
   23.50 @@ -348,9 +373,43 @@ static struct file_operations blktap_fop
   23.51      
   23.52  /*-----[ Data to/from user space ]----------------------------------------*/
   23.53  
   23.54 -
   23.55  static void fast_flush_area(int idx, int nr_pages)
   23.56  {
   23.57 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   23.58 +    struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
   23.59 +    unsigned int i, op = 0;
   23.60 +    struct grant_handle_pair *handle;
   23.61 +    unsigned long ptep;
   23.62 +
   23.63 +    for (i=0; i<nr_pages; i++)
   23.64 +    {
   23.65 +        handle = &pending_handle(idx, i);
   23.66 +        if (!BLKTAP_INVALID_HANDLE(handle))
   23.67 +        {
   23.68 +
   23.69 +            unmap[op].host_addr = MMAP_VADDR(mmap_vstart, idx, i);
   23.70 +            unmap[op].dev_bus_addr = 0;
   23.71 +            unmap[op].handle = handle->kernel;
   23.72 +            op++;
   23.73 +
   23.74 +            if (create_lookup_pte_addr(blktap_vma->vm_mm,
   23.75 +                                       MMAP_VADDR(user_vstart, idx, i), 
   23.76 +                                       &ptep) !=0) {
   23.77 +                DPRINTK("Couldn't get a pte addr!\n");
   23.78 +                return;
   23.79 +            }
   23.80 +            unmap[op].host_addr    = ptep;
   23.81 +            unmap[op].dev_bus_addr = 0;
   23.82 +            unmap[op].handle       = handle->user;
   23.83 +            op++;
   23.84 +            
   23.85 +            BLKTAP_INVALIDATE_HANDLE(handle);
   23.86 +        }
   23.87 +    }
   23.88 +    if ( unlikely(HYPERVISOR_grant_table_op(
   23.89 +        GNTTABOP_unmap_grant_ref, unmap, op)))
   23.90 +        BUG();
   23.91 +#else
   23.92      multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   23.93      int               i;
   23.94  
   23.95 @@ -363,21 +422,22 @@ static void fast_flush_area(int idx, int
   23.96      mcl[nr_pages-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
   23.97      if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
   23.98          BUG();
   23.99 +#endif
  23.100  }
  23.101  
  23.102  
  23.103 -extern int __direct_remap_area_pages(struct mm_struct *mm,
  23.104 -                                     unsigned long address,
  23.105 -                                     unsigned long size,
  23.106 -                                     mmu_update_t *v);
  23.107 -
  23.108  int blktap_write_fe_ring(blkif_request_t *req)
  23.109  {
  23.110      blkif_request_t *target;
  23.111 -    int i;
  23.112 +    int i, ret = 0;
  23.113 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  23.114 +    struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
  23.115 +    int op;
  23.116 +#else
  23.117      unsigned long remap_prot;
  23.118      multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST+1];
  23.119      mmu_update_t mmu[BLKIF_MAX_SEGMENTS_PER_REQUEST];
  23.120 +#endif
  23.121  
  23.122      /*
  23.123       * This is called to pass a request from the real frontend domain's
  23.124 @@ -394,18 +454,109 @@ int blktap_write_fe_ring(blkif_request_t
  23.125          return 0;
  23.126      }
  23.127  
  23.128 -    remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW;
  23.129      flush_cache_all(); /* a noop on intel... */
  23.130  
  23.131      target = RING_GET_REQUEST(&blktap_ufe_ring, blktap_ufe_ring.req_prod_pvt);
  23.132      memcpy(target, req, sizeof(*req));
  23.133  
  23.134      /* Map the foreign pages directly in to the application */
  23.135 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  23.136 +    op = 0;
  23.137 +    for (i=0; i<target->nr_segments; i++) {
  23.138 +
  23.139 +        unsigned long uvaddr;
  23.140 +        unsigned long kvaddr;
  23.141 +        unsigned long ptep;
  23.142 +
  23.143 +        uvaddr = MMAP_VADDR(user_vstart, ID_TO_IDX(req->id), i);
  23.144 +        kvaddr = MMAP_VADDR(mmap_vstart, ID_TO_IDX(req->id), i);
  23.145 +
  23.146 +        /* Map the remote page to kernel. */
  23.147 +        map[op].host_addr = kvaddr;
  23.148 +        map[op].dom   = ID_TO_DOM(req->id);
  23.149 +        map[op].ref   = blkif_gref_from_fas(target->frame_and_sects[i]);
  23.150 +        map[op].flags = GNTMAP_host_map;
  23.151 +        /* This needs a bit more thought in terms of interposition: 
  23.152 +         * If we want to be able to modify pages during write using 
  23.153 +         * grant table mappings, the guest will either need to allow 
  23.154 +         * it, or we'll need to incur a copy. */
  23.155 +        if (req->operation == BLKIF_OP_WRITE)
  23.156 +            map[op].flags |= GNTMAP_readonly;
  23.157 +        op++;
  23.158 +
  23.159 +        /* Now map it to user. */
  23.160 +        ret = create_lookup_pte_addr(blktap_vma->vm_mm, uvaddr, &ptep);
  23.161 +        if (ret)
  23.162 +        {
  23.163 +            DPRINTK("Couldn't get a pte addr!\n");
  23.164 +            goto fail;
  23.165 +        }
  23.166 +
  23.167 +        map[op].host_addr = ptep;
  23.168 +        map[op].dom       = ID_TO_DOM(req->id);
  23.169 +        map[op].ref       = blkif_gref_from_fas(target->frame_and_sects[i]);
  23.170 +        map[op].flags     = GNTMAP_host_map | GNTMAP_application_map
  23.171 +                            | GNTMAP_contains_pte;
  23.172 +        /* Above interposition comment applies here as well. */
  23.173 +        if (req->operation == BLKIF_OP_WRITE)
  23.174 +            map[op].flags |= GNTMAP_readonly;
  23.175 +        op++;
  23.176 +    }
  23.177 +
  23.178 +    if ( unlikely(HYPERVISOR_grant_table_op(
  23.179 +            GNTTABOP_map_grant_ref, map, op)))
  23.180 +        BUG();
  23.181 +
  23.182 +    op = 0;
  23.183 +    for (i=0; i<(target->nr_segments*2); i+=2) {
  23.184 +        unsigned long uvaddr;
  23.185 +        unsigned long kvaddr;
  23.186 +        unsigned long offset;
  23.187 +        int cancel = 0;
  23.188 +
  23.189 +        uvaddr = MMAP_VADDR(user_vstart, ID_TO_IDX(req->id), i/2);
  23.190 +        kvaddr = MMAP_VADDR(mmap_vstart, ID_TO_IDX(req->id), i/2);
  23.191 +
  23.192 +        if ( unlikely(map[i].handle < 0) ) {
  23.193 +            DPRINTK("Error on kernel grant mapping (%d)\n", map[i].handle);
  23.194 +            ret = map[i].handle;
  23.195 +            cancel = 1;
  23.196 +        }
  23.197 +
  23.198 +        if ( unlikely(map[i+1].handle < 0) ) {
  23.199 +            DPRINTK("Error on user grant mapping (%d)\n", map[i+1].handle);
  23.200 +            ret = map[i+1].handle;
  23.201 +            cancel = 1;
  23.202 +        }
  23.203 +
  23.204 +        if (cancel) 
  23.205 +            goto fail;
  23.206 +
  23.207 +        /* Set the necessary mappings in p2m and in the VM_FOREIGN 
  23.208 +         * vm_area_struct to allow user vaddr -> struct page lookups
  23.209 +         * to work.  This is needed for direct IO to foreign pages. */
  23.210 +        phys_to_machine_mapping[__pa(kvaddr)>>PAGE_SHIFT] =
  23.211 +            FOREIGN_FRAME(map[i].dev_bus_addr);
  23.212 +
  23.213 +        offset = (uvaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
  23.214 +        ((struct page **)blktap_vma->vm_private_data)[offset] =
  23.215 +            pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
  23.216 +
  23.217 +        /* Save handles for unmapping later. */
  23.218 +        pending_handle(ID_TO_IDX(req->id), i/2).kernel = map[i].handle;
  23.219 +        pending_handle(ID_TO_IDX(req->id), i/2).user   = map[i+1].handle;
  23.220 +    }
  23.221 +    
  23.222 +#else
  23.223 +
  23.224 +    remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW;
  23.225 +
  23.226      for (i=0; i<target->nr_segments; i++) {
  23.227          unsigned long buf;
  23.228          unsigned long uvaddr;
  23.229          unsigned long kvaddr;
  23.230          unsigned long offset;
  23.231 +        unsigned long ptep;
  23.232  
  23.233          buf   = target->frame_and_sects[i] & PAGE_MASK;
  23.234          uvaddr = MMAP_VADDR(user_vstart, ID_TO_IDX(req->id), i);
  23.235 @@ -421,10 +572,14 @@ int blktap_write_fe_ring(blkif_request_t
  23.236          phys_to_machine_mapping[__pa(kvaddr)>>PAGE_SHIFT] =
  23.237              FOREIGN_FRAME(buf >> PAGE_SHIFT);
  23.238  
  23.239 -        __direct_remap_area_pages(blktap_vma->vm_mm,
  23.240 -                                  uvaddr,
  23.241 -                                  PAGE_SIZE,
  23.242 -                                  &mmu[i]);
  23.243 +        ret = create_lookup_pte_addr(blktap_vma->vm_mm, uvaddr, &ptep);
  23.244 +        if (ret)
  23.245 +        { 
  23.246 +            DPRINTK("error getting pte\n");
  23.247 +            goto fail;
  23.248 +        }
  23.249 +
  23.250 +        mmu[i].ptr = ptep;
  23.251          mmu[i].val = (target->frame_and_sects[i] & PAGE_MASK)
  23.252              | pgprot_val(blktap_vma->vm_page_prot);
  23.253  
  23.254 @@ -448,16 +603,17 @@ int blktap_write_fe_ring(blkif_request_t
  23.255          if ( unlikely(mcl[i].result != 0) )
  23.256          {
  23.257              DPRINTK("invalid buffer -- could not remap it\n");
  23.258 -            fast_flush_area(ID_TO_IDX(req->id), target->nr_segments);
  23.259 -            return -1;
  23.260 +            ret = mcl[i].result;
  23.261 +            goto fail;
  23.262          }
  23.263      }
  23.264      if ( unlikely(mcl[i].result != 0) )
  23.265      {
  23.266          DPRINTK("direct remapping of pages to /dev/blktap failed.\n");
  23.267 -        return -1;
  23.268 +        ret = mcl[i].result;
  23.269 +        goto fail;
  23.270      }
  23.271 -
  23.272 +#endif /* CONFIG_XEN_BLKDEV_GRANT */
  23.273  
  23.274      /* Mark mapped pages as reserved: */
  23.275      for ( i = 0; i < target->nr_segments; i++ )
  23.276 @@ -472,6 +628,10 @@ int blktap_write_fe_ring(blkif_request_t
  23.277      blktap_ufe_ring.req_prod_pvt++;
  23.278      
  23.279      return 0;
  23.280 +
  23.281 + fail:
  23.282 +    fast_flush_area(ID_TO_IDX(req->id), target->nr_segments);
  23.283 +    return ret;
  23.284  }
  23.285  
  23.286  int blktap_write_be_ring(blkif_response_t *rsp)
  23.287 @@ -538,11 +698,10 @@ static int blktap_read_fe_ring(void)
  23.288                  map[offset] = NULL;
  23.289              }
  23.290  
  23.291 -
  23.292 +            fast_flush_area(ID_TO_IDX(resp_s->id), ar->nr_pages);
  23.293              zap_page_range(blktap_vma, 
  23.294                      MMAP_VADDR(user_vstart, ID_TO_IDX(resp_s->id), 0), 
  23.295                      ar->nr_pages << PAGE_SHIFT, NULL);
  23.296 -            fast_flush_area(ID_TO_IDX(resp_s->id), ar->nr_pages);
  23.297              write_resp_to_fe_ring(blkif, resp_s);
  23.298              blktap_ufe_ring.rsp_cons = i + 1;
  23.299              kick_fe_domain(blkif);
  23.300 @@ -616,11 +775,17 @@ static struct miscdevice blktap_miscdev 
  23.301  
  23.302  int blktap_init(void)
  23.303  {
  23.304 -    int err;
  23.305 +    int err, i, j;
  23.306  
  23.307      if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 )
  23.308          BUG();
  23.309  
  23.310 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  23.311 +    for (i=0; i<MAX_PENDING_REQS ; i++)
  23.312 +        for (j=0; j<BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
  23.313 +            BLKTAP_INVALIDATE_HANDLE(&pending_handle(i, j));
  23.314 +#endif
  23.315 +
  23.316      err = misc_register(&blktap_miscdev);
  23.317      if ( err != 0 )
  23.318      {
    24.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h	Tue Aug 16 12:15:23 2005 +0800
    24.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h	Tue Aug 16 10:09:07 2005 -0800
    24.3 @@ -1,11 +1,33 @@
    24.4  #ifndef _ASM_I386_DMA_MAPPING_H
    24.5  #define _ASM_I386_DMA_MAPPING_H
    24.6  
    24.7 +/*
    24.8 + * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
    24.9 + * documentation.
   24.10 + */
   24.11 +
   24.12 +#include <linux/config.h>
   24.13  #include <linux/mm.h>
   24.14 -
   24.15  #include <asm/cache.h>
   24.16  #include <asm/io.h>
   24.17  #include <asm/scatterlist.h>
   24.18 +#include <asm-i386/swiotlb.h>
   24.19 +
   24.20 +static inline int
   24.21 +address_needs_mapping(struct device *hwdev, dma_addr_t addr)
   24.22 +{
   24.23 +	dma_addr_t mask = 0xffffffff;
   24.24 +	/* If the device has a mask, use it, otherwise default to 32 bits */
   24.25 +	if (hwdev && hwdev->dma_mask)
   24.26 +		mask = *hwdev->dma_mask;
   24.27 +	return (addr & ~mask) != 0;
   24.28 +}
   24.29 +
   24.30 +static inline int
   24.31 +range_straddles_page_boundary(void *p, size_t size)
   24.32 +{
   24.33 +	return ((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE);
   24.34 +}
   24.35  
   24.36  #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
   24.37  #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
   24.38 @@ -24,46 +46,18 @@ extern void
   24.39  dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
   24.40  		 enum dma_data_direction direction);
   24.41  
   24.42 -static inline int
   24.43 -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
   24.44 -	   enum dma_data_direction direction)
   24.45 -{
   24.46 -	int i;
   24.47 -
   24.48 -	BUG_ON(direction == DMA_NONE);
   24.49 +extern int dma_map_sg(struct device *hwdev, struct scatterlist *sg,
   24.50 +		      int nents, enum dma_data_direction direction);
   24.51 +extern void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg,
   24.52 +			 int nents, enum dma_data_direction direction);
   24.53  
   24.54 -	for (i = 0; i < nents; i++ ) {
   24.55 -		BUG_ON(!sg[i].page);
   24.56 -
   24.57 -		sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
   24.58 -	}
   24.59 -
   24.60 -	flush_write_buffers();
   24.61 -	return nents;
   24.62 -}
   24.63 -
   24.64 -static inline dma_addr_t
   24.65 +extern dma_addr_t
   24.66  dma_map_page(struct device *dev, struct page *page, unsigned long offset,
   24.67 -	     size_t size, enum dma_data_direction direction)
   24.68 -{
   24.69 -	BUG_ON(direction == DMA_NONE);
   24.70 -	return page_to_phys(page) + offset;
   24.71 -}
   24.72 +	     size_t size, enum dma_data_direction direction);
   24.73  
   24.74 -static inline void
   24.75 +extern void
   24.76  dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
   24.77 -	       enum dma_data_direction direction)
   24.78 -{
   24.79 -	BUG_ON(direction == DMA_NONE);
   24.80 -}
   24.81 -
   24.82 -
   24.83 -static inline void
   24.84 -dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
   24.85 -	     enum dma_data_direction direction)
   24.86 -{
   24.87 -	BUG_ON(direction == DMA_NONE);
   24.88 -}
   24.89 +	       enum dma_data_direction direction);
   24.90  
   24.91  extern void
   24.92  dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
   24.93 @@ -93,34 +87,25 @@ static inline void
   24.94  dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
   24.95  		    enum dma_data_direction direction)
   24.96  {
   24.97 +	if (swiotlb)
   24.98 +		swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
   24.99 +	flush_write_buffers();
  24.100  }
  24.101  
  24.102  static inline void
  24.103  dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
  24.104  		    enum dma_data_direction direction)
  24.105  {
  24.106 +	if (swiotlb)
  24.107 +		swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
  24.108  	flush_write_buffers();
  24.109  }
  24.110  
  24.111 -static inline int
  24.112 -dma_mapping_error(dma_addr_t dma_addr)
  24.113 -{
  24.114 -	return 0;
  24.115 -}
  24.116 +extern int
  24.117 +dma_mapping_error(dma_addr_t dma_addr);
  24.118  
  24.119 -static inline int
  24.120 -dma_supported(struct device *dev, u64 mask)
  24.121 -{
  24.122 -        /*
  24.123 -         * we fall back to GFP_DMA when the mask isn't all 1s,
  24.124 -         * so we can't guarantee allocations that must be
  24.125 -         * within a tighter range than GFP_DMA..
  24.126 -         */
  24.127 -        if(mask < 0x00ffffff)
  24.128 -                return 0;
  24.129 -
  24.130 -	return 1;
  24.131 -}
  24.132 +extern int
  24.133 +dma_supported(struct device *dev, u64 mask);
  24.134  
  24.135  static inline int
  24.136  dma_set_mask(struct device *dev, u64 mask)
  24.137 @@ -133,6 +118,7 @@ dma_set_mask(struct device *dev, u64 mas
  24.138  	return 0;
  24.139  }
  24.140  
  24.141 +#ifdef __i386__
  24.142  static inline int
  24.143  dma_get_cache_alignment(void)
  24.144  {
  24.145 @@ -140,6 +126,9 @@ dma_get_cache_alignment(void)
  24.146  	 * maximum possible, to be safe */
  24.147  	return (1 << L1_CACHE_SHIFT_MAX);
  24.148  }
  24.149 +#else
  24.150 +extern int dma_get_cache_alignment(void);
  24.151 +#endif
  24.152  
  24.153  #define dma_is_consistent(d)	(1)
  24.154  
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/kmap_types.h	Tue Aug 16 10:09:07 2005 -0800
    25.3 @@ -0,0 +1,32 @@
    25.4 +#ifndef _ASM_KMAP_TYPES_H
    25.5 +#define _ASM_KMAP_TYPES_H
    25.6 +
    25.7 +#include <linux/config.h>
    25.8 +
    25.9 +#ifdef CONFIG_DEBUG_HIGHMEM
   25.10 +# define D(n) __KM_FENCE_##n ,
   25.11 +#else
   25.12 +# define D(n)
   25.13 +#endif
   25.14 +
   25.15 +enum km_type {
   25.16 +D(0)	KM_BOUNCE_READ,
   25.17 +D(1)	KM_SKB_SUNRPC_DATA,
   25.18 +D(2)	KM_SKB_DATA_SOFTIRQ,
   25.19 +D(3)	KM_USER0,
   25.20 +D(4)	KM_USER1,
   25.21 +D(5)	KM_BIO_SRC_IRQ,
   25.22 +D(6)	KM_BIO_DST_IRQ,
   25.23 +D(7)	KM_PTE0,
   25.24 +D(8)	KM_PTE1,
   25.25 +D(9)	KM_IRQ0,
   25.26 +D(10)	KM_IRQ1,
   25.27 +D(11)	KM_SOFTIRQ0,
   25.28 +D(12)	KM_SOFTIRQ1,
   25.29 +D(13)	KM_SWIOTLB,
   25.30 +D(14)	KM_TYPE_NR
   25.31 +};
   25.32 +
   25.33 +#undef D
   25.34 +
   25.35 +#endif
    26.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pci.h	Tue Aug 16 12:15:23 2005 +0800
    26.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pci.h	Tue Aug 16 10:09:07 2005 -0800
    26.3 @@ -43,11 +43,8 @@ int pcibios_set_irq_routing(struct pci_d
    26.4  
    26.5  struct pci_dev;
    26.6  
    26.7 -/* The PCI address space does equal the physical memory
    26.8 - * address space.  The networking and block device layers use
    26.9 - * this boolean for bounce buffer decisions.
   26.10 - */
   26.11 -#define PCI_DMA_BUS_IS_PHYS	(1)
   26.12 +/* On Xen we use SWIOTLB instead of blk-specific bounce buffers. */
   26.13 +#define PCI_DMA_BUS_IS_PHYS	(0)
   26.14  
   26.15  /* pci_unmap_{page,single} is a nop so... */
   26.16  #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/scatterlist.h	Tue Aug 16 10:09:07 2005 -0800
    27.3 @@ -0,0 +1,22 @@
    27.4 +#ifndef _I386_SCATTERLIST_H
    27.5 +#define _I386_SCATTERLIST_H
    27.6 +
    27.7 +struct scatterlist {
    27.8 +    struct page		*page;
    27.9 +    unsigned int	offset;
   27.10 +    unsigned int	length;
   27.11 +    dma_addr_t		dma_address;
   27.12 +    unsigned int	dma_length;
   27.13 +};
   27.14 +
   27.15 +/* These macros should be used after a pci_map_sg call has been done
   27.16 + * to get bus addresses of each of the SG entries and their lengths.
   27.17 + * You should only work with the number of sg entries pci_map_sg
   27.18 + * returns.
   27.19 + */
   27.20 +#define sg_dma_address(sg)	((sg)->dma_address)
   27.21 +#define sg_dma_len(sg)		((sg)->dma_length)
   27.22 +
   27.23 +#define ISA_DMA_THRESHOLD (0x00ffffff)
   27.24 +
   27.25 +#endif /* !(_I386_SCATTERLIST_H) */
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/swiotlb.h	Tue Aug 16 10:09:07 2005 -0800
    28.3 @@ -0,0 +1,42 @@
    28.4 +#ifndef _ASM_SWIOTLB_H
    28.5 +#define _ASM_SWIOTLB_H 1
    28.6 +
    28.7 +#include <linux/config.h>
    28.8 +
    28.9 +/* SWIOTLB interface */
   28.10 +
   28.11 +extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, size_t size,
   28.12 +				      int dir);
   28.13 +extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
   28.14 +				  size_t size, int dir);
   28.15 +extern void swiotlb_sync_single_for_cpu(struct device *hwdev,
   28.16 +					 dma_addr_t dev_addr,
   28.17 +					 size_t size, int dir);
   28.18 +extern void swiotlb_sync_single_for_device(struct device *hwdev,
   28.19 +					    dma_addr_t dev_addr,
   28.20 +					    size_t size, int dir);
   28.21 +extern void swiotlb_sync_sg_for_cpu(struct device *hwdev,
   28.22 +				     struct scatterlist *sg, int nelems,
   28.23 +				     int dir);
   28.24 +extern void swiotlb_sync_sg_for_device(struct device *hwdev,
   28.25 +					struct scatterlist *sg, int nelems,
   28.26 +					int dir);
   28.27 +extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg,
   28.28 +		      int nents, int direction);
   28.29 +extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
   28.30 +			 int nents, int direction);
   28.31 +extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
   28.32 +extern dma_addr_t swiotlb_map_page(struct device *hwdev, struct page *page,
   28.33 +                                   unsigned long offset, size_t size,
   28.34 +                                   enum dma_data_direction direction);
   28.35 +extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
   28.36 +                               size_t size, enum dma_data_direction direction);
   28.37 +extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
   28.38 +
   28.39 +#ifdef CONFIG_SWIOTLB
   28.40 +extern int swiotlb;
   28.41 +#else
   28.42 +#define swiotlb 0
   28.43 +#endif
   28.44 +
   28.45 +#endif
    29.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h	Tue Aug 16 12:15:23 2005 +0800
    29.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h	Tue Aug 16 10:09:07 2005 -0800
    29.3 @@ -1,89 +1,1 @@
    29.4 -#ifndef _X8664_DMA_MAPPING_H
    29.5 -#define _X8664_DMA_MAPPING_H 1
    29.6 -
    29.7 -/*
    29.8 - * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
    29.9 - * documentation.
   29.10 - */
   29.11 -
   29.12 -#include <linux/config.h>
   29.13 -
   29.14 -#include <asm/scatterlist.h>
   29.15 -#include <asm/io.h>
   29.16 -#include <asm/swiotlb.h>
   29.17 -
   29.18 -extern dma_addr_t bad_dma_address;
   29.19 -#define dma_mapping_error(x) \
   29.20 -	(swiotlb ? swiotlb_dma_mapping_error(x) : ((x) == bad_dma_address))
   29.21 -
   29.22 -void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
   29.23 -			 unsigned gfp);
   29.24 -void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
   29.25 -			 dma_addr_t dma_handle);
   29.26 -
   29.27 -extern dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size,
   29.28 -				 enum dma_data_direction direction);
   29.29 -extern void dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
   29.30 -			     enum dma_data_direction direction);
   29.31 -
   29.32 -#define dma_map_page(dev,page,offset,size,dir) \
   29.33 -	dma_map_single((dev), page_address(page)+(offset), (size), (dir))
   29.34 -
   29.35 -extern void
   29.36 -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
   29.37 -			enum dma_data_direction direction);
   29.38 -
   29.39 -extern void
   29.40 -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
   29.41 -                           enum dma_data_direction direction);
   29.42 -
   29.43 -static inline void dma_sync_sg_for_cpu(struct device *hwdev,
   29.44 -				       struct scatterlist *sg,
   29.45 -				       int nelems, int direction)
   29.46 -{
   29.47 -	if (direction == DMA_NONE)
   29.48 -		out_of_line_bug();
   29.49 -
   29.50 -	if (swiotlb)
   29.51 -		return swiotlb_sync_sg_for_cpu(hwdev,sg,nelems,direction);
   29.52 -
   29.53 -	flush_write_buffers();
   29.54 -}
   29.55 -
   29.56 -static inline void dma_sync_sg_for_device(struct device *hwdev,
   29.57 -					  struct scatterlist *sg,
   29.58 -					  int nelems, int direction)
   29.59 -{
   29.60 -	if (direction == DMA_NONE)
   29.61 -		out_of_line_bug();
   29.62 -
   29.63 -	if (swiotlb)
   29.64 -		return swiotlb_sync_sg_for_device(hwdev,sg,nelems,direction);
   29.65 -
   29.66 -	flush_write_buffers();
   29.67 -}
   29.68 -
   29.69 -extern int dma_map_sg(struct device *hwdev, struct scatterlist *sg,
   29.70 -		      int nents, int direction);
   29.71 -extern void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg,
   29.72 -			 int nents, int direction);
   29.73 -
   29.74 -#define dma_unmap_page dma_unmap_single
   29.75 -
   29.76 -extern int dma_supported(struct device *hwdev, u64 mask);
   29.77 -extern int dma_get_cache_alignment(void);
   29.78 -#define dma_is_consistent(h) 1
   29.79 -
   29.80 -static inline int dma_set_mask(struct device *dev, u64 mask)
   29.81 -{
   29.82 -	if (!dev->dma_mask || !dma_supported(dev, mask))
   29.83 -		return -EIO;
   29.84 -	*dev->dma_mask = mask;
   29.85 -	return 0;
   29.86 -}
   29.87 -
   29.88 -static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir)
   29.89 -{
   29.90 -	flush_write_buffers();
   29.91 -}
   29.92 -#endif
   29.93 +#include <asm-i386/dma-mapping.h>
    30.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pci.h	Tue Aug 16 12:15:23 2005 +0800
    30.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pci.h	Tue Aug 16 10:09:07 2005 -0800
    30.3 @@ -79,7 +79,9 @@ extern int iommu_sac_force;
    30.4  #else
    30.5  /* No IOMMU */
    30.6  
    30.7 -#define PCI_DMA_BUS_IS_PHYS	1
    30.8 +/* On Xen we use SWIOTLB instead of blk-specific bounce buffers. */
    30.9 +#define PCI_DMA_BUS_IS_PHYS	(0)
   30.10 +
   30.11  #define pci_dac_dma_supported(pci_dev, mask)    1
   30.12  
   30.13  #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
    31.1 --- a/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h	Tue Aug 16 12:15:23 2005 +0800
    31.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h	Tue Aug 16 10:09:07 2005 -0800
    31.3 @@ -134,7 +134,8 @@ void xen_invlpg_mask(cpumask_t *mask, un
    31.4  #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
    31.5  #endif /* linux < 2.6.0 */
    31.6  
    31.7 -void xen_contig_memory(unsigned long vstart, unsigned int order);
    31.8 +void xen_create_contiguous_region(unsigned long vstart, unsigned int order);
    31.9 +void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
   31.10  
   31.11  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
   31.12  /* Allocate a contiguous empty region of low memory. Return virtual start. */
    32.1 --- a/tools/console/daemon/io.c	Tue Aug 16 12:15:23 2005 +0800
    32.2 +++ b/tools/console/daemon/io.c	Tue Aug 16 10:09:07 2005 -0800
    32.3 @@ -87,6 +87,7 @@ struct domain
    32.4  {
    32.5  	int domid;
    32.6  	int tty_fd;
    32.7 +	bool is_dead;
    32.8  	struct buffer buffer;
    32.9  	struct domain *next;
   32.10  };
   32.11 @@ -156,10 +157,12 @@ static struct domain *create_domain(int 
   32.12  
   32.13  	dom->domid = domid;
   32.14  	dom->tty_fd = domain_create_tty(dom);
   32.15 +	dom->is_dead = false;
   32.16  	dom->buffer.data = 0;
   32.17  	dom->buffer.size = 0;
   32.18  	dom->buffer.capacity = 0;
   32.19  	dom->buffer.max_capacity = 0;
   32.20 +	dom->next = 0;
   32.21  
   32.22  	dolog(LOG_DEBUG, "New domain %d", domid);
   32.23  
   32.24 @@ -206,6 +209,16 @@ static void remove_domain(struct domain 
   32.25  	}
   32.26  }
   32.27  
   32.28 +static void remove_dead_domains(struct domain *dom)
   32.29 +{
   32.30 +	if (dom == NULL) return;
   32.31 +	remove_dead_domains(dom->next);
   32.32 +
   32.33 +	if (dom->is_dead) {
   32.34 +		remove_domain(dom);
   32.35 +	}
   32.36 +}
   32.37 +
   32.38  static void handle_tty_read(struct domain *dom)
   32.39  {
   32.40  	ssize_t len;
   32.41 @@ -224,7 +237,7 @@ static void handle_tty_read(struct domai
   32.42  		if (domain_is_valid(dom->domid)) {
   32.43  			dom->tty_fd = domain_create_tty(dom);
   32.44  		} else {
   32.45 -			remove_domain(dom);
   32.46 +			dom->is_dead = true;
   32.47  		}
   32.48  	} else if (domain_is_valid(dom->domid)) {
   32.49  		msg.u.control.msg.length = len;
   32.50 @@ -235,7 +248,7 @@ static void handle_tty_read(struct domai
   32.51  		}
   32.52  	} else {
   32.53  		close(dom->tty_fd);
   32.54 -		remove_domain(dom);
   32.55 +		dom->is_dead = true;
   32.56  	}
   32.57  }
   32.58  
   32.59 @@ -250,7 +263,7 @@ static void handle_tty_write(struct doma
   32.60  		if (domain_is_valid(dom->domid)) {
   32.61  			dom->tty_fd = domain_create_tty(dom);
   32.62  		} else {
   32.63 -			remove_domain(dom);
   32.64 +			dom->is_dead = true;
   32.65  		}
   32.66  	} else {
   32.67  		buffer_advance(&dom->buffer, len);
   32.68 @@ -316,6 +329,7 @@ void handle_io(void)
   32.69  
   32.70  		ret = select(max_fd + 1, &readfds, &writefds, 0, &tv);
   32.71  		if (tv.tv_sec == 1 && (++num_of_writes % 100) == 0) {
   32.72 +#if 0
   32.73  			/* FIXME */
   32.74  			/* This is a nasty hack.  xcs does not handle the
   32.75  			   control channels filling up well at all.  We'll
   32.76 @@ -325,6 +339,7 @@ void handle_io(void)
   32.77  			   going away */
   32.78  			tv.tv_usec = 1000;
   32.79  			select(0, 0, 0, 0, &tv);
   32.80 +#endif
   32.81  		}
   32.82  		enum_domains();
   32.83  
   32.84 @@ -333,13 +348,15 @@ void handle_io(void)
   32.85  		}
   32.86  
   32.87  		for (d = dom_head; d; d = d->next) {
   32.88 -			if (FD_ISSET(d->tty_fd, &readfds)) {
   32.89 +			if (!d->is_dead && FD_ISSET(d->tty_fd, &readfds)) {
   32.90  				handle_tty_read(d);
   32.91  			}
   32.92  
   32.93 -			if (FD_ISSET(d->tty_fd, &writefds)) {
   32.94 +			if (!d->is_dead && FD_ISSET(d->tty_fd, &writefds)) {
   32.95  				handle_tty_write(d);
   32.96  			}
   32.97  		}
   32.98 +
   32.99 +		remove_dead_domains(dom_head);
  32.100  	} while (ret > -1);
  32.101  }
    33.1 --- a/tools/debugger/pdb/Domain.ml	Tue Aug 16 12:15:23 2005 +0800
    33.2 +++ b/tools/debugger/pdb/Domain.ml	Tue Aug 16 10:09:07 2005 -0800
    33.3 @@ -36,6 +36,7 @@ let string_of_context ctx =
    33.4        Printf.sprintf "{domain} domain: %d, vcpu: %d"
    33.5                        ctx.domain  ctx.vcpu
    33.6  
    33.7 +external read_register : context_t -> int -> int32 = "dom_read_register"
    33.8  external read_registers : context_t -> registers = "dom_read_registers"
    33.9  external write_register : context_t -> register -> int32 -> unit =
   33.10    "dom_write_register"
    34.1 --- a/tools/debugger/pdb/Domain.mli	Tue Aug 16 12:15:23 2005 +0800
    34.2 +++ b/tools/debugger/pdb/Domain.mli	Tue Aug 16 10:09:07 2005 -0800
    34.3 @@ -22,6 +22,7 @@ val get_vcpu : context_t -> int
    34.4  
    34.5  val string_of_context : context_t -> string
    34.6  
    34.7 +val read_register : context_t -> int -> int32
    34.8  val read_registers : context_t -> registers
    34.9  val write_register : context_t -> register -> int32 -> unit
   34.10  val read_memory : context_t -> int32 -> int -> int list
    35.1 --- a/tools/debugger/pdb/Makefile	Tue Aug 16 12:15:23 2005 +0800
    35.2 +++ b/tools/debugger/pdb/Makefile	Tue Aug 16 10:09:07 2005 -0800
    35.3 @@ -33,7 +33,8 @@ LIBDIRS    += ../libxendebug
    35.4  LIBS       += unix str
    35.5  
    35.6  # bc = byte-code, dc = debug byte-code
    35.7 -all : patches dc
    35.8 +# patches = patch linux domU source code
    35.9 +all : dc
   35.10  
   35.11  SOURCES    += pdb_caml_xc.c 
   35.12  SOURCES    += pdb_caml_domain.c pdb_caml_process.c
    36.1 --- a/tools/debugger/pdb/PDB.ml	Tue Aug 16 12:15:23 2005 +0800
    36.2 +++ b/tools/debugger/pdb/PDB.ml	Tue Aug 16 10:09:07 2005 -0800
    36.3 @@ -219,6 +219,17 @@ let add_default_context sock =
    36.4  
    36.5  (***************************************************************************)
    36.6  
    36.7 +let read_register ctx register =    (* register is int32 because of sscanf *)
    36.8 +  match ctx with
    36.9 +  | Void -> 0l                                      (* default for startup *)
   36.10 +  | Domain d  -> Domain.read_register d register
   36.11 +  | Process p ->
   36.12 +      begin
   36.13 +	Process.read_register p register;
   36.14 +	raise No_reply
   36.15 +      end
   36.16 +  | _ -> raise (Unimplemented "read registers")
   36.17 +
   36.18  let read_registers ctx =
   36.19    match ctx with
   36.20    | Void -> Intel.null_registers                    (* default for startup *)
   36.21 @@ -278,15 +289,43 @@ let step ctx =
   36.22  let insert_memory_breakpoint ctx addr len =
   36.23    match ctx with
   36.24    | Domain d  -> Domain.insert_memory_breakpoint d addr len
   36.25 -  | Process p  -> Process.insert_memory_breakpoint p addr len
   36.26 +  | Process p  ->
   36.27 +      begin
   36.28 +	Process.insert_memory_breakpoint p addr len;
   36.29 +	raise No_reply
   36.30 +      end
   36.31    | _ -> raise (Unimplemented "insert memory breakpoint")
   36.32  
   36.33  let remove_memory_breakpoint ctx addr len =
   36.34    match ctx with
   36.35    | Domain d  -> Domain.remove_memory_breakpoint d addr len
   36.36 -  | Process p  -> Process.remove_memory_breakpoint p addr len
   36.37 +  | Process p  ->
   36.38 +      begin
   36.39 +	Process.remove_memory_breakpoint p addr len;
   36.40 +	raise No_reply
   36.41 +      end
   36.42    | _ -> raise (Unimplemented "remove memory breakpoint")
   36.43  
   36.44 +let insert_watchpoint ctx kind addr len =
   36.45 +  match ctx with
   36.46 +(*  | Domain d  -> Domain.insert_watchpoint d kind addr len  TODO *)
   36.47 +  | Process p  ->
   36.48 +      begin
   36.49 +	Process.insert_watchpoint p kind addr len;
   36.50 +	raise No_reply
   36.51 +      end
   36.52 +  | _ -> raise (Unimplemented "insert watchpoint")
   36.53 +
   36.54 +let remove_watchpoint ctx kind addr len =
   36.55 +  match ctx with
   36.56 +(*  | Domain d  -> Domain.remove_watchpoint d kind addr len  TODO *)
   36.57 +  | Process p  ->
   36.58 +      begin
   36.59 +	Process.remove_watchpoint p kind addr len;
   36.60 +	raise No_reply
   36.61 +      end
   36.62 +  | _ -> raise (Unimplemented "remove watchpoint")
   36.63 +
   36.64  
   36.65  let pause ctx =
   36.66    match ctx with
    37.1 --- a/tools/debugger/pdb/Process.ml	Tue Aug 16 12:15:23 2005 +0800
    37.2 +++ b/tools/debugger/pdb/Process.ml	Tue Aug 16 10:09:07 2005 -0800
    37.3 @@ -54,6 +54,7 @@ let attach_debugger proc_ctx dom_ctx =
    37.4    proc_ctx.ring   <- Xen_domain.get_ring   dom_ctx;
    37.5    _attach_debugger proc_ctx
    37.6  
    37.7 +external read_register : context_t -> int -> unit = "proc_read_register"
    37.8  external read_registers : context_t -> unit = "proc_read_registers"
    37.9  external write_register : context_t -> register -> int32 -> unit =
   37.10    "proc_write_register"
   37.11 @@ -69,6 +70,10 @@ external insert_memory_breakpoint : cont
   37.12    "proc_insert_memory_breakpoint"
   37.13  external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
   37.14    "proc_remove_memory_breakpoint"
   37.15 +external insert_watchpoint : context_t -> int -> int32 -> int -> unit =
   37.16 +  "proc_insert_watchpoint"
   37.17 +external remove_watchpoint : context_t -> int -> int32 -> int -> unit =
   37.18 +  "proc_remove_watchpoint"
   37.19  
   37.20  let pause ctx =
   37.21    pause_target ctx
    38.1 --- a/tools/debugger/pdb/Process.mli	Tue Aug 16 12:15:23 2005 +0800
    38.2 +++ b/tools/debugger/pdb/Process.mli	Tue Aug 16 10:09:07 2005 -0800
    38.3 @@ -26,7 +26,7 @@ val attach_debugger : context_t -> Xen_d
    38.4  val detach_debugger : context_t -> unit
    38.5  val pause : context_t -> unit
    38.6  
    38.7 -
    38.8 +val read_register : context_t -> int -> unit
    38.9  val read_registers : context_t -> unit
   38.10  val write_register : context_t -> register -> int32 -> unit
   38.11  val read_memory : context_t -> int32 -> int -> unit
   38.12 @@ -37,3 +37,5 @@ val step : context_t -> unit
   38.13  
   38.14  val insert_memory_breakpoint : context_t -> int32 -> int -> unit
   38.15  val remove_memory_breakpoint : context_t -> int32 -> int -> unit
   38.16 +val insert_watchpoint : context_t -> int -> int32 -> int -> unit
   38.17 +val remove_watchpoint : context_t -> int -> int32 -> int -> unit
    39.1 --- a/tools/debugger/pdb/debugger.ml	Tue Aug 16 12:15:23 2005 +0800
    39.2 +++ b/tools/debugger/pdb/debugger.ml	Tue Aug 16 10:09:07 2005 -0800
    39.3 @@ -53,10 +53,20 @@ let gdb_step ctx =
    39.4    PDB.step ctx;
    39.5    raise No_reply
    39.6  
    39.7 +(**
    39.8 +   Read Register Command.
    39.9 +   return register as a 4-byte value.
   39.10 + *)
   39.11 +let gdb_read_register ctx command =
   39.12 +  let read_reg register =
   39.13 +    (Printf.sprintf "%08lx" (Util.flip_int32 (PDB.read_register ctx register)))
   39.14 +  in
   39.15 +  Scanf.sscanf command "p%x" read_reg
   39.16 +    
   39.17  
   39.18  (**
   39.19     Read Registers Command.
   39.20 -   returns 16 4-byte registers in a particular defined by gdb.
   39.21 +   returns 16 4-byte registers in a particular format defined by gdb.
   39.22   *)
   39.23  let gdb_read_registers ctx =
   39.24    let regs = PDB.read_registers ctx in
   39.25 @@ -100,7 +110,7 @@ let gdb_read_memory ctx command =
   39.26      with
   39.27        Failure s -> "E02"
   39.28    in
   39.29 -  Scanf.sscanf command "m%lx,%d" read_mem
   39.30 +  Scanf.sscanf command "m%lx,%x" read_mem
   39.31  
   39.32  
   39.33  
   39.34 @@ -218,16 +228,24 @@ let pdb_extensions command sock =
   39.35  (**
   39.36     Insert Breakpoint or Watchpoint Packet
   39.37   *)
   39.38 +
   39.39 +let bwc_watch_write  = 102                              (* from pdb_module.h *)
   39.40 +let bwc_watch_read   = 103
   39.41 +let bwc_watch_access = 104
   39.42 +
   39.43  let gdb_insert_bwcpoint ctx command =
   39.44    let insert cmd addr length =
   39.45      try
   39.46        match cmd with
   39.47        | 0 -> PDB.insert_memory_breakpoint ctx addr length; "OK"
   39.48 +      | 2 -> PDB.insert_watchpoint ctx bwc_watch_write  addr length; "OK"
   39.49 +      | 3 -> PDB.insert_watchpoint ctx bwc_watch_read   addr length; "OK"
   39.50 +      | 4 -> PDB.insert_watchpoint ctx bwc_watch_access addr length; "OK"
   39.51        | _ -> ""
   39.52      with
   39.53        Failure s -> "E03"
   39.54    in
   39.55 -  Scanf.sscanf command "Z%d,%lx,%d" insert
   39.56 +  Scanf.sscanf command "Z%d,%lx,%x" insert
   39.57  
   39.58  (**
   39.59     Remove Breakpoint or Watchpoint Packet
   39.60 @@ -237,6 +255,9 @@ let gdb_remove_bwcpoint ctx command =
   39.61      try
   39.62        match cmd with
   39.63        | 0 -> PDB.remove_memory_breakpoint ctx addr length; "OK"
   39.64 +      | 2 -> PDB.remove_watchpoint ctx bwc_watch_write  addr length; "OK"
   39.65 +      | 3 -> PDB.remove_watchpoint ctx bwc_watch_read   addr length; "OK"
   39.66 +      | 4 -> PDB.remove_watchpoint ctx bwc_watch_access addr length; "OK"
   39.67        | _ -> ""
   39.68      with
   39.69        Failure s -> "E04"
   39.70 @@ -260,6 +281,7 @@ let process_command command sock =
   39.71      | 'k' -> gdb_kill ()
   39.72      | 'm' -> gdb_read_memory ctx command
   39.73      | 'M' -> gdb_write_memory ctx command
   39.74 +    | 'p' -> gdb_read_register ctx command
   39.75      | 'P' -> gdb_write_register ctx command
   39.76      | 'q' -> gdb_query command
   39.77      | 's' -> gdb_step ctx
   39.78 @@ -270,7 +292,7 @@ let process_command command sock =
   39.79      | 'Z' -> gdb_insert_bwcpoint ctx command
   39.80      | _ -> 
   39.81  	print_endline (Printf.sprintf "unknown gdb command [%s]" command);
   39.82 -	"E02"
   39.83 +	""
   39.84    with
   39.85      Unimplemented s ->
   39.86        print_endline (Printf.sprintf "loser. unimplemented command [%s][%s]" 
    40.1 --- a/tools/debugger/pdb/linux-2.6-module/debug.c	Tue Aug 16 12:15:23 2005 +0800
    40.2 +++ b/tools/debugger/pdb/linux-2.6-module/debug.c	Tue Aug 16 10:09:07 2005 -0800
    40.3 @@ -9,33 +9,143 @@
    40.4  #include <asm-i386/kdebug.h>
    40.5  #include <asm-xen/asm-i386/processor.h>
    40.6  #include <asm-xen/asm-i386/ptrace.h>
    40.7 +#include <asm-xen/asm-i386/tlbflush.h>
    40.8  #include <asm-xen/xen-public/xen.h>
    40.9  #include "pdb_module.h"
   40.10  #include "pdb_debug.h"
   40.11  
   40.12 -#define BWC_DEBUG 1
   40.13 -#define BWC_INT3  3
   40.14 +
   40.15 +static int pdb_debug_fn (struct pt_regs *regs, long error_code,
   40.16 +                         unsigned int condition);
   40.17 +static int pdb_int3_fn (struct pt_regs *regs, long error_code);
   40.18 +static int pdb_page_fault_fn (struct pt_regs *regs, long error_code,
   40.19 +                              unsigned int condition);
   40.20 +
   40.21 +/***********************************************************************/
   40.22 +
   40.23  typedef struct bwcpoint                           /* break/watch/catch point */
   40.24  {
   40.25      struct list_head list;
   40.26      memory_t address;
   40.27 -    u32 domain;
   40.28 +    int length;
   40.29 +
   40.30 +    u8  type;                                                     /* BWC_??? */
   40.31 +    u8  mode;                   /* for BWC_PAGE, the current protection mode */
   40.32      u32 process;
   40.33 -    u8  old_value;                            /* old value for software bkpt */
   40.34 -    u8  type;                                                     /* BWC_??? */
   40.35 +    u8  error;                /* error occured when enabling: don't disable. */
   40.36 +
   40.37 +    /* original values */
   40.38 +    u8    orig_bkpt;                               /* single byte breakpoint */
   40.39 +    pte_t orig_pte;
   40.40 +
   40.41 +    struct list_head watchpt_read_list;     /* read watchpoints on this page */
   40.42 +    struct list_head watchpt_write_list;                            /* write */
   40.43 +    struct list_head watchpt_access_list;                          /* access */
   40.44 +    struct list_head watchpt_disabled_list;                      /* disabled */
   40.45 +
   40.46 +    struct bwcpoint *parent;             /* watchpoint: bwc_watch (the page) */
   40.47 +    struct bwcpoint *watchpoint;      /* bwc_watch_step: original watchpoint */
   40.48  } bwcpoint_t, *bwcpoint_p;
   40.49  
   40.50 -static bwcpoint_t bwcpoint_list;
   40.51 +static struct list_head bwcpoint_list = LIST_HEAD_INIT(bwcpoint_list);
   40.52 +
   40.53 +#define _pdb_bwcpoint_alloc(_var) \
   40.54 +{ \
   40.55 +    if ( (_var = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL)) == NULL ) \
   40.56 +        printk("error: unable to allocate memory %d\n", __LINE__); \
   40.57 +    else { \
   40.58 +        memset(_var, 0, sizeof(bwcpoint_t)); \
   40.59 +        INIT_LIST_HEAD(&_var->watchpt_read_list); \
   40.60 +        INIT_LIST_HEAD(&_var->watchpt_write_list); \
   40.61 +        INIT_LIST_HEAD(&_var->watchpt_access_list); \
   40.62 +        INIT_LIST_HEAD(&_var->watchpt_disabled_list); \
   40.63 +    } \
   40.64 +}
   40.65 +
   40.66 +/***********************************************************************/
   40.67 +
   40.68 +static void _pdb_bwc_print_list (struct list_head *, char *, int);
   40.69 +
   40.70 +static void
   40.71 +_pdb_bwc_print (bwcpoint_p bwc, char *label, int level)
   40.72 +{
   40.73 +    printk("%s%03d 0x%08lx:0x%02x %c\n", label, bwc->type,
   40.74 +           bwc->address, bwc->length, bwc->error ? 'e' : '-');
   40.75 +
   40.76 +    if ( !list_empty(&bwc->watchpt_read_list) )
   40.77 +        _pdb_bwc_print_list(&bwc->watchpt_read_list, "r", level);
   40.78 +    if ( !list_empty(&bwc->watchpt_write_list) )
   40.79 +        _pdb_bwc_print_list(&bwc->watchpt_write_list, "w", level);
   40.80 +    if ( !list_empty(&bwc->watchpt_access_list) )
   40.81 +        _pdb_bwc_print_list(&bwc->watchpt_access_list, "a", level);
   40.82 +    if ( !list_empty(&bwc->watchpt_disabled_list) )
   40.83 +        _pdb_bwc_print_list(&bwc->watchpt_disabled_list, "d", level);
   40.84 +}
   40.85 +
   40.86 +static void
   40.87 +_pdb_bwc_print_list (struct list_head *bwc_list, char *label, int level)
   40.88 +{
   40.89 +    struct list_head *ptr;
   40.90 +    int counter = 0;
   40.91 +
   40.92 +    list_for_each(ptr, bwc_list)
   40.93 +    {
   40.94 +        bwcpoint_p bwc = list_entry(ptr, bwcpoint_t, list);
   40.95 +        printk("  %s[%02d]%s ", level > 0 ? "  " : "", counter++,
   40.96 +                                level > 0 ? "" : "  ");
   40.97 +        _pdb_bwc_print(bwc, label, level+1);
   40.98 +    }
   40.99 +
  40.100 +    if (counter == 0)
  40.101 +    {
  40.102 +        printk("  empty list\n");
  40.103 +    }
  40.104 +}
  40.105  
  40.106  void
  40.107 -pdb_initialize_bwcpoint (void)
  40.108 +pdb_bwc_print_list (void)
  40.109  {
  40.110 -    memset((void *) &bwcpoint_list, 0, sizeof(bwcpoint_t));
  40.111 -    INIT_LIST_HEAD(&bwcpoint_list.list);
  40.112 -
  40.113 -    return;
  40.114 +    _pdb_bwc_print_list(&bwcpoint_list, " ", 0);
  40.115  }
  40.116  
  40.117 +bwcpoint_p
  40.118 +pdb_search_watchpoint (u32 process, memory_t address)
  40.119 +{
  40.120 +    bwcpoint_p bwc_watch = (bwcpoint_p) 0;
  40.121 +    bwcpoint_p bwc_entry = (bwcpoint_p) 0;
  40.122 +    struct list_head *ptr;
  40.123 +
  40.124 +    list_for_each(ptr, &bwcpoint_list)                /* find bwc page entry */
  40.125 +    {
  40.126 +        bwc_watch = list_entry(ptr, bwcpoint_t, list);
  40.127 +        if (bwc_watch->address == (address & PAGE_MASK)) break;
  40.128 +    }
  40.129 +
  40.130 +    if ( !bwc_watch )
  40.131 +    {
  40.132 +        return (bwcpoint_p) 0;
  40.133 +    }
  40.134 +
  40.135 +#define __pdb_search_watchpoint_list(__list) \
  40.136 +    list_for_each(ptr, (__list))  \
  40.137 +    { \
  40.138 +        bwc_entry = list_entry(ptr, bwcpoint_t, list); \
  40.139 +        if ( bwc_entry->process == process &&          \
  40.140 +             bwc_entry->address <= address &&          \
  40.141 +             bwc_entry->address + bwc_entry->length > address ) \
  40.142 +            return bwc_entry; \
  40.143 +    }
  40.144 +
  40.145 +    __pdb_search_watchpoint_list(&bwc_watch->watchpt_read_list);
  40.146 +    __pdb_search_watchpoint_list(&bwc_watch->watchpt_write_list);
  40.147 +    __pdb_search_watchpoint_list(&bwc_watch->watchpt_access_list);
  40.148 +
  40.149 +#undef __pdb_search_watchpoint_list
  40.150 +
  40.151 +    return (bwcpoint_p) 0;
  40.152 +}
  40.153 +
  40.154 +/*************************************************************/
  40.155  
  40.156  int
  40.157  pdb_suspend (struct task_struct *target)
  40.158 @@ -137,6 +247,35 @@ static void
  40.159  }
  40.160  
  40.161  int
  40.162 +pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op)
  40.163 +{
  40.164 +    int rc = 0;
  40.165 +
  40.166 +    switch (op->reg)
  40.167 +    {
  40.168 +    case  0: op->value = _pdb_get_register(target, LINUX_EAX); break;
  40.169 +    case  1: op->value = _pdb_get_register(target, LINUX_ECX); break;
  40.170 +    case  2: op->value = _pdb_get_register(target, LINUX_EDX); break;
  40.171 +    case  3: op->value = _pdb_get_register(target, LINUX_EBX); break;
  40.172 +    case  4: op->value = _pdb_get_register(target, LINUX_ESP); break;
  40.173 +    case  5: op->value = _pdb_get_register(target, LINUX_EBP); break;
  40.174 +    case  6: op->value = _pdb_get_register(target, LINUX_ESI); break;
  40.175 +    case  7: op->value = _pdb_get_register(target, LINUX_EDI); break;
  40.176 +    case  8: op->value = _pdb_get_register(target, LINUX_EIP); break;
  40.177 +    case  9: op->value = _pdb_get_register(target, LINUX_EFL); break;
  40.178 +
  40.179 +    case 10: op->value = _pdb_get_register(target, LINUX_CS); break;
  40.180 +    case 11: op->value = _pdb_get_register(target, LINUX_SS); break;
  40.181 +    case 12: op->value = _pdb_get_register(target, LINUX_DS); break;
  40.182 +    case 13: op->value = _pdb_get_register(target, LINUX_ES); break;
  40.183 +    case 14: op->value = _pdb_get_register(target, LINUX_FS); break;
  40.184 +    case 15: op->value = _pdb_get_register(target, LINUX_GS); break;
  40.185 +    }
  40.186 +
  40.187 +    return rc;
  40.188 +}
  40.189 +
  40.190 +int
  40.191  pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op)
  40.192  {
  40.193      int rc = 0;
  40.194 @@ -209,18 +348,14 @@ pdb_step (struct task_struct *target)
  40.195      eflags |= X86_EFLAGS_TF;
  40.196      _pdb_set_register(target, LINUX_EFL, eflags);
  40.197  
  40.198 -    bkpt = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL);
  40.199 -    if ( bkpt == NULL )
  40.200 -    {
  40.201 -        printk("error: unable to allocation memory\n");
  40.202 -        return -1;
  40.203 -    }
  40.204 +    _pdb_bwcpoint_alloc(bkpt);
  40.205 +    if ( bkpt == NULL )  return -1;
  40.206  
  40.207      bkpt->process = target->pid;
  40.208      bkpt->address = 0;
  40.209      bkpt->type    = BWC_DEBUG;
  40.210      
  40.211 -    list_add(&bkpt->list, &bwcpoint_list.list);
  40.212 +    list_add_tail(&bkpt->list, &bwcpoint_list);
  40.213  
  40.214      wake_up_process(target);
  40.215  
  40.216 @@ -237,31 +372,27 @@ pdb_insert_memory_breakpoint (struct tas
  40.217  
  40.218      printk("insert breakpoint %d:%lx len: %d\n", target->pid, address, length);
  40.219  
  40.220 -    bkpt = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL);
  40.221 -    if ( bkpt == NULL )
  40.222 +    if ( length != 1 )
  40.223      {
  40.224 -        printk("error: unable to allocation memory\n");
  40.225 +        printk("error: breakpoint length should be 1\n");
  40.226          return -1;
  40.227      }
  40.228  
  40.229 -    if ( length != 1 )
  40.230 -    {
  40.231 -        printk("error: breakpoint length should be 1\n");
  40.232 -        kfree(bkpt);
  40.233 -        return -1;
  40.234 -    }
  40.235 +    _pdb_bwcpoint_alloc(bkpt);
  40.236 +    if ( bkpt == NULL ) return -1;
  40.237  
  40.238      bkpt->process = target->pid;
  40.239      bkpt->address = address;
  40.240      bkpt->type    = BWC_INT3;
  40.241  
  40.242 -    pdb_access_memory(target, address, &bkpt->old_value, 1, 0);
  40.243 -    pdb_access_memory(target, address, &breakpoint_opcode, 1, 1);
  40.244 +    pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_READ);
  40.245 +    pdb_access_memory(target, address, &breakpoint_opcode, 1, PDB_MEM_WRITE);
  40.246      
  40.247 -    list_add(&bkpt->list, &bwcpoint_list.list);
  40.248 +    list_add_tail(&bkpt->list, &bwcpoint_list);
  40.249  
  40.250      printk("breakpoint_set %d:%lx  OLD: 0x%x\n",
  40.251 -           target->pid, address, bkpt->old_value);
  40.252 +           target->pid, address, bkpt->orig_bkpt);
  40.253 +    pdb_bwc_print_list();
  40.254  
  40.255      return rc;
  40.256  }
  40.257 @@ -276,7 +407,7 @@ pdb_remove_memory_breakpoint (struct tas
  40.258      printk ("remove breakpoint %d:%lx\n", target->pid, address);
  40.259  
  40.260      struct list_head *entry;
  40.261 -    list_for_each(entry, &bwcpoint_list.list)
  40.262 +    list_for_each(entry, &bwcpoint_list)
  40.263      {
  40.264          bkpt = list_entry(entry, bwcpoint_t, list);
  40.265          if ( target->pid == bkpt->process && 
  40.266 @@ -285,17 +416,223 @@ pdb_remove_memory_breakpoint (struct tas
  40.267              break;
  40.268      }
  40.269      
  40.270 -    if (bkpt == &bwcpoint_list || bkpt == NULL)
  40.271 +    if (entry == &bwcpoint_list)
  40.272      {
  40.273          printk ("error: no breakpoint found\n");
  40.274          return -1;
  40.275      }
  40.276  
  40.277 -    list_del(&bkpt->list);
  40.278 +    pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_WRITE);
  40.279  
  40.280 -    pdb_access_memory(target, address, &bkpt->old_value, 1, 1);
  40.281 +    list_del(&bkpt->list);
  40.282 +    kfree(bkpt);
  40.283  
  40.284 -    kfree(bkpt);
  40.285 +    pdb_bwc_print_list();
  40.286 +
  40.287 +    return rc;
  40.288 +}
  40.289 +
  40.290 +#define PDB_PTE_UPDATE   1
  40.291 +#define PDB_PTE_RESTORE  2
  40.292 +
  40.293 +int
  40.294 +pdb_change_pte (struct task_struct *target, bwcpoint_p bwc, int mode)
  40.295 +{
  40.296 +    int rc = 0;
  40.297 +    pgd_t *pgd;
  40.298 +    pud_t *pud;
  40.299 +    pmd_t *pmd;
  40.300 +    pte_t *ptep;
  40.301 +
  40.302 +    pgd = pgd_offset(target->mm, bwc->address);
  40.303 +    if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))  return -1;
  40.304 +
  40.305 +    pud = pud_offset(pgd, bwc->address);
  40.306 +    if (pud_none(*pud) || unlikely(pud_bad(*pud))) return -2;
  40.307 +
  40.308 +    pmd = pmd_offset(pud, bwc->address);
  40.309 +    if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) return -3;
  40.310 +
  40.311 +    ptep = pte_offset_map(pmd, bwc->address);
  40.312 +    if (!ptep)  return -4;
  40.313 +
  40.314 +    switch ( mode )
  40.315 +    {
  40.316 +    case PDB_PTE_UPDATE:      /* added or removed a watchpoint.  update pte. */
  40.317 +    {
  40.318 +        pte_t new_pte;
  40.319 +
  40.320 +        if ( pte_val(bwc->parent->orig_pte) == 0 )    /* new watchpoint page */
  40.321 +        {
  40.322 +            bwc->parent->orig_pte = *ptep;
  40.323 +        }
  40.324 +
  40.325 +        new_pte = bwc->parent->orig_pte;
  40.326 +
  40.327 +        if ( !list_empty(&bwc->parent->watchpt_read_list)  || 
  40.328 +             !list_empty(&bwc->parent->watchpt_access_list) )
  40.329 +        {
  40.330 +            new_pte = pte_rdprotect(new_pte);
  40.331 +        }
  40.332 +
  40.333 +        if ( !list_empty(&bwc->parent->watchpt_write_list) ||
  40.334 +             !list_empty(&bwc->parent->watchpt_access_list) )
  40.335 +        {
  40.336 +            new_pte = pte_wrprotect(new_pte);
  40.337 +        }
  40.338 +        
  40.339 +        if ( pte_val(new_pte) != pte_val(*ptep) )
  40.340 +        {
  40.341 +            *ptep = new_pte;
  40.342 +            flush_tlb_mm(target->mm);
  40.343 +        }
  40.344 +        break;
  40.345 +    }
  40.346 +    case PDB_PTE_RESTORE :   /* suspend watchpoint by restoring original pte */
  40.347 +    {
  40.348 +        *ptep = bwc->parent->orig_pte;
  40.349 +        flush_tlb_mm(target->mm);
  40.350 +        break;
  40.351 +    }
  40.352 +    default :
  40.353 +    {
  40.354 +        printk("(linux) unknown mode %d %d\n", mode, __LINE__);
  40.355 +        break;
  40.356 +    }
  40.357 +    }
  40.358 +
  40.359 +    pte_unmap(ptep);                /* can i flush the tlb before pte_unmap? */
  40.360 +
  40.361 +    return rc;
  40.362 +}
  40.363 +
  40.364 +int
  40.365 +pdb_insert_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
  40.366 +{
  40.367 +    int rc = 0;
  40.368 +
  40.369 +    bwcpoint_p bwc_watch;
  40.370 +    bwcpoint_p bwc_entry;
  40.371 +    struct list_head *ptr;
  40.372 +    unsigned long page = watchpt->address & PAGE_MASK;
  40.373 +    struct list_head *watchpoint_list;
  40.374 +    
  40.375 +    printk("insert watchpoint: %d %x %x\n", 
  40.376 +           watchpt->type, watchpt->address, watchpt->length);
  40.377 +
  40.378 +    list_for_each(ptr, &bwcpoint_list) /* find existing bwc page entry */
  40.379 +    {
  40.380 +        bwc_watch = list_entry(ptr, bwcpoint_t, list);
  40.381 +
  40.382 +        if (bwc_watch->address == page)  goto got_bwc_watch;
  40.383 +    }
  40.384 +
  40.385 +    _pdb_bwcpoint_alloc(bwc_watch);                  /* create new bwc:watch */
  40.386 +    if ( bwc_watch == NULL ) return -1;
  40.387 +
  40.388 +    bwc_watch->type    = BWC_WATCH;
  40.389 +    bwc_watch->process = target->pid;
  40.390 +    bwc_watch->address = page;
  40.391 +
  40.392 +    list_add_tail(&bwc_watch->list, &bwcpoint_list);
  40.393 +
  40.394 + got_bwc_watch:
  40.395 +
  40.396 +    switch (watchpt->type)
  40.397 +    {
  40.398 +    case BWC_WATCH_READ:
  40.399 +        watchpoint_list = &bwc_watch->watchpt_read_list; break;
  40.400 +    case BWC_WATCH_WRITE: 
  40.401 +        watchpoint_list = &bwc_watch->watchpt_write_list; break;
  40.402 +    case BWC_WATCH_ACCESS:
  40.403 +        watchpoint_list = &bwc_watch->watchpt_access_list; break;
  40.404 +    default:
  40.405 +        printk("unknown type %d\n", watchpt->type); return -2;
  40.406 +    }
  40.407 +
  40.408 +    _pdb_bwcpoint_alloc(bwc_entry);                  /* create new bwc:entry */
  40.409 +    if ( bwc_entry == NULL ) return -1;
  40.410 +
  40.411 +    bwc_entry->process = target->pid;
  40.412 +    bwc_entry->address = watchpt->address;
  40.413 +    bwc_entry->length  = watchpt->length;
  40.414 +    bwc_entry->type    = watchpt->type;
  40.415 +    bwc_entry->parent  = bwc_watch;
  40.416 +
  40.417 +    list_add_tail(&bwc_entry->list, watchpoint_list);
  40.418 +    pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
  40.419 +
  40.420 +    pdb_bwc_print_list();
  40.421 +
  40.422 +    return rc;
  40.423 +}
  40.424 +
  40.425 +int 
  40.426 +pdb_remove_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
  40.427 +{
  40.428 +    int rc = 0;
  40.429 +    bwcpoint_p bwc_watch = (bwcpoint_p) NULL;
  40.430 +    bwcpoint_p bwc_entry = (bwcpoint_p) NULL;
  40.431 +    unsigned long page = watchpt->address & PAGE_MASK;
  40.432 +    struct list_head *ptr;
  40.433 +    struct list_head *watchpoint_list;
  40.434 +
  40.435 +    printk("remove watchpoint: %d %x %x\n", 
  40.436 +           watchpt->type, watchpt->address, watchpt->length);
  40.437 +
  40.438 +    list_for_each(ptr, &bwcpoint_list)                /* find bwc page entry */
  40.439 +    {
  40.440 +        bwc_watch = list_entry(ptr, bwcpoint_t, list);
  40.441 +        if (bwc_watch->address == page) break;
  40.442 +    }
  40.443 +
  40.444 +    if ( !bwc_watch )
  40.445 +    {
  40.446 +        printk("(linux) delete watchpoint: can't find bwc page 0x%08x\n",
  40.447 +               watchpt->address);
  40.448 +        return -1;
  40.449 +    }
  40.450 +
  40.451 +    switch (watchpt->type)
  40.452 +    {
  40.453 +    case BWC_WATCH_READ:
  40.454 +        watchpoint_list = &bwc_watch->watchpt_read_list; break;
  40.455 +    case BWC_WATCH_WRITE:
  40.456 +        watchpoint_list = &bwc_watch->watchpt_write_list; break;
  40.457 +    case BWC_WATCH_ACCESS:
  40.458 +        watchpoint_list = &bwc_watch->watchpt_access_list; break;
  40.459 +    default:
  40.460 +        printk("unknown type %d\n", watchpt->type); return -2;
  40.461 +    }
  40.462 +
  40.463 +    list_for_each(ptr, watchpoint_list)                   /* find watchpoint */
  40.464 +    {
  40.465 +        bwc_entry = list_entry(ptr, bwcpoint_t, list);
  40.466 +        if ( bwc_entry->address == watchpt->address &&
  40.467 +             bwc_entry->length  == watchpt->length ) break;
  40.468 +    }
  40.469 +
  40.470 +    if ( !bwc_entry )                           /* or ptr == watchpoint_list */
  40.471 +    {
  40.472 +        printk("(linux) delete watchpoint: can't find watchpoint 0x%08x\n",
  40.473 +               watchpt->address);
  40.474 +        return -1;
  40.475 +    }
  40.476 +    
  40.477 +    list_del(&bwc_entry->list);
  40.478 +    pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
  40.479 +    kfree(bwc_entry);
  40.480 +
  40.481 +
  40.482 +    if ( list_empty(&bwc_watch->watchpt_read_list)  &&
  40.483 +         list_empty(&bwc_watch->watchpt_write_list) &&
  40.484 +         list_empty(&bwc_watch->watchpt_access_list) )
  40.485 +    {
  40.486 +        list_del(&bwc_watch->list);
  40.487 +        kfree(bwc_watch);
  40.488 +    }
  40.489 +
  40.490 +    pdb_bwc_print_list();
  40.491  
  40.492      return rc;
  40.493  }
  40.494 @@ -312,16 +649,24 @@ pdb_exceptions_notify (struct notifier_b
  40.495  	switch (val) 
  40.496      {
  40.497  	case DIE_DEBUG:
  40.498 -		if (pdb_debug_fn(args->regs, args->trapnr, args->err))
  40.499 +		if ( pdb_debug_fn(args->regs, args->trapnr, args->err) )
  40.500  			return NOTIFY_STOP;
  40.501  		break;
  40.502      case DIE_TRAP:
  40.503 -		if (args->trapnr == 3 && pdb_int3_fn(args->regs, args->err))
  40.504 +		if ( args->trapnr == 3 && pdb_int3_fn(args->regs, args->err) )
  40.505  			return NOTIFY_STOP;
  40.506          break;
  40.507  	case DIE_INT3:          /* without kprobes, we should never see DIE_INT3 */
  40.508 +		if ( pdb_int3_fn(args->regs, args->err) )
  40.509 +			return NOTIFY_STOP;
  40.510 +		break;
  40.511 +	case DIE_PAGE_FAULT:
  40.512 +		if ( pdb_page_fault_fn(args->regs, args->trapnr, args->err) )
  40.513 +			return NOTIFY_STOP;
  40.514 +		break;
  40.515  	case DIE_GPF:
  40.516 -	case DIE_PAGE_FAULT:
  40.517 +        printk("---------------GPF\n");
  40.518 +        break;
  40.519  	default:
  40.520  		break;
  40.521  	}
  40.522 @@ -330,70 +675,110 @@ pdb_exceptions_notify (struct notifier_b
  40.523  }
  40.524  
  40.525  
  40.526 -int
  40.527 +static int
  40.528  pdb_debug_fn (struct pt_regs *regs, long error_code, 
  40.529                     unsigned int condition)
  40.530  {
  40.531      pdb_response_t resp;
  40.532      bwcpoint_p bkpt = NULL;
  40.533 +    struct list_head *entry;
  40.534  
  40.535 -    struct list_head *entry;
  40.536 -    list_for_each(entry, &bwcpoint_list.list)
  40.537 +    printk("pdb_debug_fn\n");
  40.538 +
  40.539 +    list_for_each(entry, &bwcpoint_list)
  40.540      {
  40.541          bkpt = list_entry(entry, bwcpoint_t, list);
  40.542          if ( current->pid == bkpt->process && 
  40.543 -             bkpt->type == BWC_DEBUG )
  40.544 +             (bkpt->type == BWC_DEBUG ||                      /* single step */
  40.545 +              bkpt->type == BWC_WATCH_STEP))  /* single step over watchpoint */
  40.546              break;
  40.547      }
  40.548      
  40.549 -    if (bkpt == &bwcpoint_list || bkpt == NULL)
  40.550 +    if (entry == &bwcpoint_list)
  40.551      {
  40.552          printk("not my debug  0x%x 0x%lx\n", current->pid, regs->eip);
  40.553          return 0;
  40.554      }
  40.555  
  40.556 -    list_del(&bkpt->list);
  40.557 -
  40.558      pdb_suspend(current);
  40.559  
  40.560 -    printk("(pdb) debug  pid: %d, eip: 0x%08lx\n", current->pid, regs->eip);
  40.561 +    printk("(pdb) %s  pid: %d, eip: 0x%08lx\n", 
  40.562 +           bkpt->type == BWC_DEBUG ? "debug" : "watch-step",
  40.563 +           current->pid, regs->eip);
  40.564  
  40.565      regs->eflags &= ~X86_EFLAGS_TF;
  40.566  	set_tsk_thread_flag(current, TIF_SINGLESTEP);
  40.567  
  40.568 -    resp.operation = PDB_OPCODE_STEP;
  40.569 +    switch (bkpt->type)
  40.570 +    {
  40.571 +    case BWC_DEBUG:
  40.572 +        resp.operation = PDB_OPCODE_STEP;
  40.573 +        break;
  40.574 +    case BWC_WATCH_STEP:
  40.575 +    {
  40.576 +        struct list_head *watchpoint_list;
  40.577 +        bwcpoint_p watch_page = bkpt->watchpoint->parent;
  40.578 +
  40.579 +        switch (bkpt->watchpoint->type)
  40.580 +        {
  40.581 +        case BWC_WATCH_READ:
  40.582 +            watchpoint_list = &watch_page->watchpt_read_list; break;
  40.583 +        case BWC_WATCH_WRITE: 
  40.584 +            watchpoint_list = &watch_page->watchpt_write_list; break;
  40.585 +        case BWC_WATCH_ACCESS:
  40.586 +            watchpoint_list = &watch_page->watchpt_access_list; break;
  40.587 +        default:
  40.588 +            printk("unknown type %d\n", bkpt->watchpoint->type); return 0;
  40.589 +        }
  40.590 +
  40.591 +        resp.operation = PDB_OPCODE_WATCHPOINT;
  40.592 +        list_del_init(&bkpt->watchpoint->list);
  40.593 +        list_add_tail(&bkpt->watchpoint->list, watchpoint_list);
  40.594 +        pdb_change_pte(current, bkpt->watchpoint, PDB_PTE_UPDATE);
  40.595 +        pdb_bwc_print_list();
  40.596 +        break;
  40.597 +    }
  40.598 +    default:
  40.599 +        printk("unknown breakpoint type %d %d\n", __LINE__, bkpt->type);
  40.600 +        return 0;
  40.601 +    }
  40.602 +
  40.603      resp.process   = current->pid;
  40.604      resp.status    = PDB_RESPONSE_OKAY;
  40.605  
  40.606      pdb_send_response(&resp);
  40.607  
  40.608 +    list_del(&bkpt->list);
  40.609 +    kfree(bkpt);
  40.610 +
  40.611      return 1;
  40.612  }
  40.613  
  40.614  
  40.615 -int
  40.616 +static int
  40.617  pdb_int3_fn (struct pt_regs *regs, long error_code)
  40.618  {
  40.619      pdb_response_t resp;
  40.620      bwcpoint_p bkpt = NULL;
  40.621 +    memory_t address = regs->eip - 1;
  40.622  
  40.623      struct list_head *entry;
  40.624 -    list_for_each(entry, &bwcpoint_list.list)
  40.625 +    list_for_each(entry, &bwcpoint_list)
  40.626      {
  40.627          bkpt = list_entry(entry, bwcpoint_t, list);
  40.628          if ( current->pid == bkpt->process && 
  40.629 -             regs->eip == bkpt->address    &&
  40.630 +             address == bkpt->address      &&
  40.631               bkpt->type == BWC_INT3 )
  40.632              break;
  40.633      }
  40.634      
  40.635 -    if (bkpt == &bwcpoint_list || bkpt == NULL)
  40.636 +    if (entry == &bwcpoint_list)
  40.637      {
  40.638 -        printk("not my int3 bkpt  0x%x 0x%lx\n", current->pid, regs->eip);
  40.639 +        printk("not my int3 bkpt  0x%x 0x%lx\n", current->pid, address);
  40.640          return 0;
  40.641      }
  40.642  
  40.643 -    printk("(pdb) int3  pid: %d, eip: 0x%08lx\n", current->pid, regs->eip);
  40.644 +    printk("(pdb) int3  pid: %d, eip: 0x%08lx\n", current->pid, address);
  40.645  
  40.646      pdb_suspend(current);
  40.647  
  40.648 @@ -406,6 +791,54 @@ pdb_int3_fn (struct pt_regs *regs, long 
  40.649      return 1;
  40.650  }
  40.651  
  40.652 +static int
  40.653 +pdb_page_fault_fn (struct pt_regs *regs, long error_code, 
  40.654 +                   unsigned int condition)
  40.655 +{
  40.656 +    unsigned long cr2;
  40.657 +    unsigned long cr3;
  40.658 +    bwcpoint_p bwc;
  40.659 +    bwcpoint_p watchpt;
  40.660 +    bwcpoint_p bkpt;
  40.661 +
  40.662 +    __asm__ __volatile__ ("movl %%cr3,%0" : "=r" (cr3) : );
  40.663 +    __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (cr2) : );
  40.664 +
  40.665 +    bwc = pdb_search_watchpoint(current->pid, cr2);
  40.666 +    if ( !bwc )
  40.667 +    {
  40.668 +        return 0;                                                /* not mine */
  40.669 +    }
  40.670 +
  40.671 +    printk("page_fault cr2:%08lx err:%lx eip:%08lx\n", 
  40.672 +           cr2, error_code, regs->eip);
  40.673 +
  40.674 +    /* disable the watchpoint */
  40.675 +    watchpt = bwc->watchpoint;
  40.676 +    list_del_init(&bwc->list);
  40.677 +    list_add_tail(&bwc->list, &bwc->parent->watchpt_disabled_list);
  40.678 +    pdb_change_pte(current, bwc, PDB_PTE_RESTORE);
  40.679 +
  40.680 +    /* single step the faulting instruction */
  40.681 +    regs->eflags |= X86_EFLAGS_TF;
  40.682 +
  40.683 +    /* create a bwcpoint entry so we know what to do once we regain control */
  40.684 +    _pdb_bwcpoint_alloc(bkpt);
  40.685 +    if ( bkpt == NULL )  return -1;
  40.686 +
  40.687 +    bkpt->process    = current->pid;
  40.688 +    bkpt->address    = 0;
  40.689 +    bkpt->type       = BWC_WATCH_STEP;
  40.690 +    bkpt->watchpoint = bwc;
  40.691 +
  40.692 +    /* add to head so we see it first the next time we break */
  40.693 +    list_add(&bkpt->list, &bwcpoint_list);                
  40.694 +
  40.695 +    pdb_bwc_print_list();
  40.696 +    return 1;
  40.697 +}
  40.698 +
  40.699 +
  40.700  /*
  40.701   * Local variables:
  40.702   * mode: C
    41.1 --- a/tools/debugger/pdb/linux-2.6-module/module.c	Tue Aug 16 12:15:23 2005 +0800
    41.2 +++ b/tools/debugger/pdb/linux-2.6-module/module.c	Tue Aug 16 10:09:07 2005 -0800
    41.3 @@ -98,6 +98,11 @@ pdb_process_request (pdb_request_t *requ
    41.4          printk("(linux) detach 0x%x\n", request->process);
    41.5          resp.status = PDB_RESPONSE_OKAY;
    41.6          break;
    41.7 +    case PDB_OPCODE_RD_REG :
    41.8 +        resp.u.rd_reg.reg = request->u.rd_reg.reg;
    41.9 +        pdb_read_register(target, &resp.u.rd_reg);
   41.10 +        resp.status = PDB_RESPONSE_OKAY;
   41.11 +        break;
   41.12      case PDB_OPCODE_RD_REGS :
   41.13          pdb_read_registers(target, &resp.u.rd_regs);
   41.14          resp.status = PDB_RESPONSE_OKAY;
   41.15 @@ -108,14 +113,16 @@ pdb_process_request (pdb_request_t *requ
   41.16          break;
   41.17      case PDB_OPCODE_RD_MEM :
   41.18          pdb_access_memory(target, request->u.rd_mem.address,
   41.19 -                          &resp.u.rd_mem.data, request->u.rd_mem.length, 0);
   41.20 +                          &resp.u.rd_mem.data, request->u.rd_mem.length, 
   41.21 +                          PDB_MEM_READ);
   41.22          resp.u.rd_mem.address = request->u.rd_mem.address;
   41.23          resp.u.rd_mem.length  = request->u.rd_mem.length;
   41.24          resp.status = PDB_RESPONSE_OKAY;
   41.25          break;
   41.26      case PDB_OPCODE_WR_MEM :
   41.27          pdb_access_memory(target, request->u.wr_mem.address,
   41.28 -                         &request->u.wr_mem.data, request->u.wr_mem.length, 1);
   41.29 +                         &request->u.wr_mem.data, request->u.wr_mem.length, 
   41.30 +                          PDB_MEM_WRITE);
   41.31          resp.status = PDB_RESPONSE_OKAY;
   41.32          break;
   41.33      case PDB_OPCODE_CONTINUE :
   41.34 @@ -137,6 +144,14 @@ pdb_process_request (pdb_request_t *requ
   41.35                                       request->u.bkpt.length);
   41.36          resp.status = PDB_RESPONSE_OKAY;
   41.37          break;
   41.38 +    case PDB_OPCODE_SET_WATCHPT :
   41.39 +        pdb_insert_watchpoint(target, &request->u.watchpt);
   41.40 +        resp.status = PDB_RESPONSE_OKAY;
   41.41 +        break;
   41.42 +    case PDB_OPCODE_CLR_WATCHPT :
   41.43 +        pdb_remove_watchpoint(target, &request->u.watchpt);
   41.44 +        resp.status = PDB_RESPONSE_OKAY;
   41.45 +        break;
   41.46      default:
   41.47          printk("(pdb) unknown request operation %d\n", request->operation);
   41.48          resp.status = PDB_RESPONSE_ERROR;
   41.49 @@ -249,8 +264,6 @@ pdb_initialize (void)
   41.50  
   41.51      printk("----\npdb initialize   %s %s\n", __DATE__, __TIME__);
   41.52  
   41.53 -    pdb_initialize_bwcpoint();
   41.54 -
   41.55      /*
   41.56      if ( xen_start_info.flags & SIF_INITDOMAIN )
   41.57          return 1;
    42.1 --- a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h	Tue Aug 16 12:15:23 2005 +0800
    42.2 +++ b/tools/debugger/pdb/linux-2.6-module/pdb_debug.h	Tue Aug 16 10:09:07 2005 -0800
    42.3 @@ -6,6 +6,7 @@
    42.4  void pdb_initialize_bwcpoint (void);
    42.5  int pdb_suspend (struct task_struct *target);
    42.6  int pdb_resume (struct task_struct *target);
    42.7 +int pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op);
    42.8  int pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op);
    42.9  int pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op);
   42.10  int pdb_read_memory (struct task_struct *target, pdb_op_rd_mem_req_p req, 
   42.11 @@ -20,14 +21,14 @@ int pdb_insert_memory_breakpoint (struct
   42.12                                    memory_t address, u32 length);
   42.13  int pdb_remove_memory_breakpoint (struct task_struct *target,
   42.14                                    memory_t address, u32 length);
   42.15 +int pdb_insert_watchpoint (struct task_struct *target,
   42.16 +                           pdb_op_watchpt_p watchpt);
   42.17 +int pdb_remove_watchpoint (struct task_struct *target,
   42.18 +                           pdb_op_watchpt_p watchpt);
   42.19  
   42.20  int pdb_exceptions_notify (struct notifier_block *self, unsigned long val,
   42.21                             void *data);
   42.22  
   42.23 -int pdb_debug_fn (struct pt_regs *regs, long error_code,
   42.24 -                  unsigned int condition);
   42.25 -int pdb_int3_fn (struct pt_regs *regs, long error_code);
   42.26 -
   42.27  /* module.c */
   42.28  void pdb_send_response (pdb_response_t *response);
   42.29  
    43.1 --- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h	Tue Aug 16 12:15:23 2005 +0800
    43.2 +++ b/tools/debugger/pdb/linux-2.6-module/pdb_module.h	Tue Aug 16 10:09:07 2005 -0800
    43.3 @@ -14,20 +14,27 @@ typedef struct pdb_op_attach
    43.4  
    43.5  #define PDB_OPCODE_DETACH 3
    43.6  
    43.7 -#define PDB_OPCODE_RD_REGS 4
    43.8 +#define PDB_OPCODE_RD_REG 4
    43.9 +typedef struct pdb_op_rd_reg
   43.10 +{
   43.11 +    u32 reg;
   43.12 +    u32 value;
   43.13 +} pdb_op_rd_reg_t, *pdb_op_rd_reg_p;
   43.14 +
   43.15 +#define PDB_OPCODE_RD_REGS 5
   43.16  typedef struct pdb_op_rd_regs
   43.17  {
   43.18      u32 reg[GDB_REGISTER_FRAME_SIZE];
   43.19  } pdb_op_rd_regs_t, *pdb_op_rd_regs_p;
   43.20  
   43.21 -#define PDB_OPCODE_WR_REG 5
   43.22 +#define PDB_OPCODE_WR_REG 6
   43.23  typedef struct pdb_op_wr_reg
   43.24  {
   43.25      u32 reg;
   43.26      u32 value;
   43.27  } pdb_op_wr_reg_t, *pdb_op_wr_reg_p;
   43.28  
   43.29 -#define PDB_OPCODE_RD_MEM 6
   43.30 +#define PDB_OPCODE_RD_MEM 7
   43.31  typedef struct pdb_op_rd_mem_req
   43.32  {
   43.33      u32 address;
   43.34 @@ -41,7 +48,7 @@ typedef struct pdb_op_rd_mem_resp
   43.35      u8  data[1024];
   43.36  } pdb_op_rd_mem_resp_t, *pdb_op_rd_mem_resp_p;
   43.37  
   43.38 -#define PDB_OPCODE_WR_MEM 7
   43.39 +#define PDB_OPCODE_WR_MEM 8
   43.40  typedef struct pdb_op_wr_mem
   43.41  {
   43.42      u32 address;
   43.43 @@ -49,17 +56,34 @@ typedef struct pdb_op_wr_mem
   43.44      u8  data[1024];                                             /* arbitrary */
   43.45  } pdb_op_wr_mem_t, *pdb_op_wr_mem_p;
   43.46  
   43.47 -#define PDB_OPCODE_CONTINUE 8
   43.48 -#define PDB_OPCODE_STEP     9
   43.49 +#define PDB_OPCODE_CONTINUE 9
   43.50 +#define PDB_OPCODE_STEP     10
   43.51  
   43.52 -#define PDB_OPCODE_SET_BKPT 10
   43.53 -#define PDB_OPCODE_CLR_BKPT 11
   43.54 +#define PDB_OPCODE_SET_BKPT 11
   43.55 +#define PDB_OPCODE_CLR_BKPT 12
   43.56  typedef struct pdb_op_bkpt
   43.57  {
   43.58      u32 address;
   43.59      u32 length;
   43.60  } pdb_op_bkpt_t, *pdb_op_bkpt_p;
   43.61  
   43.62 +#define PDB_OPCODE_SET_WATCHPT 13
   43.63 +#define PDB_OPCODE_CLR_WATCHPT 14
   43.64 +#define PDB_OPCODE_WATCHPOINT  15
   43.65 +typedef struct pdb_op_watchpt
   43.66 +{
   43.67 +#define BWC_DEBUG 1
   43.68 +#define BWC_INT3  3
   43.69 +#define BWC_WATCH        100                         /* pdb: watchpoint page */
   43.70 +#define BWC_WATCH_STEP   101                  /* pdb: watchpoint single step */
   43.71 +#define BWC_WATCH_WRITE  102
   43.72 +#define BWC_WATCH_READ   103
   43.73 +#define BWC_WATCH_ACCESS 104
   43.74 +    u32 type;
   43.75 +    u32 address;
   43.76 +    u32 length;
   43.77 +} pdb_op_watchpt_t, *pdb_op_watchpt_p;
   43.78 +
   43.79  
   43.80  typedef struct 
   43.81  {
   43.82 @@ -68,10 +92,12 @@ typedef struct
   43.83      union
   43.84      {
   43.85          pdb_op_attach_t     attach;
   43.86 +        pdb_op_rd_reg_t     rd_reg;
   43.87          pdb_op_wr_reg_t     wr_reg;
   43.88          pdb_op_rd_mem_req_t rd_mem;
   43.89          pdb_op_wr_mem_t     wr_mem;
   43.90          pdb_op_bkpt_t       bkpt;
   43.91 +        pdb_op_watchpt_t    watchpt;
   43.92      } u;
   43.93  } pdb_request_t, *pdb_request_p;
   43.94  
   43.95 @@ -87,6 +113,7 @@ typedef struct {
   43.96      s16  status;          /* PDB_RESPONSE_???    */
   43.97      union
   43.98      {
   43.99 +        pdb_op_rd_reg_t      rd_reg;
  43.100          pdb_op_rd_regs_t     rd_regs;
  43.101          pdb_op_rd_mem_resp_t rd_mem;
  43.102      } u;
  43.103 @@ -95,6 +122,11 @@ typedef struct {
  43.104  
  43.105  DEFINE_RING_TYPES(pdb, pdb_request_t, pdb_response_t);
  43.106  
  43.107 +
  43.108 +/* from access_process_vm */
  43.109 +#define PDB_MEM_READ  0
  43.110 +#define PDB_MEM_WRITE 1
  43.111 +
  43.112  #endif
  43.113  
  43.114  
    44.1 --- a/tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch	Tue Aug 16 12:15:23 2005 +0800
    44.2 +++ b/tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch	Tue Aug 16 10:09:07 2005 -0800
    44.3 @@ -1,7 +1,15 @@
    44.4  diff -u linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c linux-2.6.12-pdb/arch/xen/i386/kernel/i386_ksyms.c
    44.5  --- linux-2.6.12/arch/xen/i386/kernel/i386_ksyms.c	2005-07-31 22:36:50.000000000 +0100
    44.6  +++ linux-2.6.12-pdb/arch/xen/i386/kernel/i386_ksyms.c	2005-08-01 10:57:31.000000000 +0100
    44.7 -@@ -172,6 +172,7 @@
    44.8 +@@ -151,6 +151,7 @@
    44.9 + /* TLB flushing */
   44.10 + EXPORT_SYMBOL(flush_tlb_page);
   44.11 + #endif
   44.12 ++EXPORT_SYMBOL(flush_tlb_mm);
   44.13 + 
   44.14 + #ifdef CONFIG_X86_IO_APIC
   44.15 + EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
   44.16 +@@ -172,6 +173,7 @@
   44.17   EXPORT_SYMBOL_GPL(unset_nmi_callback);
   44.18   
   44.19   EXPORT_SYMBOL(register_die_notifier);
    45.1 --- a/tools/debugger/pdb/pdb_caml_domain.c	Tue Aug 16 12:15:23 2005 +0800
    45.2 +++ b/tools/debugger/pdb/pdb_caml_domain.c	Tue Aug 16 10:09:07 2005 -0800
    45.3 @@ -43,6 +43,54 @@ typedef struct
    45.4  /****************************************************************************/
    45.5  
    45.6  /*
    45.7 + * dom_read_register : context_t -> int -> int32
    45.8 + */
    45.9 +value
   45.10 +dom_read_register (value context, value reg)
   45.11 +{
   45.12 +    CAMLparam2(context, reg);
   45.13 +    CAMLlocal1(result);
   45.14 +
   45.15 +    int my_reg = Int_val(reg);
   45.16 +    cpu_user_regs_t *regs;
   45.17 +    context_t ctx;
   45.18 +
   45.19 +    decode_context(&ctx, context);
   45.20 +
   45.21 +    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
   45.22 +    {
   45.23 +        printf("(pdb) read registers error!\n");  fflush(stdout);
   45.24 +        failwith("read registers error");
   45.25 +    }
   45.26 +
   45.27 +    dump_regs(regs);
   45.28 +
   45.29 +    result = caml_alloc_tuple(16);
   45.30 +
   45.31 +    switch (my_reg)
   45.32 +    {
   45.33 +    case GDB_EAX: result = caml_copy_int32(regs->eax); break;
   45.34 +    case GDB_ECX: result = caml_copy_int32(regs->ecx); break;
   45.35 +    case GDB_EDX: result = caml_copy_int32(regs->edx); break;
   45.36 +    case GDB_EBX: result = caml_copy_int32(regs->ebx); break;
   45.37 +    case GDB_ESP: result = caml_copy_int32(regs->esp); break;
   45.38 +    case GDB_EBP: result = caml_copy_int32(regs->ebp); break;
   45.39 +    case GDB_ESI: result = caml_copy_int32(regs->esi); break;
   45.40 +    case GDB_EDI: result = caml_copy_int32(regs->edi); break;
   45.41 +    case GDB_EIP: result = caml_copy_int32(regs->eip); break;
   45.42 +    case GDB_EFL: result = caml_copy_int32(regs->eflags); break;
   45.43 +    case GDB_CS:  result = caml_copy_int32(regs->cs);  break;
   45.44 +    case GDB_SS: result = caml_copy_int32(regs->ss); break;
   45.45 +    case GDB_DS: result = caml_copy_int32(regs->ds); break;
   45.46 +    case GDB_ES: result = caml_copy_int32(regs->es); break;
   45.47 +    case GDB_FS: result = caml_copy_int32(regs->fs); break;
   45.48 +    case GDB_GS: result = caml_copy_int32(regs->gs); break;
   45.49 +    }
   45.50 +
   45.51 +    CAMLreturn(result);
   45.52 +}
   45.53 +
   45.54 +/*
   45.55   * dom_read_registers : context_t -> int32
   45.56   */
   45.57  value
    46.1 --- a/tools/debugger/pdb/pdb_caml_process.c	Tue Aug 16 12:15:23 2005 +0800
    46.2 +++ b/tools/debugger/pdb/pdb_caml_process.c	Tue Aug 16 10:09:07 2005 -0800
    46.3 @@ -113,6 +113,12 @@ process_handle_response (value ring)
    46.4          case PDB_OPCODE_DETACH :
    46.5              break;
    46.6              
    46.7 +        case PDB_OPCODE_RD_REG :
    46.8 +        {
    46.9 +            sprintf(&msg[0], "%08x", _flip(resp->u.rd_reg.value));
   46.10 +            break;
   46.11 +        }
   46.12 +
   46.13          case PDB_OPCODE_RD_REGS :
   46.14          {
   46.15              int loop;
   46.16 @@ -161,16 +167,22 @@ process_handle_response (value ring)
   46.17          }
   46.18  
   46.19          case PDB_OPCODE_SET_BKPT :
   46.20 -        {
   46.21 -            break;
   46.22 -        }
   46.23          case PDB_OPCODE_CLR_BKPT :
   46.24 +        case PDB_OPCODE_SET_WATCHPT :
   46.25 +        case PDB_OPCODE_CLR_WATCHPT :
   46.26          {
   46.27              break;
   46.28          }
   46.29  
   46.30 +        case PDB_OPCODE_WATCHPOINT :
   46.31 +        {
   46.32 +            sprintf(msg, "S05");
   46.33 +            break;
   46.34 +        }
   46.35 +
   46.36          default :
   46.37 -            printf("(linux) UNKNOWN MESSAGE TYPE IN RESPONSE\n");
   46.38 +            printf("(linux) UNKNOWN MESSAGE TYPE IN RESPONSE %d\n",
   46.39 +                   resp->operation);
   46.40              break;
   46.41          }
   46.42  
   46.43 @@ -261,6 +273,32 @@ proc_pause_target (value context)
   46.44  
   46.45  
   46.46  /*
   46.47 + * proc_read_register : context_t -> int -> unit
   46.48 + */
   46.49 +value
   46.50 +proc_read_register (value context, value reg)
   46.51 +{
   46.52 +    CAMLparam1(context);
   46.53 +
   46.54 +    pdb_request_t req;
   46.55 +    context_t ctx;
   46.56 +    int my_reg = Int_val(reg);
   46.57 +
   46.58 +    decode_context(&ctx, context);
   46.59 +
   46.60 +    req.operation = PDB_OPCODE_RD_REG;
   46.61 +    req.process = ctx.process;
   46.62 +    req.u.rd_reg.reg = my_reg;
   46.63 +    req.u.rd_reg.value = 0;
   46.64 +
   46.65 +    send_request (ctx.ring, ctx.evtchn, &req);
   46.66 +
   46.67 +    CAMLreturn(Val_unit);
   46.68 +}
   46.69 +
   46.70 +
   46.71 +
   46.72 +/*
   46.73   * proc_read_registers : context_t -> unit
   46.74   */
   46.75  value
   46.76 @@ -443,7 +481,7 @@ proc_step_target (value context)
   46.77  
   46.78  
   46.79  /*
   46.80 - * proc_insert_memory_breakpoint : context_t -> int32 -> int list -> unit
   46.81 + * proc_insert_memory_breakpoint : context_t -> int32 -> int -> unit
   46.82   */
   46.83  value
   46.84  proc_insert_memory_breakpoint (value context, value address, value length)
   46.85 @@ -466,7 +504,7 @@ proc_insert_memory_breakpoint (value con
   46.86  }
   46.87  
   46.88  /*
   46.89 - * proc_remove_memory_breakpoint : context_t -> int32 -> int list -> unit
   46.90 + * proc_remove_memory_breakpoint : context_t -> int32 -> int -> unit
   46.91   */
   46.92  value
   46.93  proc_remove_memory_breakpoint (value context, value address, value length)
   46.94 @@ -488,6 +526,54 @@ proc_remove_memory_breakpoint (value con
   46.95      CAMLreturn(Val_unit);
   46.96  }
   46.97  
   46.98 +/*
   46.99 + * proc_insert_watchpoint : context_t -> bwcpoint_t -> int32 -> int -> unit
  46.100 + */
  46.101 +value
  46.102 +proc_insert_watchpoint (value context, value kind, value address, value length)
  46.103 +{
  46.104 +    CAMLparam3(context, address, length);
  46.105 +
  46.106 +    context_t ctx;
  46.107 +    pdb_request_t req;
  46.108 +
  46.109 +    decode_context(&ctx, context);
  46.110 +
  46.111 +    req.operation = PDB_OPCODE_SET_WATCHPT;
  46.112 +    req.process = ctx.process;
  46.113 +    req.u.watchpt.type    =  Int_val(kind);
  46.114 +    req.u.watchpt.address = (memory_t) Int32_val(address);
  46.115 +    req.u.watchpt.length  =  Int_val(length);
  46.116 +
  46.117 +    send_request(ctx.ring, ctx.evtchn, &req);
  46.118 +
  46.119 +    CAMLreturn(Val_unit);
  46.120 +}
  46.121 +
  46.122 +/*
  46.123 + * proc_remove_watchpoint : context_t -> bwcpoint_t -> int32 -> int -> unit
  46.124 + */
  46.125 +value
  46.126 +proc_remove_watchpoint (value context, value kind, value address, value length)
  46.127 +{
  46.128 +    CAMLparam3(context, address, length);
  46.129 +
  46.130 +    context_t ctx;
  46.131 +    pdb_request_t req;
  46.132 +
  46.133 +    decode_context(&ctx, context);
  46.134 +
  46.135 +    req.operation = PDB_OPCODE_CLR_WATCHPT;
  46.136 +    req.process = ctx.process;
  46.137 +    req.u.watchpt.type    =  Int_val(kind);
  46.138 +    req.u.watchpt.address = (memory_t) Int32_val(address);
  46.139 +    req.u.watchpt.length  =  Int_val(length);
  46.140 +
  46.141 +    send_request(ctx.ring, ctx.evtchn, &req);
  46.142 +
  46.143 +    CAMLreturn(Val_unit);
  46.144 +}
  46.145 +
  46.146  
  46.147  /*
  46.148   * Local variables:
    47.1 --- a/tools/debugger/pdb/readme	Tue Aug 16 12:15:23 2005 +0800
    47.2 +++ b/tools/debugger/pdb/readme	Tue Aug 16 10:09:07 2005 -0800
    47.3 @@ -1,9 +1,9 @@
    47.4  
    47.5 -PDB 0.3 
    47.6 +PDB 0.3.3
    47.7  http://www.cl.cam.ac.uk/netos/pdb
    47.8  
    47.9  Alex Ho  
   47.10 -June 2005
   47.11 +August 2005
   47.12  
   47.13  
   47.14  This is the latest incarnation of the pervasive debugger.
   47.15 @@ -79,6 +79,11 @@ Usage
   47.16  Process
   47.17  
   47.18    PDB can also debug a process running in a Linux 2.6 domain. 
   47.19 +  You will need to patch the Linux 2.6 domain U tree to export some
   47.20 +  additional symbols for the pdb module
   47.21 +
   47.22 +  % make -C linux-2.6-patches
   47.23 +
   47.24    After running PDB in domain 0, insert the pdb module in dom u:
   47.25    
   47.26    % insmod linux-2.6-module/pdb.ko
   47.27 @@ -87,7 +92,14 @@ Process
   47.28  
   47.29    (gdb) maint packet x context = process <domid> <pid>
   47.30  
   47.31 +  Read, write, and access watchpoint should also work for processes, 
   47.32 +  use the "rwatch", "watch" and "awatch" gdb commands respectively.
   47.33 +
   47.34 +  If you are having trouble with GDB 5.3 (i386-redhat-linux-gnu),
   47.35 +  try GDB 6.3 (configured with --target=i386-linux-gnu).
   47.36 +
   47.37 +  
   47.38  To Do
   47.39  
   47.40 -- watchpoints
   47.41 +- watchpoints for domains
   47.42  - support for SMP
    48.1 --- a/tools/examples/network-bridge	Tue Aug 16 12:15:23 2005 +0800
    48.2 +++ b/tools/examples/network-bridge	Tue Aug 16 10:09:07 2005 -0800
    48.3 @@ -188,12 +188,13 @@ op_start () {
    48.4  		fi
    48.5  	fi
    48.6  	ip link set ${netdev} name p${netdev}
    48.7 -	ip link set veth0 name eth0
    48.8 +	ip link set veth0 name ${netdev}
    48.9  	ifconfig p${netdev} -arp down
   48.10  	ifconfig p${netdev} hw ether fe:ff:ff:ff:ff:ff
   48.11  	ifconfig ${netdev} hw ether ${mac}
   48.12  	add_to_bridge ${bridge} vif0.0
   48.13  	add_to_bridge ${bridge} p${netdev}
   48.14 +	ip link set ${bridge} up
   48.15  	ip link set vif0.0 up
   48.16  	ip link set p${netdev} up
   48.17  	if ! ifup ${netdev} ; then
    49.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Aug 16 12:15:23 2005 +0800
    49.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Aug 16 10:09:07 2005 -0800
    49.3 @@ -583,7 +583,7 @@ class XendDomainInfo:
    49.4          self.create_channel()
    49.5          self.image.createImage()
    49.6          self.exportToDB()
    49.7 -        if self.store_channel:
    49.8 +        if self.store_channel and self.store_mfn >= 0:
    49.9              self.db.introduceDomain(self.id,
   49.10                                      self.store_mfn,
   49.11                                      self.store_channel)
   49.12 @@ -915,8 +915,7 @@ class XendDomainInfo:
   49.13          """
   49.14          self.configure_fields()
   49.15          self.create_devices()
   49.16 -	if self.image.ostype != 'vmx':
   49.17 -            self.create_blkif()
   49.18 +        self.create_blkif()
   49.19  
   49.20      def create_blkif(self):
   49.21          """Create the block device interface (blkif) for the vm.