bitkeeper revision 1.1159.258.42 (4230e421NhFkCppVay5rDH0tzHn2bQ)
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 11 Mar 2005 00:19:45 +0000 (00:19 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 11 Mar 2005 00:19:45 +0000 (00:19 +0000)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into firebug.cl.cam.ac.uk:/local/scratch/cl349/xen-2.0-testing.bk-2.6.11

1  2 
.rootkeys
linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c
linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c
linux-2.6.11-xen-sparse/drivers/xen/console/console.c

diff --cc .rootkeys
index f5baebe00f6e5615f32eb8e7663b0fcbbbb9e76d,8e29f01aa4a56eb816624b42d7b8f260c70f382f..46d3689876cbde4ff2a5afd3bdc004a24465354e
+++ b/.rootkeys
  3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.29-xen-sparse/mm/swapfile.c
  41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.29-xen-sparse/mm/vmalloc.c
  41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.29-xen-sparse/net/core/skbuff.c
- 40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.10-xen-sparse/arch/xen/Kconfig
- 40f56237utH41NPukqHksuNf29IC9A linux-2.6.10-xen-sparse/arch/xen/Kconfig.drivers
- 40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.10-xen-sparse/arch/xen/Makefile
- 40f56237JTc60m1FRlUxkUaGSQKrNw linux-2.6.10-xen-sparse/arch/xen/boot/Makefile
- 40f56237hRxbacU_3PdoAl6DjZ3Jnw linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig
- 40f56237wubfjJKlfIzZlI3ZM2VgGA linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig
- 40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.10-xen-sparse/arch/xen/i386/Kconfig
- 40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.10-xen-sparse/arch/xen/i386/Makefile
- 40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile
- 40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/Makefile
- 40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c
- 41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile
- 41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c
- 40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S
- 40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.10-xen-sparse/arch/xen/i386/kernel/head.S
- 40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c
- 40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ioport.c
- 40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c
- 41d54a76YMCA67S8J-TBT3J62Wx6yA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/microcode.c
- 4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c
- 40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c
- 40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c
- 40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c
- 40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c
- 40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/Makefile
- 40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c
- 40f562389xNa78YBZciUibQjyRU_Lg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c
- 40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.S
- 40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.lds
- 40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.10-xen-sparse/arch/xen/i386/mm/Makefile
- 40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c
- 4118cc35CbY8rfGVspF5O-7EkXBEAA linux-2.6.10-xen-sparse/arch/xen/i386/mm/highmem.c
- 40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c
- 40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c
- 41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c
- 413b5ab8LIowAnQrEmaOJSdmqm96jQ linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c
- 40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c
- 4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.10-xen-sparse/arch/xen/i386/pci/Makefile
- 4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.10-xen-sparse/arch/xen/i386/pci/direct.c
- 4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.10-xen-sparse/arch/xen/i386/pci/irq.c
- 40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile
- 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.10-xen-sparse/arch/xen/kernel/ctrl_if.c
- 41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c
- 40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c
- 4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.10-xen-sparse/arch/xen/kernel/fixup.c
- 412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c
- 40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c
- 414c113396tK1HTVeUalm3u-1DF16g linux-2.6.10-xen-sparse/arch/xen/kernel/skbuff.c
- 3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.10-xen-sparse/arch/xen/kernel/xen_proc.c
- 41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.10-xen-sparse/drivers/Makefile
- 4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.10-xen-sparse/drivers/char/mem.c
- 4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.10-xen-sparse/drivers/char/tty_io.c
- 40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.10-xen-sparse/drivers/xen/Makefile
- 41768fbcncpBQf8s2l2-CwoSNIZ9uA linux-2.6.10-xen-sparse/drivers/xen/balloon/Makefile
- 3e6377f8i5e9eGz7Pw6fQuhuTQ7DQg linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c
- 410d0893otFGghmv4dUXDUBBdY5aIA linux-2.6.10-xen-sparse/drivers/xen/blkback/Makefile
- 4087cf0d1XgMkooTZAiJS6NrcpLQNQ linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c
- 4087cf0dZadZ8r6CEt4fNN350Yle3A linux-2.6.10-xen-sparse/drivers/xen/blkback/common.h
- 4087cf0dxlh29iw0w-9rxOCEGCjPcw linux-2.6.10-xen-sparse/drivers/xen/blkback/control.c
- 4087cf0dbuoH20fMjNZjcgrRK-1msQ linux-2.6.10-xen-sparse/drivers/xen/blkback/interface.c
- 4087cf0dk97tacDzxfByWV7JifUYqA linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c
- 40f56239Sfle6wGv5FS0wjS_HI150A linux-2.6.10-xen-sparse/drivers/xen/blkfront/Kconfig
- 40f562395atl9x4suKGhPkjqLOXESg linux-2.6.10-xen-sparse/drivers/xen/blkfront/Makefile
- 40f56239-JNIaTzlviVJohVdoYOUpw linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c
- 40f56239y9naBTXe40Pi2J_z3p-d1g linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h
- 40f56239BVfPsXBiWQitXgDRtOsiqg linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c
- 40f56239fsLjvtD8YBRAWphps4FDjg linux-2.6.10-xen-sparse/drivers/xen/console/Makefile
- 3e5a4e651TH-SXHoufurnWjgl5bfOA linux-2.6.10-xen-sparse/drivers/xen/console/console.c
- 40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6.10-xen-sparse/drivers/xen/evtchn/Makefile
- 40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.10-xen-sparse/drivers/xen/evtchn/evtchn.c
- 410a9817HEVJvred5Oy_uKH3HFJC5Q linux-2.6.10-xen-sparse/drivers/xen/netback/Makefile
- 4097ba831lpGeLlPg-bfV8XarVVuoQ linux-2.6.10-xen-sparse/drivers/xen/netback/common.h
- 4097ba83wvv8yi5P5xugCUBAdb6O-A linux-2.6.10-xen-sparse/drivers/xen/netback/control.c
- 4097ba83byY5bTSugJGZ1exTxIcMKw linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c
- 4087cf0dGmSbFhFZyIZBJzvqxY-qBw linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c
- 40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.10-xen-sparse/drivers/xen/netfront/Kconfig
- 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.10-xen-sparse/drivers/xen/netfront/Makefile
- 405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c
- 4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.10-xen-sparse/drivers/xen/privcmd/Makefile
- 3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c
- 412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.10-xen-sparse/include/asm-generic/pgtable.h
- 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h
- 4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
- 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h
- 41979925z1MsKU1SfuuheM1IFDQ_bA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/floppy.h
- 4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/highmem.h
- 40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h
- 40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
- 40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
- 40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h
- 4120f807GCO0uqsLqdZj9csxR1Wthw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mmu_context.h
- 40f5623aFTyFTR-vdiA-KaGxk5JOKQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/msr.h
- 40f5623adgjZq9nAgCt0IXdWl7udSA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h
- 40f5623a54NuG-7qHihGYmw4wWQnMA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/param.h
- 41137cc1kkvg0cg7uxddcEfjL7L67w linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pci.h
- 40f5623atCokYc2uCysSJ8jFO8TEsw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
- 412e01beTwiaC8sYY4XJP8PxLST5CA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h
- 40f5623aEToIXouJgO-ao5d5pcEt1w linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
- 40f5623aCCXRPlGpNthVXstGz9ZV3A linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h
- 40f5623aPCkQQfPtJSooGdhcatrvnQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/processor.h
- 412ea0afQL2CAI-f522TbLjLPMibPQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/ptrace.h
- 40f5623bzLvxr7WoJIxVf2OH4rCBJg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/segment.h
- 40f5623bG_LzgG6-qwk292nTc5Wabw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/setup.h
- 40f5623bgzm_9vwxpzJswlAxg298Gg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h
- 40f5623bVdKP7Dt7qm8twu3NcnGNbA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h
- 40f5623bc8LKPRO09wY5dGDnY_YCpw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/tlbflush.h
- 41062ab7uFxnCq-KtPeAm-aV8CicgA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/vga.h
- 40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/xor.h
- 41af4017PDMuSmMWtSRU5UC9Vylw5g linux-2.6.10-xen-sparse/include/asm-xen/balloon.h
- 40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.10-xen-sparse/include/asm-xen/ctrl_if.h
- 40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.10-xen-sparse/include/asm-xen/evtchn.h
- 419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.10-xen-sparse/include/asm-xen/foreign_page.h
- 412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h
- 40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h
- 3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.10-xen-sparse/include/asm-xen/linux-public/privcmd.h
- 3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.10-xen-sparse/include/asm-xen/linux-public/suspend.h
- 40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.10-xen-sparse/include/asm-xen/multicall.h
- 4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.10-xen-sparse/include/asm-xen/queues.h
- 3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.10-xen-sparse/include/asm-xen/xen_proc.h
- 419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.10-xen-sparse/include/linux/gfp.h
 +42305f545Vc5SLCUewZ2-n-P9JJhEQ linux-2.6.10-xen-sparse/include/linux/highmem.h
- 419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.10-xen-sparse/include/linux/irq.h
- 4124f66f4NaKNa0xPiGGykn9QaZk3w linux-2.6.10-xen-sparse/include/linux/skbuff.h
- 419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.10-xen-sparse/kernel/irq/manage.c
- 40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.10-xen-sparse/mkbuildtree
 +42305f54Q6xJ1bXcQJlCQq1m-e2C8g linux-2.6.10-xen-sparse/mm/highmem.c
- 412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.10-xen-sparse/mm/memory.c
- 410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.10-xen-sparse/mm/page_alloc.c
- 41505c572m-s9ATiO1LiD1GPznTTIg linux-2.6.10-xen-sparse/net/core/skbuff.c
+ 40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.11-xen-sparse/arch/xen/Kconfig
+ 40f56237utH41NPukqHksuNf29IC9A linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers
+ 40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.11-xen-sparse/arch/xen/Makefile
+ 40f56237JTc60m1FRlUxkUaGSQKrNw linux-2.6.11-xen-sparse/arch/xen/boot/Makefile
+ 40f56237hRxbacU_3PdoAl6DjZ3Jnw linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig
+ 40f56237wubfjJKlfIzZlI3ZM2VgGA linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig
+ 40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig
+ 40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.11-xen-sparse/arch/xen/i386/Makefile
+ 40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile
+ 40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/Makefile
+ 40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c
+ 41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile
+ 41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c
+ 40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S
+ 40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.11-xen-sparse/arch/xen/i386/kernel/head.S
+ 40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c
+ 40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ioport.c
+ 40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c
+ 41d54a76YMCA67S8J-TBT3J62Wx6yA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/microcode.c
+ 4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c
+ 40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c
+ 40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c
+ 40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/signal.c
+ 40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c
+ 40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/Makefile
+ 40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c
+ 40f562389xNa78YBZciUibQjyRU_Lg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c
+ 40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.S
+ 40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.lds
+ 40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.11-xen-sparse/arch/xen/i386/mm/Makefile
+ 40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.11-xen-sparse/arch/xen/i386/mm/fault.c
+ 4118cc35CbY8rfGVspF5O-7EkXBEAA linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c
+ 40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c
+ 40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c
+ 41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c
+ 413b5ab8LIowAnQrEmaOJSdmqm96jQ linux-2.6.11-xen-sparse/arch/xen/i386/mm/pageattr.c
+ 40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c
+ 4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile
+ 4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c
+ 4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c
+ 40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.11-xen-sparse/arch/xen/kernel/Makefile
+ 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c
+ 41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.11-xen-sparse/arch/xen/kernel/devmem.c
+ 40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
+ 4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c
+ 412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c
+ 40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c
+ 414c113396tK1HTVeUalm3u-1DF16g linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c
+ 3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.11-xen-sparse/arch/xen/kernel/xen_proc.c
+ 41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.11-xen-sparse/drivers/Makefile
+ 4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.11-xen-sparse/drivers/char/mem.c
+ 4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.11-xen-sparse/drivers/char/tty_io.c
+ 40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.11-xen-sparse/drivers/xen/Makefile
+ 41768fbcncpBQf8s2l2-CwoSNIZ9uA linux-2.6.11-xen-sparse/drivers/xen/balloon/Makefile
+ 3e6377f8i5e9eGz7Pw6fQuhuTQ7DQg linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c
+ 410d0893otFGghmv4dUXDUBBdY5aIA linux-2.6.11-xen-sparse/drivers/xen/blkback/Makefile
+ 4087cf0d1XgMkooTZAiJS6NrcpLQNQ linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c
+ 4087cf0dZadZ8r6CEt4fNN350Yle3A linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h
+ 4087cf0dxlh29iw0w-9rxOCEGCjPcw linux-2.6.11-xen-sparse/drivers/xen/blkback/control.c
+ 4087cf0dbuoH20fMjNZjcgrRK-1msQ linux-2.6.11-xen-sparse/drivers/xen/blkback/interface.c
+ 4087cf0dk97tacDzxfByWV7JifUYqA linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c
+ 40f56239Sfle6wGv5FS0wjS_HI150A linux-2.6.11-xen-sparse/drivers/xen/blkfront/Kconfig
+ 40f562395atl9x4suKGhPkjqLOXESg linux-2.6.11-xen-sparse/drivers/xen/blkfront/Makefile
+ 40f56239-JNIaTzlviVJohVdoYOUpw linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c
+ 40f56239y9naBTXe40Pi2J_z3p-d1g linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h
+ 40f56239BVfPsXBiWQitXgDRtOsiqg linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c
+ 40f56239fsLjvtD8YBRAWphps4FDjg linux-2.6.11-xen-sparse/drivers/xen/console/Makefile
+ 3e5a4e651TH-SXHoufurnWjgl5bfOA linux-2.6.11-xen-sparse/drivers/xen/console/console.c
+ 40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6.11-xen-sparse/drivers/xen/evtchn/Makefile
+ 40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.11-xen-sparse/drivers/xen/evtchn/evtchn.c
+ 410a9817HEVJvred5Oy_uKH3HFJC5Q linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile
+ 4097ba831lpGeLlPg-bfV8XarVVuoQ linux-2.6.11-xen-sparse/drivers/xen/netback/common.h
+ 4097ba83wvv8yi5P5xugCUBAdb6O-A linux-2.6.11-xen-sparse/drivers/xen/netback/control.c
+ 4097ba83byY5bTSugJGZ1exTxIcMKw linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c
+ 4087cf0dGmSbFhFZyIZBJzvqxY-qBw linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c
+ 40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.11-xen-sparse/drivers/xen/netfront/Kconfig
+ 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.11-xen-sparse/drivers/xen/netfront/Makefile
+ 405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c
+ 4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.11-xen-sparse/drivers/xen/privcmd/Makefile
+ 3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c
+ 412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.11-xen-sparse/include/asm-generic/pgtable.h
+ 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h
+ 4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
+ 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h
+ 41979925z1MsKU1SfuuheM1IFDQ_bA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h
+ 4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h
+ 40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h
+ 40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
+ 40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
+ 40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h
+ 4120f807GCO0uqsLqdZj9csxR1Wthw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h
+ 40f5623aFTyFTR-vdiA-KaGxk5JOKQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/msr.h
+ 40f5623adgjZq9nAgCt0IXdWl7udSA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h
+ 40f5623a54NuG-7qHihGYmw4wWQnMA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/param.h
+ 41137cc1kkvg0cg7uxddcEfjL7L67w linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pci.h
+ 40f5623atCokYc2uCysSJ8jFO8TEsw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
+ 412e01beTwiaC8sYY4XJP8PxLST5CA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h
+ 40f5623aEToIXouJgO-ao5d5pcEt1w linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
+ 40f5623aCCXRPlGpNthVXstGz9ZV3A linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h
+ 40f5623aPCkQQfPtJSooGdhcatrvnQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h
+ 412ea0afQL2CAI-f522TbLjLPMibPQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/ptrace.h
+ 40f5623bzLvxr7WoJIxVf2OH4rCBJg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/segment.h
+ 40f5623bG_LzgG6-qwk292nTc5Wabw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/setup.h
+ 40f5623bgzm_9vwxpzJswlAxg298Gg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h
+ 40f5623bVdKP7Dt7qm8twu3NcnGNbA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h
+ 40f5623bc8LKPRO09wY5dGDnY_YCpw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/tlbflush.h
+ 41062ab7uFxnCq-KtPeAm-aV8CicgA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/vga.h
+ 40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/xor.h
+ 41af4017PDMuSmMWtSRU5UC9Vylw5g linux-2.6.11-xen-sparse/include/asm-xen/balloon.h
+ 40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.11-xen-sparse/include/asm-xen/ctrl_if.h
+ 40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.11-xen-sparse/include/asm-xen/evtchn.h
+ 419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.11-xen-sparse/include/asm-xen/foreign_page.h
+ 412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h
+ 40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
+ 3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h
+ 3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h
+ 40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.11-xen-sparse/include/asm-xen/multicall.h
+ 4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.11-xen-sparse/include/asm-xen/queues.h
+ 3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h
+ 419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.11-xen-sparse/include/linux/gfp.h
+ 419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.11-xen-sparse/include/linux/irq.h
+ 419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.11-xen-sparse/kernel/irq/manage.c
+ 40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.11-xen-sparse/mkbuildtree
+ 412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.11-xen-sparse/mm/memory.c
+ 410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.11-xen-sparse/mm/page_alloc.c
  413cb1e4zst25MDYjg63Y-NGC5_pLg netbsd-2.0-xen-sparse/Makefile
  413cb1e5c_Mkxf_X0zimEhTKI_l4DA netbsd-2.0-xen-sparse/mkbuildtree
  413cb1e5kY_Zil7-b0kI6hvCIxBEYg netbsd-2.0-xen-sparse/nbconfig-xen
index 0000000000000000000000000000000000000000,ee725d3d9de44e0613fe2bdea34ed753407cd32d..6909fabaa7978820f85b14e6f510c4e74a192dc4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,445 +1,454 @@@
 -            phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
+ /******************************************************************************
+  * balloon.c
+  *
+  * Xen balloon driver - enables returning/claiming memory to/from Xen.
+  *
+  * Copyright (c) 2003, B Dragovic
+  * Copyright (c) 2003-2004, M Williamson, K Fraser
+  * 
+  * This file may be distributed separately from the Linux kernel, or
+  * incorporated into other software packages, subject to the following license:
+  * 
+  * Permission is hereby granted, free of charge, to any person obtaining a copy
+  * of this source file (the "Software"), to deal in the Software without
+  * restriction, including without limitation the rights to use, copy, modify,
+  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+  * and to permit persons to whom the Software is furnished to do so, subject to
+  * the following conditions:
+  * 
+  * The above copyright notice and this permission notice shall be included in
+  * all copies or substantial portions of the Software.
+  * 
+  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+  * IN THE SOFTWARE.
+  */
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pagemap.h>
+ #include <linux/bootmem.h>
+ #include <linux/highmem.h>
+ #include <linux/vmalloc.h>
+ #include <asm-xen/xen_proc.h>
+ #include <asm-xen/hypervisor.h>
+ #include <asm-xen/ctrl_if.h>
+ #include <asm-xen/balloon.h>
+ #include <asm/pgalloc.h>
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
+ #include <asm/tlb.h>
+ #include <linux/list.h>
+ static struct proc_dir_entry *balloon_pde;
+ static DECLARE_MUTEX(balloon_mutex);
+ spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
+ /* We aim for 'current allocation' == 'target allocation'. */
+ static unsigned long current_pages;
+ static unsigned long target_pages;
+ /* We may hit the hard limit in Xen. If we do then we remember it. */
+ static unsigned long hard_limit;
+ /*
+  * Drivers may alter the memory reservation independently, but they must
+  * inform the balloon driver so that we can avoid hitting the hard limit.
+  */
+ static unsigned long driver_pages;
+ /* List of ballooned pages, threaded through the mem_map array. */
+ static LIST_HEAD(ballooned_pages);
+ static unsigned long balloon_low, balloon_high;
+ /* Main work function, always executed in process context. */
+ static void balloon_process(void *unused);
+ static DECLARE_WORK(balloon_worker, balloon_process, NULL);
+ static struct timer_list balloon_timer;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ /* Use the private and mapping fields of struct page as a list. */
+ #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private )
+ #define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l),   \
+                                     struct page, private ) )
+ #define UNLIST_PAGE(p)  do { list_del(PAGE_TO_LIST(p));       \
+                              p->mapping = NULL;               \
+                              p->private = 0; } while(0)
+ #else
+ /* There's a dedicated list field in struct page we can use.    */
+ #define PAGE_TO_LIST(p) ( &p->list )
+ #define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) )
+ #define UNLIST_PAGE(p)  ( list_del(&p->list) )
+ #define pte_offset_kernel pte_offset
+ #define subsys_initcall(_fn) __initcall(_fn)
++#define pfn_to_page(_pfn) (mem_map + (_pfn))
+ #endif
+ #define IPRINTK(fmt, args...) \
+     printk(KERN_INFO "xen_mem: " fmt, ##args)
+ #define WPRINTK(fmt, args...) \
+     printk(KERN_WARNING "xen_mem: " fmt, ##args)
+ /* balloon_append: add the given page to the balloon. */
+ static void balloon_append(struct page *page)
+ {
+     /* Low memory is re-populated first, so highmem pages go at list tail. */
+     if ( PageHighMem(page) )
+     {
+         list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
+         balloon_high++;
+     }
+     else
+     {
+         list_add(PAGE_TO_LIST(page), &ballooned_pages);
+         balloon_low++;
+     }
+ }
+ /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
+ static struct page *balloon_retrieve(void)
+ {
+     struct page *page;
+     if ( list_empty(&ballooned_pages) )
+         return NULL;
+     page = LIST_TO_PAGE(ballooned_pages.next);
+     UNLIST_PAGE(page);
+     if ( PageHighMem(page) )
+         balloon_high--;
+     else
+         balloon_low--;
+     return page;
+ }
+ static inline pte_t *get_ptep(unsigned long addr)
+ {
+     pgd_t *pgd;
+     pud_t *pud;
+     pmd_t *pmd;
+     pgd = pgd_offset_k(addr);
+     if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG();
+     pud = pud_offset(pgd, addr);
+     if ( pud_none(*pud) || pud_bad(*pud) ) BUG();
+     pmd = pmd_offset(pud, addr);
+     if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG();
+     return pte_offset_kernel(pmd, addr);
+ }
+ static void balloon_alarm(unsigned long unused)
+ {
+     schedule_work(&balloon_worker);
+ }
+ static unsigned long current_target(void)
+ {
+     unsigned long target = min(target_pages, hard_limit);
+     if ( target > (current_pages + balloon_low + balloon_high) )
+         target = current_pages + balloon_low + balloon_high;
+     return target;
+ }
+ /*
+  * We avoid multiple worker processes conflicting via the balloon mutex.
+  * We may of course race updates of the target counts (which are protected
+  * by the balloon lock), or with changes to the Xen hard limit, but we will
+  * recover from these in time.
+  */
+ static void balloon_process(void *unused)
+ {
+     unsigned long *mfn_list, pfn, i, flags;
+     struct page   *page;
+     long           credit, debt, rc;
+     void          *v;
+     down(&balloon_mutex);
+  retry:
+     mfn_list = NULL;
+     if ( (credit = current_target() - current_pages) > 0 )
+     {
+         mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list));
+         if ( mfn_list == NULL )
+             goto out;
+         balloon_lock(flags);
+         rc = HYPERVISOR_dom_mem_op(
+             MEMOP_increase_reservation, mfn_list, credit, 0);
+         balloon_unlock(flags);
+         if ( rc < credit )
+         {
+             /* We hit the Xen hard limit: reprobe. */
+             if ( HYPERVISOR_dom_mem_op(
+                 MEMOP_decrease_reservation, mfn_list, rc, 0) != rc )
+                 BUG();
+             hard_limit = current_pages + rc - driver_pages;
+             vfree(mfn_list);
+             goto retry;
+         }
+         for ( i = 0; i < credit; i++ )
+         {
+             if ( (page = balloon_retrieve()) == NULL )
+                 BUG();
+             pfn = page - mem_map;
+             if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
+                 BUG();
+             /* Update P->M and M->P tables. */
+             phys_to_machine_mapping[pfn] = mfn_list[i];
+             queue_machphys_update(mfn_list[i], pfn);
+             
+             /* Link back into the page tables if it's not a highmem page. */
+             if ( pfn < max_low_pfn )
+                 queue_l1_entry_update(
+                     get_ptep((unsigned long)__va(pfn << PAGE_SHIFT)),
+                     (mfn_list[i] << PAGE_SHIFT) | pgprot_val(PAGE_KERNEL));
+             
+             /* Finally, relinquish the memory back to the system allocator. */
+             ClearPageReserved(page);
+             set_page_count(page, 1);
+             __free_page(page);
+         }
+         current_pages += credit;
+     }
+     else if ( credit < 0 )
+     {
+         debt = -credit;
+         mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list));
+         if ( mfn_list == NULL )
+             goto out;
+         for ( i = 0; i < debt; i++ )
+         {
+             if ( (page = alloc_page(GFP_HIGHUSER)) == NULL )
+             {
+                 debt = i;
+                 break;
+             }
+             pfn = page - mem_map;
+             mfn_list[i] = phys_to_machine_mapping[pfn];
 -                v = phys_to_virt((page - mem_map) << PAGE_SHIFT);
+             if ( !PageHighMem(page) )
+             {
 -#endif            
 -
 -            balloon_append(page);
++                v = phys_to_virt(pfn << PAGE_SHIFT);
+                 scrub_pages(v, 1);
+                 queue_l1_entry_update(get_ptep((unsigned long)v), 0);
+             }
+ #ifdef CONFIG_XEN_SCRUB_PAGES
+             else
+             {
+                 v = kmap(page);
+                 scrub_pages(v, 1);
+                 kunmap(page);
+             }
++#endif
+         }
++        /* Ensure that ballooned highmem pages don't have cached mappings. */
++        kmap_flush_unused();
++
+         /* Flush updates through and flush the TLB. */
+         xen_tlb_flush();
++        /* No more mappings: invalidate pages in P2M and add to balloon. */
++        for ( i = 0; i < debt; i++ )
++        {
++            pfn = mfn_to_pfn(mfn_list[i]);
++            phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
++            balloon_append(pfn_to_page(pfn));
++        }
++
+         if ( HYPERVISOR_dom_mem_op(
+             MEMOP_decrease_reservation, mfn_list, debt, 0) != debt )
+             BUG();
+         current_pages -= debt;
+     }
+  out:
+     if ( mfn_list != NULL )
+         vfree(mfn_list);
+     /* Schedule more work if there is some still to be done. */
+     if ( current_target() != current_pages )
+         mod_timer(&balloon_timer, jiffies + HZ);
+     up(&balloon_mutex);
+ }
+ /* Resets the Xen limit, sets new target, and kicks off processing. */
+ static void set_new_target(unsigned long target)
+ {
+     /* No need for lock. Not read-modify-write updates. */
+     hard_limit   = ~0UL;
+     target_pages = target;
+     schedule_work(&balloon_worker);
+ }
+ static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
+ {
+     switch ( msg->subtype )
+     {
+     case CMSG_MEM_REQUEST_SET:
+     {
+         mem_request_t *req = (mem_request_t *)&msg->msg[0];
+         if ( msg->length != sizeof(mem_request_t) )
+             goto parse_error;
+         set_new_target(req->target);
+         req->status = 0;
+     }
+     break;        
+     default:
+         goto parse_error;
+     }
+     ctrl_if_send_response(msg);
+     return;
+  parse_error:
+     msg->length = 0;
+     ctrl_if_send_response(msg);
+ }
+ static int balloon_write(struct file *file, const char __user *buffer,
+                          unsigned long count, void *data)
+ {
+     char memstring[64], *endchar;
+     unsigned long long target_bytes;
+     if ( !capable(CAP_SYS_ADMIN) )
+         return -EPERM;
+     if ( count <= 1 )
+         return -EBADMSG; /* runt */
+     if ( count > sizeof(memstring) )
+         return -EFBIG;   /* too long */
+     if ( copy_from_user(memstring, buffer, count) )
+         return -EFAULT;
+     memstring[sizeof(memstring)-1] = '\0';
+     target_bytes = memparse(memstring, &endchar);
+     set_new_target(target_bytes >> PAGE_SHIFT);
+     return count;
+ }
+ static int balloon_read(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+ {
+     int len;
+ #define K(_p) ((_p)<<(PAGE_SHIFT-10))
+     len = sprintf(
+         page,
+         "Current allocation: %8lu kB\n"
+         "Requested target:   %8lu kB\n"
+         "Low-mem balloon:    %8lu kB\n"
+         "High-mem balloon:   %8lu kB\n"
+         "Xen hard limit:     ",
+         K(current_pages), K(target_pages), K(balloon_low), K(balloon_high));
+     if ( hard_limit != ~0UL )
+         len += sprintf(
+             page + len, 
+             "%8lu kB (inc. %8lu kB driver headroom)\n",
+             K(hard_limit), K(driver_pages));
+     else
+         len += sprintf(
+             page + len,
+             "     ??? kB\n");
+     *eof = 1;
+     return len;
+ }
+ static int __init balloon_init(void)
+ {
+     unsigned long pfn;
+     struct page *page;
+     IPRINTK("Initialising balloon driver.\n");
+     current_pages = min(xen_start_info.nr_pages, max_pfn);
+     target_pages  = current_pages;
+     balloon_low   = 0;
+     balloon_high  = 0;
+     driver_pages  = 0UL;
+     hard_limit    = ~0UL;
+     init_timer(&balloon_timer);
+     balloon_timer.data = 0;
+     balloon_timer.function = balloon_alarm;
+     
+     if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL )
+     {
+         WPRINTK("Unable to create /proc/xen/balloon.\n");
+         return -1;
+     }
+     balloon_pde->read_proc  = balloon_read;
+     balloon_pde->write_proc = balloon_write;
+     (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0);
+     /* Initialise the balloon with excess memory space. */
+     for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ )
+     {
+         page = &mem_map[pfn];
+         if ( !PageReserved(page) )
+             balloon_append(page);
+     }
+     return 0;
+ }
+ subsys_initcall(balloon_init);
+ void balloon_update_driver_allowance(long delta)
+ {
+     unsigned long flags;
+     balloon_lock(flags);
+     driver_pages += delta; /* non-atomic update */
+     balloon_unlock(flags);
+ }
+ void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns)
+ {
+     unsigned long flags;
+     balloon_lock(flags);
+     if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
+                                mfn_list, nr_mfns, 0) != nr_mfns )
+         BUG();
+     current_pages -= nr_mfns; /* non-atomic update */
+     balloon_unlock(flags);
+     schedule_work(&balloon_worker);
+ }
+ EXPORT_SYMBOL(balloon_update_driver_allowance);
+ EXPORT_SYMBOL(balloon_put_pages);
index 0000000000000000000000000000000000000000,b530128366cc8fc89502dc4283a7eb75758d874a..1aa5acf0c9c7270b0f747827f93c65ced1d1150b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,576 +1,577 @@@
 -    x->extent.device        = grow->extent.device;
+ /******************************************************************************
+  * blkback/vbd.c
+  * 
+  * Routines for managing virtual block devices (VBDs).
+  * 
+  * NOTE: vbd_lock protects updates to the rb_tree against concurrent lookups 
+  * in vbd_translate.  All other lookups are implicitly protected because the 
+  * only caller (the control message dispatch routine) serializes the calls.
+  * 
+  * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
+  */
+ #include "common.h"
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ static dev_t vbd_map_devnum(blkif_pdev_t);
+ #endif
+ void vbd_create(blkif_be_vbd_create_t *create) 
+ {
+     vbd_t       *vbd; 
+     rb_node_t  **rb_p, *rb_parent = NULL;
+     blkif_t     *blkif;
+     blkif_vdev_t vdevice = create->vdevice;
+     blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
+     if ( unlikely(blkif == NULL) )
+     {
+         DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
+                 create->domid, create->blkif_handle); 
+         create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+         return;
+     }
+     rb_p = &blkif->vbd_rb.rb_node;
+     while ( *rb_p != NULL )
+     {
+         rb_parent = *rb_p;
+         vbd = rb_entry(rb_parent, vbd_t, rb);
+         if ( vdevice < vbd->vdevice )
+         {
+             rb_p = &rb_parent->rb_left;
+         }
+         else if ( vdevice > vbd->vdevice )
+         {
+             rb_p = &rb_parent->rb_right;
+         }
+         else
+         {
+             DPRINTK("vbd_create attempted for already existing vbd\n");
+             create->status = BLKIF_BE_STATUS_VBD_EXISTS;
+             return;
+         }
+     }
+     if ( unlikely((vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL)) == NULL) )
+     {
+         DPRINTK("vbd_create: out of memory\n");
+         create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
+         return;
+     }
+     vbd->vdevice  = vdevice; 
+     vbd->readonly = create->readonly;
+     vbd->type     = VDISK_TYPE_DISK | VDISK_FLAG_VIRT;
+     vbd->extents  = NULL; 
+     spin_lock(&blkif->vbd_lock);
+     rb_link_node(&vbd->rb, rb_parent, rb_p);
+     rb_insert_color(&vbd->rb, &blkif->vbd_rb);
+     spin_unlock(&blkif->vbd_lock);
+     DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
+             vdevice, create->domid);
+     create->status = BLKIF_BE_STATUS_OKAY;
+ }
+ /* Grow a VBD by appending a new extent. Fails if the VBD doesn't exist. */
+ void vbd_grow(blkif_be_vbd_grow_t *grow) 
+ {
+     blkif_t            *blkif;
+     blkif_extent_le_t **px, *x; 
+     vbd_t              *vbd = NULL;
+     rb_node_t          *rb;
+     blkif_vdev_t        vdevice = grow->vdevice;
+     unsigned long       sz;
+     blkif = blkif_find_by_handle(grow->domid, grow->blkif_handle);
+     if ( unlikely(blkif == NULL) )
+     {
+         DPRINTK("vbd_grow attempted for non-existent blkif (%u,%u)\n", 
+                 grow->domid, grow->blkif_handle); 
+         grow->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+         return;
+     }
+     rb = blkif->vbd_rb.rb_node;
+     while ( rb != NULL )
+     {
+         vbd = rb_entry(rb, vbd_t, rb);
+         if ( vdevice < vbd->vdevice )
+             rb = rb->rb_left;
+         else if ( vdevice > vbd->vdevice )
+             rb = rb->rb_right;
+         else
+             break;
+     }
+     if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
+     {
+         DPRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
+         grow->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
+         return;
+     } 
+     if ( grow->extent.sector_start > 0 )
+     {
+         DPRINTK("vbd_grow: dev %08x start not zero.\n", grow->extent.device);
+         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         return;
+     }
+     if ( unlikely((x = kmalloc(sizeof(blkif_extent_le_t), 
+                                GFP_KERNEL)) == NULL) )
+     {
+         DPRINTK("vbd_grow: out of memory\n");
+         grow->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
+         return;
+     }
++    /* Mask to 16-bit for compatibility with old tools */
++    x->extent.device        = grow->extent.device & 0xffff;
+     x->extent.sector_start  = grow->extent.sector_start;
+     x->extent.sector_length = grow->extent.sector_length;
+     x->next                 = (blkif_extent_le_t *)NULL;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+     x->bdev = open_by_devnum(vbd_map_devnum(x->extent.device),
+                              vbd->readonly ? FMODE_READ : FMODE_WRITE);
+     if ( IS_ERR(x->bdev) )
+     {
+         DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
+         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         goto out;
+     }
+     /* XXXcl maybe bd_claim? */
+     if ( (x->bdev->bd_disk == NULL) )
+     {
+         DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
+         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         blkdev_put(x->bdev);
+         goto out;
+     }
+     /* get size in sectors */   
+     if ( x->bdev->bd_part )
+        sz = x->bdev->bd_part->nr_sects;
+     else
+        sz = x->bdev->bd_disk->capacity;
+ #else
+     if( !blk_size[MAJOR(x->extent.device)] )
+     {
+         DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
+         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         goto out;
+     }
+     
+     /* convert blocks (1KB) to sectors */
+     sz = blk_size[MAJOR(x->extent.device)][MINOR(x->extent.device)] * 2;    
+     
+     if ( sz == 0 )
+     {
+         DPRINTK("vbd_grow: device %08x zero size!\n", x->extent.device);
+         grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         goto out;
+     }
+ #endif
+     /*
+      * NB. This test assumes sector_start == 0, which is always the case
+      * in Xen 1.3. In fact the whole grow/shrink interface could do with
+      * some simplification.
+      */
+     if ( x->extent.sector_length > sz )
+         x->extent.sector_length = sz;
+     
+     DPRINTK("vbd_grow: requested_len %llu actual_len %lu\n", 
+             x->extent.sector_length, sz);
+     for ( px = &vbd->extents; *px != NULL; px = &(*px)->next ) 
+         continue;
+     
+     *px = x; /* ATOMIC: no need for vbd_lock. */
+     DPRINTK("Successful grow of vdev=%04x (dom=%u)\n",
+             vdevice, grow->domid);
+     
+     grow->status = BLKIF_BE_STATUS_OKAY;
+     return;
+  out:
+     kfree(x);
+ }
+ void vbd_shrink(blkif_be_vbd_shrink_t *shrink)
+ {
+     blkif_t            *blkif;
+     blkif_extent_le_t **px, *x; 
+     vbd_t              *vbd = NULL;
+     rb_node_t          *rb;
+     blkif_vdev_t        vdevice = shrink->vdevice;
+     blkif = blkif_find_by_handle(shrink->domid, shrink->blkif_handle);
+     if ( unlikely(blkif == NULL) )
+     {
+         DPRINTK("vbd_shrink attempted for non-existent blkif (%u,%u)\n", 
+                 shrink->domid, shrink->blkif_handle); 
+         shrink->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+         return;
+     }
+     rb = blkif->vbd_rb.rb_node;
+     while ( rb != NULL )
+     {
+         vbd = rb_entry(rb, vbd_t, rb);
+         if ( vdevice < vbd->vdevice )
+             rb = rb->rb_left;
+         else if ( vdevice > vbd->vdevice )
+             rb = rb->rb_right;
+         else
+             break;
+     }
+     if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
+     {
+         shrink->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
+         return;
+     }
+     if ( unlikely(vbd->extents == NULL) )
+     {
+         shrink->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+         return;
+     }
+     /* Find the last extent. We now know that there is at least one. */
+     for ( px = &vbd->extents; (*px)->next != NULL; px = &(*px)->next )
+         continue;
+     x   = *px;
+     *px = x->next; /* ATOMIC: no need for vbd_lock. */
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+     blkdev_put(x->bdev);
+ #endif
+     kfree(x);
+     shrink->status = BLKIF_BE_STATUS_OKAY;
+ }
+ void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
+ {
+     blkif_t           *blkif;
+     vbd_t             *vbd;
+     rb_node_t         *rb;
+     blkif_extent_le_t *x, *t;
+     blkif_vdev_t       vdevice = destroy->vdevice;
+     blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
+     if ( unlikely(blkif == NULL) )
+     {
+         DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
+                 destroy->domid, destroy->blkif_handle); 
+         destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+         return;
+     }
+     rb = blkif->vbd_rb.rb_node;
+     while ( rb != NULL )
+     {
+         vbd = rb_entry(rb, vbd_t, rb);
+         if ( vdevice < vbd->vdevice )
+             rb = rb->rb_left;
+         else if ( vdevice > vbd->vdevice )
+             rb = rb->rb_right;
+         else
+             goto found;
+     }
+     destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
+     return;
+  found:
+     spin_lock(&blkif->vbd_lock);
+     rb_erase(rb, &blkif->vbd_rb);
+     spin_unlock(&blkif->vbd_lock);
+     x = vbd->extents;
+     kfree(vbd);
+     while ( x != NULL )
+     {
+         t = x->next;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+         blkdev_put(x->bdev);
+ #endif
+         kfree(x);
+         x = t;
+     }
+ }
+ void destroy_all_vbds(blkif_t *blkif)
+ {
+     vbd_t             *vbd;
+     rb_node_t         *rb;
+     blkif_extent_le_t *x, *t;
+     spin_lock(&blkif->vbd_lock);
+     while ( (rb = blkif->vbd_rb.rb_node) != NULL )
+     {
+         vbd = rb_entry(rb, vbd_t, rb);
+         rb_erase(rb, &blkif->vbd_rb);
+         x = vbd->extents;
+         kfree(vbd);
+         
+         while ( x != NULL )
+         {
+             t = x->next;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+             blkdev_put(x->bdev);
+ #endif
+             kfree(x);
+             x = t;
+         }          
+     }
+     spin_unlock(&blkif->vbd_lock);
+ }
+ static int vbd_probe_single(blkif_t *blkif, vdisk_t *vbd_info, vbd_t *vbd)
+ {
+     blkif_extent_le_t *x; 
+     vbd_info->device = vbd->vdevice; 
+     vbd_info->info   = vbd->type;
+     if ( vbd->readonly )
+         vbd_info->info |= VDISK_FLAG_RO; 
+     vbd_info->capacity = 0ULL;
+     for ( x = vbd->extents; x != NULL; x = x->next )
+         vbd_info->capacity += x->extent.sector_length; 
+         
+     return 0;
+ }
+ int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
+ {
+     int        rc = 0, nr_vbds = 0;
+     rb_node_t *rb;
+     spin_lock(&blkif->vbd_lock);
+     if ( (rb = blkif->vbd_rb.rb_node) == NULL )
+         goto out;
+  new_subtree:
+     /* STEP 1. Find least node (it'll be left-most). */
+     while ( rb->rb_left != NULL )
+         rb = rb->rb_left;
+     for ( ; ; )
+     {
+         /* STEP 2. Dealt with left subtree. Now process current node. */
+         if ( (rc = vbd_probe_single(blkif, &vbd_info[nr_vbds], 
+                                     rb_entry(rb, vbd_t, rb))) != 0 )
+             goto out;
+         if ( ++nr_vbds == max_vbds )
+             goto out;
+         /* STEP 3. Process right subtree, if any. */
+         if ( rb->rb_right != NULL )
+         {
+             rb = rb->rb_right;
+             goto new_subtree;
+         }
+         /* STEP 4. Done both subtrees. Head back through ancesstors. */
+         for ( ; ; ) 
+         {
+             /* We're done when we get back to the root node. */
+             if ( rb->rb_parent == NULL )
+                 goto out;
+             /* If we are left of parent, then parent is next to process. */
+             if ( rb->rb_parent->rb_left == rb )
+                 break;
+             /* If we are right of parent, then we climb to grandparent. */
+             rb = rb->rb_parent;
+         }
+         rb = rb->rb_parent;
+     }
+  out:
+     spin_unlock(&blkif->vbd_lock);
+     return (rc == 0) ? nr_vbds : rc;  
+ }
+ int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation)
+ {
+     blkif_extent_le_t *x; 
+     vbd_t             *vbd;
+     rb_node_t         *rb;
+     blkif_sector_t     sec_off;
+     unsigned long      nr_secs;
+     /* Take the vbd_lock because another thread could be updating the tree. */
+     spin_lock(&blkif->vbd_lock);
+     rb = blkif->vbd_rb.rb_node;
+     while ( rb != NULL )
+     {
+         vbd = rb_entry(rb, vbd_t, rb);
+         if ( pseg->dev < vbd->vdevice )
+             rb = rb->rb_left;
+         else if ( pseg->dev > vbd->vdevice )
+             rb = rb->rb_right;
+         else
+             goto found;
+     }
+     DPRINTK("vbd_translate; domain %u attempted to access "
+             "non-existent VBD.\n", blkif->domid);
+     spin_unlock(&blkif->vbd_lock);
+     return -ENODEV; 
+  found:
+     if ( (operation == WRITE) && vbd->readonly )
+     {
+         spin_unlock(&blkif->vbd_lock);
+         return -EACCES; 
+     }
+     /*
+      * Now iterate through the list of blkif_extents, working out which should 
+      * be used to perform the translation.
+      */
+     sec_off = pseg->sector_number; 
+     nr_secs = pseg->nr_sects;
+     for ( x = vbd->extents; x != NULL; x = x->next )
+     { 
+         if ( sec_off < x->extent.sector_length )
+         {
+             pseg->dev  = x->extent.device;
+             pseg->bdev = x->bdev;
+             pseg->sector_number = x->extent.sector_start + sec_off;
+             if ( unlikely((sec_off + nr_secs) > x->extent.sector_length) )
+                 goto overrun;
+             spin_unlock(&blkif->vbd_lock);
+             return 1;
+         } 
+         sec_off -= x->extent.sector_length; 
+     }
+     DPRINTK("vbd_translate: end of vbd.\n");
+     spin_unlock(&blkif->vbd_lock);
+     return -EACCES; 
+     /*
+      * Here we deal with overrun onto the following extent. We don't deal with 
+      * overrun of more than one boundary since each request is restricted to 
+      * 2^9 512-byte sectors, so it should be trivial for control software to 
+      * ensure that extents are large enough to prevent excessive overrun.
+      */
+  overrun:
+     /* Adjust length of first chunk to run to end of first extent. */
+     pseg[0].nr_sects = x->extent.sector_length - sec_off;
+     /* Set second chunk buffer and length to start where first chunk ended. */
+     pseg[1].buffer   = pseg[0].buffer + (pseg[0].nr_sects << 9);
+     pseg[1].nr_sects = nr_secs - pseg[0].nr_sects;
+     /* Now move to the next extent. Check it exists and is long enough! */
+     if ( unlikely((x = x->next) == NULL) || 
+          unlikely(x->extent.sector_length < pseg[1].nr_sects) )
+     {
+         DPRINTK("vbd_translate: multiple overruns or end of vbd.\n");
+         spin_unlock(&blkif->vbd_lock);
+         return -EACCES;
+     }
+     /* Store the real device and start sector for the second chunk. */
+     pseg[1].dev           = x->extent.device;
+     pseg[1].bdev          = x->bdev;
+     pseg[1].sector_number = x->extent.sector_start;
+     
+     spin_unlock(&blkif->vbd_lock);
+     return 2;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ #define MAJOR_XEN(dev) ((dev)>>8)
+ #define MINOR_XEN(dev) ((dev) & 0xff)
+ #ifndef FANCY_REMAPPING
+ static dev_t vbd_map_devnum(blkif_pdev_t cookie)
+ {
+     int major = MAJOR_XEN(cookie);
+     int minor = MINOR_XEN(cookie);
+     return MKDEV(major, minor);
+ }
+ #else
+ #define XEN_IDE0_MAJOR IDE0_MAJOR
+ #define XEN_IDE1_MAJOR IDE1_MAJOR
+ #define XEN_IDE2_MAJOR IDE2_MAJOR
+ #define XEN_IDE3_MAJOR IDE3_MAJOR
+ #define XEN_IDE4_MAJOR IDE4_MAJOR
+ #define XEN_IDE5_MAJOR IDE5_MAJOR
+ #define XEN_IDE6_MAJOR IDE6_MAJOR
+ #define XEN_IDE7_MAJOR IDE7_MAJOR
+ #define XEN_IDE8_MAJOR IDE8_MAJOR
+ #define XEN_IDE9_MAJOR IDE9_MAJOR
+ #define XEN_SCSI_DISK0_MAJOR SCSI_DISK0_MAJOR
+ #define XEN_SCSI_DISK1_MAJOR SCSI_DISK1_MAJOR
+ #define XEN_SCSI_DISK2_MAJOR SCSI_DISK2_MAJOR
+ #define XEN_SCSI_DISK3_MAJOR SCSI_DISK3_MAJOR
+ #define XEN_SCSI_DISK4_MAJOR SCSI_DISK4_MAJOR
+ #define XEN_SCSI_DISK5_MAJOR SCSI_DISK5_MAJOR
+ #define XEN_SCSI_DISK6_MAJOR SCSI_DISK6_MAJOR
+ #define XEN_SCSI_DISK7_MAJOR SCSI_DISK7_MAJOR
+ #define XEN_SCSI_CDROM_MAJOR SCSI_CDROM_MAJOR
+ static dev_t vbd_map_devnum(blkif_pdev_t cookie)
+ {
+     int new_major;
+     int major = MAJOR_XEN(cookie);
+     int minor = MINOR_XEN(cookie);
+     switch (major) {
+     case XEN_IDE0_MAJOR: new_major = IDE0_MAJOR; break;
+     case XEN_IDE1_MAJOR: new_major = IDE1_MAJOR; break;
+     case XEN_IDE2_MAJOR: new_major = IDE2_MAJOR; break;
+     case XEN_IDE3_MAJOR: new_major = IDE3_MAJOR; break;
+     case XEN_IDE4_MAJOR: new_major = IDE4_MAJOR; break;
+     case XEN_IDE5_MAJOR: new_major = IDE5_MAJOR; break;
+     case XEN_IDE6_MAJOR: new_major = IDE6_MAJOR; break;
+     case XEN_IDE7_MAJOR: new_major = IDE7_MAJOR; break;
+     case XEN_IDE8_MAJOR: new_major = IDE8_MAJOR; break;
+     case XEN_IDE9_MAJOR: new_major = IDE9_MAJOR; break;
+     case XEN_SCSI_DISK0_MAJOR: new_major = SCSI_DISK0_MAJOR; break;
+     case XEN_SCSI_DISK1_MAJOR ... XEN_SCSI_DISK7_MAJOR:
+         new_major = SCSI_DISK1_MAJOR + major - XEN_SCSI_DISK1_MAJOR;
+         break;
+     case XEN_SCSI_CDROM_MAJOR: new_major = SCSI_CDROM_MAJOR; break;
+     default: new_major = 0; break;
+     }
+     return MKDEV(new_major, minor);
+ }
+ #endif
+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION_CODE(2,6,0) */
index 0000000000000000000000000000000000000000,b9c09c3d73da003644f1ec9479c4eb43efe97961..f1fe3c517fae3fa6701db06f5c7b514d7fa1698a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,772 +1,768 @@@
 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 -    if (str[0] == '=')
 -      str++;
 -#endif
+ /******************************************************************************
+  * console.c
+  * 
+  * Virtual console driver.
+  * 
+  * Copyright (c) 2002-2004, K A Fraser.
+  * 
+  * This file may be distributed separately from the Linux kernel, or
+  * incorporated into other software packages, subject to the following license:
+  * 
+  * Permission is hereby granted, free of charge, to any person obtaining a copy
+  * of this source file (the "Software"), to deal in the Software without
+  * restriction, including without limitation the rights to use, copy, modify,
+  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+  * and to permit persons to whom the Software is furnished to do so, subject to
+  * the following conditions:
+  * 
+  * The above copyright notice and this permission notice shall be included in
+  * all copies or substantial portions of the Software.
+  * 
+  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+  * IN THE SOFTWARE.
+  */
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/errno.h>
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+ #include <linux/serial.h>
+ #include <linux/major.h>
+ #include <linux/ptrace.h>
+ #include <linux/ioport.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/console.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/uaccess.h>
+ #include <asm-xen/xen-public/event_channel.h>
+ #include <asm-xen/hypervisor.h>
+ #include <asm-xen/evtchn.h>
+ #include <asm-xen/ctrl_if.h>
+ /*
+  * Modes:
+  *  'xencons=off'  [XC_OFF]:     Console is disabled.
+  *  'xencons=tty'  [XC_TTY]:     Console attached to '/dev/tty[0-9]+'.
+  *  'xencons=ttyS' [XC_SERIAL]:  Console attached to '/dev/ttyS[0-9]+'.
+  *                 [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
+  * 
+  * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
+  * warnings from standard distro startup scripts.
+  */
+ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
+ static int __init xencons_setup(char *str)
+ {
 -__setup("xencons", xencons_setup);
+     if ( !strcmp(str, "tty") )
+         xc_mode = XC_TTY;
+     else if ( !strcmp(str, "ttyS") )
+         xc_mode = XC_SERIAL;
+     else if ( !strcmp(str, "off") )
+         xc_mode = XC_OFF;
+     return 1;
+ }
++__setup("xencons=", xencons_setup);
+ /* The kernel and user-land drivers share a common transmit buffer. */
+ #define WBUF_SIZE     4096
+ #define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1))
+ static char wbuf[WBUF_SIZE];
+ static unsigned int wc, wp; /* write_cons, write_prod */
+ /* This lock protects accesses to the common transmit buffer. */
+ static spinlock_t xencons_lock = SPIN_LOCK_UNLOCKED;
+ /* Common transmit-kick routine. */
+ static void __xencons_tx_flush(void);
+ /* This task is used to defer sending console data until there is space. */
+ static void xencons_tx_flush_task_routine(void *data);
+ static DECLARE_TQUEUE(xencons_tx_flush_task, 
+                       xencons_tx_flush_task_routine,
+                       NULL);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ static struct tty_driver *xencons_driver;
+ #else
+ static struct tty_driver xencons_driver;
+ #endif
+ /******************** Kernel console driver ********************************/
+ static void kcons_write(
+     struct console *c, const char *s, unsigned int count)
+ {
+     int           i;
+     unsigned long flags;
+     spin_lock_irqsave(&xencons_lock, flags);
+     
+     for ( i = 0; i < count; i++ )
+     {
+         if ( (wp - wc) >= (WBUF_SIZE - 1) )
+             break;
+         if ( (wbuf[WBUF_MASK(wp++)] = s[i]) == '\n' )
+             wbuf[WBUF_MASK(wp++)] = '\r';
+     }
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ static void kcons_write_dom0(
+     struct console *c, const char *s, unsigned int count)
+ {
+     int rc;
+     while ( count > 0 )
+     {
+         if ( (rc = HYPERVISOR_console_io(CONSOLEIO_write,
+                                          count, (char *)s)) > 0 )
+         {
+             count -= rc;
+             s += rc;
+         }
+       else
+           break;
+     }
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ static struct tty_driver *kcons_device(struct console *c, int *index)
+ {
+     *index = c->index;
+     return xencons_driver;
+ }
+ #else
+ static kdev_t kcons_device(struct console *c)
+ {
+     return MKDEV(TTY_MAJOR, (xc_mode == XC_SERIAL) ? 64 : 1);
+ }
+ #endif
+ static struct console kcons_info = {
+     device:  kcons_device,
+     flags:   CON_PRINTBUFFER,
+     index:   -1
+ };
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ #define __RETCODE 0
+ static int __init xen_console_init(void)
+ #else
+ #define __RETCODE
+ void xen_console_init(void)
+ #endif
+ {
+     if ( xen_start_info.flags & SIF_INITDOMAIN )
+     {
+         if ( xc_mode == XC_DEFAULT )
+             xc_mode = XC_SERIAL;
+         kcons_info.write = kcons_write_dom0;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+       if ( xc_mode == XC_SERIAL )
+           kcons_info.flags |= CON_ENABLED;
+ #endif
+     }
+     else
+     {
+         if ( xc_mode == XC_DEFAULT )
+             xc_mode = XC_TTY;
+         kcons_info.write = kcons_write;
+     }
+     if ( xc_mode == XC_OFF )
+         return __RETCODE;
+     if ( xc_mode == XC_SERIAL )
+         strcpy(kcons_info.name, "ttyS");
+     else
+         strcpy(kcons_info.name, "tty");
+     register_console(&kcons_info);
+     return __RETCODE;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ console_initcall(xen_console_init);
+ #endif
+ /*** Useful function for console debugging -- goes straight to Xen. ***/
+ asmlinkage int xprintk(const char *fmt, ...)
+ {
+     va_list args;
+     int printk_len;
+     static char printk_buf[1024];
+     
+     /* Emit the output into the temporary buffer */
+     va_start(args, fmt);
+     printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+     va_end(args);
+     /* Send the processed output directly to Xen. */
+     kcons_write_dom0(NULL, printk_buf, printk_len);
+     return 0;
+ }
+ /*** Forcibly flush console data before dying. ***/
+ void xencons_force_flush(void)
+ {
+     ctrl_msg_t msg;
+     int        sz;
+     /* Emergency console is synchronous, so there's nothing to flush. */
+     if ( xen_start_info.flags & SIF_INITDOMAIN )
+         return;
+     /*
+      * We use dangerous control-interface functions that require a quiescent
+      * system and no interrupts. Try to ensure this with a global cli().
+      */
+     cli();
+     /* Spin until console data is flushed through to the domain controller. */
+     while ( (wc != wp) && !ctrl_if_transmitter_empty() )
+     {
+         /* Interrupts are disabled -- we must manually reap responses. */
+         ctrl_if_discard_responses();
+         if ( (sz = wp - wc) == 0 )
+             continue;
+         if ( sz > sizeof(msg.msg) )
+             sz = sizeof(msg.msg);
+         if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) )
+             sz = WBUF_SIZE - WBUF_MASK(wc);
+         msg.type    = CMSG_CONSOLE;
+         msg.subtype = CMSG_CONSOLE_DATA;
+         msg.length  = sz;
+         memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
+             
+         if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
+             wc += sz;
+     }
+ }
+ /******************** User-space console driver (/dev/console) ************/
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ #define DRV(_d)         (_d)
+ #define TTY_INDEX(_tty) ((_tty)->index)
+ #else
+ static int xencons_refcount;
+ static struct tty_struct *xencons_table[MAX_NR_CONSOLES];
+ #define DRV(_d)         (&(_d))
+ #define TTY_INDEX(_tty) (MINOR((_tty)->device) - xencons_driver.minor_start)
+ #endif
+ static struct termios *xencons_termios[MAX_NR_CONSOLES];
+ static struct termios *xencons_termios_locked[MAX_NR_CONSOLES];
+ static struct tty_struct *xencons_tty;
+ static int xencons_priv_irq;
+ static char x_char;
+ /* Non-privileged receive callback. */
+ static void xencons_rx(ctrl_msg_t *msg, unsigned long id)
+ {
+     int           i;
+     unsigned long flags;
+     spin_lock_irqsave(&xencons_lock, flags);
+     if ( xencons_tty != NULL )
+     {
+         for ( i = 0; i < msg->length; i++ )
+             tty_insert_flip_char(xencons_tty, msg->msg[i], 0);
+         tty_flip_buffer_push(xencons_tty);
+     }
+     spin_unlock_irqrestore(&xencons_lock, flags);
+     msg->length = 0;
+     ctrl_if_send_response(msg);
+ }
+ /* Privileged and non-privileged transmit worker. */
+ static void __xencons_tx_flush(void)
+ {
+     int        sz, work_done = 0;
+     ctrl_msg_t msg;
+     if ( xen_start_info.flags & SIF_INITDOMAIN )
+     {
+         if ( x_char )
+         {
+             kcons_write_dom0(NULL, &x_char, 1);
+             x_char = 0;
+             work_done = 1;
+         }
+         while ( wc != wp )
+         {
+             sz = wp - wc;
+             if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) )
+                 sz = WBUF_SIZE - WBUF_MASK(wc);
+             kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
+             wc += sz;
+             work_done = 1;
+         }
+     }
+     else
+     {
+         while ( x_char )
+         {
+             msg.type    = CMSG_CONSOLE;
+             msg.subtype = CMSG_CONSOLE_DATA;
+             msg.length  = 1;
+             msg.msg[0]  = x_char;
+             if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
+                 x_char = 0;
+             else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) )
+                 break;
+             work_done = 1;
+         }
+         while ( wc != wp )
+         {
+             sz = wp - wc;
+             if ( sz > sizeof(msg.msg) )
+                 sz = sizeof(msg.msg);
+             if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) )
+                 sz = WBUF_SIZE - WBUF_MASK(wc);
+             msg.type    = CMSG_CONSOLE;
+             msg.subtype = CMSG_CONSOLE_DATA;
+             msg.length  = sz;
+             memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
+             
+             if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
+                 wc += sz;
+             else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) )
+                 break;
+             work_done = 1;
+         }
+     }
+     if ( work_done && (xencons_tty != NULL) )
+     {
+         wake_up_interruptible(&xencons_tty->write_wait);
+         if ( (xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+              (xencons_tty->ldisc.write_wakeup != NULL) )
+             (xencons_tty->ldisc.write_wakeup)(xencons_tty);
+     }
+ }
+ /* Non-privileged transmit kicker. */
+ static void xencons_tx_flush_task_routine(void *data)
+ {
+     unsigned long flags;
+     spin_lock_irqsave(&xencons_lock, flags);
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ /* Privileged receive callback and transmit kicker. */
+ static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
+                                           struct pt_regs *regs)
+ {
+     static char   rbuf[16];
+     int           i, l;
+     unsigned long flags;
+     spin_lock_irqsave(&xencons_lock, flags);
+     if ( xencons_tty != NULL )
+     {
+         /* Receive work. */
+         while ( (l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
+             for ( i = 0; i < l; i++ )
+                 tty_insert_flip_char(xencons_tty, rbuf[i], 0);
+         if ( xencons_tty->flip.count != 0 )
+             tty_flip_buffer_push(xencons_tty);
+     }
+     /* Transmit work. */
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+     return IRQ_HANDLED;
+ }
+ static int xencons_write_room(struct tty_struct *tty)
+ {
+     return WBUF_SIZE - (wp - wc);
+ }
+ static int xencons_chars_in_buffer(struct tty_struct *tty)
+ {
+     return wp - wc;
+ }
+ static void xencons_send_xchar(struct tty_struct *tty, char ch)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     spin_lock_irqsave(&xencons_lock, flags);
+     x_char = ch;
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ static void xencons_throttle(struct tty_struct *tty)
+ {
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     if ( I_IXOFF(tty) )
+         xencons_send_xchar(tty, STOP_CHAR(tty));
+ }
+ static void xencons_unthrottle(struct tty_struct *tty)
+ {
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     if ( I_IXOFF(tty) )
+     {
+         if ( x_char != 0 )
+             x_char = 0;
+         else
+             xencons_send_xchar(tty, START_CHAR(tty));
+     }
+ }
+ static void xencons_flush_buffer(struct tty_struct *tty)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     spin_lock_irqsave(&xencons_lock, flags);
+     wc = wp = 0;
+     spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ static inline int __xencons_put_char(int ch)
+ {
+     char _ch = (char)ch;
+     if ( (wp - wc) == WBUF_SIZE )
+         return 0;
+     wbuf[WBUF_MASK(wp++)] = _ch;
+     return 1;
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ static int xencons_write(struct tty_struct *tty, const unsigned char *buf,
+                        int count)
+ {
+     int i;
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return count;
+     spin_lock_irqsave(&xencons_lock, flags);
+     for ( i = 0; i < count; i++ )
+         if ( !__xencons_put_char(buf[i]) )
+             break;
+     if ( i != 0 )
+         __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+     return i;
+ }
+ #else
+ static int xencons_write(struct tty_struct *tty, int from_user,
+                        const u_char *buf, int count)
+ {
+     int i;
+     unsigned long flags;
+     if ( from_user && verify_area(VERIFY_READ, buf, count) )
+         return -EINVAL;
+     if ( TTY_INDEX(tty) != 0 )
+         return count;
+     spin_lock_irqsave(&xencons_lock, flags);
+     for ( i = 0; i < count; i++ )
+     {
+         char ch;
+         if ( from_user )
+             __get_user(ch, buf + i);
+         else
+             ch = buf[i];
+         if ( !__xencons_put_char(ch) )
+             break;
+     }
+     if ( i != 0 )
+         __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);
+     return i;
+ }
+ #endif
+ static void xencons_put_char(struct tty_struct *tty, u_char ch)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     spin_lock_irqsave(&xencons_lock, flags);
+     (void)__xencons_put_char(ch);
+     spin_unlock_irqrestore(&xencons_lock, flags);
+ }
+ static void xencons_flush_chars(struct tty_struct *tty)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     spin_lock_irqsave(&xencons_lock, flags);
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);    
+ }
+ static void xencons_wait_until_sent(struct tty_struct *tty, int timeout)
+ {
+     unsigned long orig_jiffies = jiffies;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     while ( DRV(tty->driver)->chars_in_buffer(tty) )
+     {
+         set_current_state(TASK_INTERRUPTIBLE);
+         schedule_timeout(1);
+         if ( signal_pending(current) )
+             break;
+         if ( (timeout != 0) && time_after(jiffies, orig_jiffies + timeout) )
+             break;
+     }
+     
+     set_current_state(TASK_RUNNING);
+ }
+ static int xencons_open(struct tty_struct *tty, struct file *filp)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return 0;
+     spin_lock_irqsave(&xencons_lock, flags);
+     tty->driver_data = NULL;
+     if ( xencons_tty == NULL )
+         xencons_tty = tty;
+     __xencons_tx_flush();
+     spin_unlock_irqrestore(&xencons_lock, flags);    
+     return 0;
+ }
+ static void xencons_close(struct tty_struct *tty, struct file *filp)
+ {
+     unsigned long flags;
+     if ( TTY_INDEX(tty) != 0 )
+         return;
+     if ( tty->count == 1 )
+     {
+         tty->closing = 1;
+         tty_wait_until_sent(tty, 0);
+         if ( DRV(tty->driver)->flush_buffer != NULL )
+             DRV(tty->driver)->flush_buffer(tty);
+         if ( tty->ldisc.flush_buffer != NULL )
+             tty->ldisc.flush_buffer(tty);
+         tty->closing = 0;
+         spin_lock_irqsave(&xencons_lock, flags);
+         xencons_tty = NULL;
+         spin_unlock_irqrestore(&xencons_lock, flags);    
+     }
+ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ static struct tty_operations xencons_ops = {
+     .open = xencons_open,
+     .close = xencons_close,
+     .write = xencons_write,
+     .write_room = xencons_write_room,
+     .put_char = xencons_put_char,
+     .flush_chars = xencons_flush_chars,
+     .chars_in_buffer = xencons_chars_in_buffer,
+     .send_xchar = xencons_send_xchar,
+     .flush_buffer = xencons_flush_buffer,
+     .throttle = xencons_throttle,
+     .unthrottle = xencons_unthrottle,
+     .wait_until_sent = xencons_wait_until_sent,
+ };
+ #ifdef CONFIG_XEN_PRIVILEGED_GUEST
+ static const char *xennullcon_startup(void)
+ {
+     return NULL;
+ }
+ static int xennullcon_dummy(void)
+ {
+     return 0;
+ }
+ #define DUMMY (void *)xennullcon_dummy
+ /*
+  *  The console `switch' structure for the dummy console
+  *
+  *  Most of the operations are dummies.
+  */
+ const struct consw xennull_con = {
+     .owner =          THIS_MODULE,
+     .con_startup =    xennullcon_startup,
+     .con_init =               DUMMY,
+     .con_deinit =     DUMMY,
+     .con_clear =      DUMMY,
+     .con_putc =               DUMMY,
+     .con_putcs =      DUMMY,
+     .con_cursor =     DUMMY,
+     .con_scroll =     DUMMY,
+     .con_bmove =      DUMMY,
+     .con_switch =     DUMMY,
+     .con_blank =      DUMMY,
+     .con_font_set =   DUMMY,
+     .con_font_get =   DUMMY,
+     .con_font_default =       DUMMY,
+     .con_font_copy =  DUMMY,
+     .con_set_palette =        DUMMY,
+     .con_scrolldelta =        DUMMY,
+ };
+ #endif
+ #endif
+ static int __init xencons_init(void)
+ {
+     int rc;
+     if ( xc_mode == XC_OFF )
+         return 0;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+     xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? 
+                                       1 : MAX_NR_CONSOLES);
+     if ( xencons_driver == NULL )
+         return -ENOMEM;
+ #else
+     memset(&xencons_driver, 0, sizeof(struct tty_driver));
+     xencons_driver.magic       = TTY_DRIVER_MAGIC;
+     xencons_driver.refcount    = &xencons_refcount;
+     xencons_driver.table       = xencons_table;
+     xencons_driver.num         = (xc_mode == XC_SERIAL) ? 1 : MAX_NR_CONSOLES;
+ #endif
+     DRV(xencons_driver)->major           = TTY_MAJOR;
+     DRV(xencons_driver)->type            = TTY_DRIVER_TYPE_SERIAL;
+     DRV(xencons_driver)->subtype         = SERIAL_TYPE_NORMAL;
+     DRV(xencons_driver)->init_termios    = tty_std_termios;
+     DRV(xencons_driver)->flags           = 
+         TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
+     DRV(xencons_driver)->termios         = xencons_termios;
+     DRV(xencons_driver)->termios_locked  = xencons_termios_locked;
+     if ( xc_mode == XC_SERIAL )
+     {
+         DRV(xencons_driver)->name        = "ttyS";
+         DRV(xencons_driver)->minor_start = 64;
+       DRV(xencons_driver)->name_base   = 0;
+     }
+     else
+     {
+         DRV(xencons_driver)->name        = "tty";
+         DRV(xencons_driver)->minor_start = 1;
+       DRV(xencons_driver)->name_base   = 1;
+     }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+     tty_set_operations(xencons_driver, &xencons_ops);
+ #else
+     xencons_driver.open            = xencons_open;
+     xencons_driver.close           = xencons_close;
+     xencons_driver.write           = xencons_write;
+     xencons_driver.write_room      = xencons_write_room;
+     xencons_driver.put_char        = xencons_put_char;
+     xencons_driver.flush_chars     = xencons_flush_chars;
+     xencons_driver.chars_in_buffer = xencons_chars_in_buffer;
+     xencons_driver.send_xchar      = xencons_send_xchar;
+     xencons_driver.flush_buffer    = xencons_flush_buffer;
+     xencons_driver.throttle        = xencons_throttle;
+     xencons_driver.unthrottle      = xencons_unthrottle;
+     xencons_driver.wait_until_sent = xencons_wait_until_sent;
+ #endif
+     if ( (rc = tty_register_driver(DRV(xencons_driver))) != 0 )
+     {
+         printk("WARNING: Failed to register Xen virtual "
+                "console driver as '%s%d'\n",
+                DRV(xencons_driver)->name, DRV(xencons_driver)->name_base);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+         put_tty_driver(xencons_driver);
+         xencons_driver = NULL;
+ #endif
+         return rc;
+     }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+     tty_register_device(xencons_driver, 0, NULL);
+ #endif
+     if ( xen_start_info.flags & SIF_INITDOMAIN )
+     {
+         xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE);
+         (void)request_irq(xencons_priv_irq,
+                           xencons_priv_interrupt, 0, "console", NULL);
+     }
+     else
+     {
+         (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0);
+     }
+     printk("Xen virtual console successfully installed as %s\n",
+            DRV(xencons_driver)->name);
+     
+     return 0;
+ }
+ module_init(xencons_init);